diff --git a/AppScope/app.json5 b/AppScope/app.json5 index 0b34a7c2e49e042e407799decac2c4781907925f..20a7cb8ad618125d312058f48e360aca2adfbf9b 100644 --- a/AppScope/app.json5 +++ b/AppScope/app.json5 @@ -4,7 +4,7 @@ "vendor": "example", "versionCode": 1000000, "versionName": "1.0.0", - "icon": "$media:layered_image", - "label": "$string:app_name", + "icon": "$media:hmos_layered_image", + "label": "$string:hmos_app_name", } } \ No newline at end of file diff --git a/AppScope/resources/base/element/string.json b/AppScope/resources/base/element/string.json index 28b97069fc2da4fde48f0b5bea0ba3ac99c30284..9981211ed5bbf1d97fd25f4d9faeedae3bfa98e7 100644 --- a/AppScope/resources/base/element/string.json +++ b/AppScope/resources/base/element/string.json @@ -1,7 +1,7 @@ { "string": [ { - "name": "app_name", + "name": "hmos_app_name", "value": "HMOS代码工坊" } ] diff --git a/AppScope/resources/base/media/hmos_layered_image.json b/AppScope/resources/base/media/hmos_layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..ab180cdfef55bcd5248e3aef53bad8d621a6443a --- /dev/null +++ b/AppScope/resources/base/media/hmos_layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:ic_background", + "foreground" : "$media:ic_foreground" + } +} \ No newline at end of file diff --git a/AppScope/resources/base/media/ic_foreground.png b/AppScope/resources/base/media/ic_foreground.png index 633d7243b55c07163b416bef06b83b630a6696f4..3cc9e44f965c521a46fad6660b7fe6d091f45418 100644 Binary files a/AppScope/resources/base/media/ic_foreground.png and b/AppScope/resources/base/media/ic_foreground.png differ diff --git a/common/Index.ets b/common/Index.ets index 4fad1144722febffd12ad3951663206005030156..f9106c084024d9d47a8a6e3b5d15ff5e63ba3751 100644 --- a/common/Index.ets +++ b/common/Index.ets @@ -34,6 +34,8 @@ export { LoadingMore } from './src/main/ets/component/LoadingMore'; export { NoMore } from './src/main/ets/component/NoMore'; +export { default as Toast } from './src/main/ets/component/Toast'; + export { CommonConstants } from './src/main/ets/constant/CommonConstants'; export { @@ -41,6 +43,7 @@ export { LoadingStatus, ModuleNameEnum, ScrollDirectionEnum, + StorageKey, ProductSeriesEnum, } from './src/main/ets/constant/CommonEnums'; @@ -49,7 +52,7 @@ export { IPageContext, PageContext } from './src/main/ets/routermanager/PageCont export { NativeActionData, WebUtil, - WebNodeController, + type WebNodeController, javascriptProxyPermission, } from './src/main/ets/util/WebUtil'; diff --git a/common/src/main/ets/component/LoadingMore.ets b/common/src/main/ets/component/LoadingMore.ets index 3b2267d66aaccf71a8f53e1a0aacf0c5769a338a..54eb5ea0f01f8a6556313c6ca2d095fe3f55b874 100644 --- a/common/src/main/ets/component/LoadingMore.ets +++ b/common/src/main/ets/component/LoadingMore.ets @@ -17,7 +17,7 @@ export function LoadingMore() { Row() { LoadingProgress() - .color($r('sys.color.font_primary')) + .color($r('sys.color.icon_secondary')) .size({ width: $r('sys.float.padding_level12'), height: $r('sys.float.padding_level12') }) Text($r('app.string.loading')) diff --git a/common/src/main/ets/component/NoMore.ets b/common/src/main/ets/component/NoMore.ets index d467e3b03fe3908aa2604f9297effa7f4082fbc5..0fa310b99212058a240440d325a9705ab3aaacb2 100644 --- a/common/src/main/ets/component/NoMore.ets +++ b/common/src/main/ets/component/NoMore.ets @@ -17,7 +17,7 @@ export function NoMore() { Row() { Divider() - .color($r('sys.color.ohos_id_color_text_field_sub_bg')) + .color($r('sys.color.comp_background_tertiary')) .height(1) .layoutWeight(1) Text($r('app.string.no_more')) @@ -25,7 +25,7 @@ export function NoMore() { .fontSize($r('sys.float.Caption_M')) .margin($r('sys.float.padding_level6')) Divider() - .color($r('sys.color.ohos_id_color_text_field_sub_bg')) + .color($r('sys.color.comp_background_tertiary')) .height(1) .layoutWeight(1) } diff --git a/common/src/main/ets/component/Toast.ets b/common/src/main/ets/component/Toast.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9336d067d18f4a378d05b36cb1a47f5f0f15ef2 --- /dev/null +++ b/common/src/main/ets/component/Toast.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PromptAction } from '@kit.ArkUI'; +import { type BusinessError } from '@kit.BasicServicesKit'; +import { StorageKey } from '../constant/CommonEnums'; +import Logger from '../util/Logger'; + +const TAG: string = '[HMOS_Toast]'; + +class Toast { + private longToastTime: number = 2000; + + public showToast(message: ResourceStr, duration?: number) { + try { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT)!; + const promptAction: PromptAction = uiContext.getPromptAction(); + promptAction.showToast({ + message: message, + duration: duration, + }); + } catch (err) { + const error: BusinessError = err as BusinessError; + Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); + } + } + + public showLongToast(message: ResourceStr) { + this.showToast(message, this.longToastTime); + } +} + +export default new Toast(); \ No newline at end of file diff --git a/common/src/main/ets/component/TopNavigationView.ets b/common/src/main/ets/component/TopNavigationView.ets index 205a475484eb10372a9bc9ae8f58e4c0bda54fb4..884f3e2dfd9f5232fa0500976e8800544eb59591 100644 --- a/common/src/main/ets/component/TopNavigationView.ets +++ b/common/src/main/ets/component/TopNavigationView.ets @@ -13,8 +13,8 @@ * limitations under the License. */ -import { MeasureText } from '@kit.ArkUI'; import { CommonConstants } from '../constant/CommonConstants'; +import { StorageKey } from '../constant/CommonEnums'; import { BreakpointTypeEnum, type GlobalInfoModel } from '../model/GlobalInfoModel'; import { BreakpointType } from '../util/BreakpointSystem'; @@ -27,9 +27,9 @@ const TOTAL_PADDING: number = 40; @Component export struct TopNavigationView { - @StorageProp('GlobalInfoModel') @Watch('calculateTitleSize') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; - @StorageProp('BlurRenderGroup') blurRenderGroup: boolean = false; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('calculateTitleSize') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.BLUE_RENDER_GROUP) blurRenderGroup: boolean = false; @Prop topNavigationData: TopNavigationData = new TopNavigationData(); @BuilderParam menuView?: () => void; @State fontSize: number = 20; @@ -44,16 +44,17 @@ export struct TopNavigationView { } calculateTitleSize(): void { + const uiContext: UIContext = this.getUIContext(); const maxWidth = this.globalInfoModel.deviceWidth - BACK_ICON_WIDTH - TOTAL_PADDING; let currentFontSize: number = this.fontSize; - let titleWidth: number = Math.ceil(px2vp(MeasureText.measureText({ + let titleWidth: number = Math.ceil(uiContext.px2vp(uiContext.getMeasureUtils().measureText({ textContent: this.topNavigationData.title, fontWeight: FontWeight.Bold, fontSize: currentFontSize, }))); while (currentFontSize > 14 && titleWidth > maxWidth) { currentFontSize--; - titleWidth = Math.ceil(px2vp(MeasureText.measureText({ + titleWidth = Math.ceil(uiContext.px2vp(uiContext.getMeasureUtils().measureText({ textContent: this.topNavigationData.title, fontWeight: FontWeight.Bold, fontSize: currentFontSize, diff --git a/common/src/main/ets/component/WebSheet.ets b/common/src/main/ets/component/WebSheet.ets index 5d200d1430ac1d63c6aba61176da1f6b2ce9420e..f4f89329b8782e7c9873cedcc6028c05b7c84f33 100644 --- a/common/src/main/ets/component/WebSheet.ets +++ b/common/src/main/ets/component/WebSheet.ets @@ -13,6 +13,7 @@ * limitations under the License. */ +import { StorageKey } from '../constant/CommonEnums'; import type { GlobalInfoModel } from '../model/GlobalInfoModel'; import { BreakpointType } from '../util/BreakpointSystem'; import { WebUtil } from '../util/WebUtil'; @@ -31,8 +32,8 @@ const HARMONYOS_TOP_HEIGHT: number = 56; @Component struct WebSheet { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - @StorageProp('webIsLoading') isLoading: boolean = false; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.WEB_LOADING) isLoading: boolean = false; @Prop url: string; @Prop urlType: WebUrlType; @State loadFailed: boolean = false; diff --git a/common/src/main/ets/constant/CommonEnums.ets b/common/src/main/ets/constant/CommonEnums.ets index e2aa3fb37f7544b79df35870f771d3c6f5408711..3f7eecfb09736f17a236615356f684644304d774 100644 --- a/common/src/main/ets/constant/CommonEnums.ets +++ b/common/src/main/ets/constant/CommonEnums.ets @@ -56,4 +56,20 @@ export enum ScrollDirectionEnum { export enum ProductSeriesEnum { HPR = 'HPR', // fordable PC VDE = 'VDE', +} + +export enum StorageKey { + UI_CONTEXT = 'hmos_world_UIContext', + COLOR_MODE = 'hmos_world_SystemColorMode', + GLOBAL_INFO = 'hmos_world_GlobalInfoModel', + BUNDLE_INFO = 'hmos_world_BundleInfoData', + WEB_LOADING = 'hmos_world_WebIsLoading', + IS_PLAYING = 'hmos_world_IsPlaying', + CURRENT_TAB = 'hmos_world_CurrentTabIndex', + BLUE_RENDER_GROUP = 'hmos_world_BlurRenderGroup', + COMPONENT_CONFIG = 'hmos_world_ComponentDetailConfig', + COMPONENT_PAGE_CONTEXT = 'hmos_world_ComponentListPageContext', + SAMPLE_PAGE_CONTEXT = 'hmos_world_SamplePageContext', + EXPLORATION_PAGE_CONTEXT = 'hmos_world_ExplorationPageContext', + HOME_PAGE_CONTEXT = 'hmos_world_PageContext' } \ No newline at end of file diff --git a/common/src/main/ets/storagemanager/MockRequest.ets b/common/src/main/ets/storagemanager/MockRequest.ets index c3ec3e0c8ae28913813c9d36527abe31be6358ca..765e506e9631a7bcf56dd3563897f2f43d0a214d 100644 --- a/common/src/main/ets/storagemanager/MockRequest.ets +++ b/common/src/main/ets/storagemanager/MockRequest.ets @@ -15,6 +15,7 @@ import { util } from '@kit.ArkTS'; import { BusinessError } from '@kit.BasicServicesKit'; +import { StorageKey } from '../constant/CommonEnums'; import Logger from '../util/Logger'; const TAG = '[MockRequest]'; @@ -27,8 +28,8 @@ class MockRequest { return new Promise((resolve: (value: T | PromiseLike) => void, reject: ((reason?: BusinessError) => void)) => { try { - const context: Context = getContext(); - const result: Uint8Array = context.resourceManager.getRawFileContentSync(`mockdata/${trigger}.json`); + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const result: Uint8Array = uiContext.getHostContext()!.resourceManager.getRawFileContentSync(`mockdata/${trigger}.json`); const textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }); const content: string = textDecoder.decodeToString(result, { stream: false }); const jsonContent: ResultData = JSON.parse(content) as ResultData; diff --git a/common/src/main/ets/storagemanager/PreferenceManager.ets b/common/src/main/ets/storagemanager/PreferenceManager.ets index 367d3fafc79460a8d77e8e2ac28e845e5560f1f7..d9b34781d11bedb48d915c642bbeeb35fba796e6 100644 --- a/common/src/main/ets/storagemanager/PreferenceManager.ets +++ b/common/src/main/ets/storagemanager/PreferenceManager.ets @@ -15,6 +15,7 @@ import { preferences } from '@kit.ArkData'; import { BusinessError } from '@kit.BasicServicesKit'; +import { StorageKey } from '../constant/CommonEnums'; import Logger from '../util/Logger'; const PREFERENCES_NAME: string = 'HMosWorldStore'; @@ -36,7 +37,8 @@ export class PreferenceManager { } private initPreference(storeName: string): Promise { - return preferences.getPreferences(getContext(), storeName) + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + return preferences.getPreferences(uiContext.getHostContext() as Context, storeName) .then((preferences: preferences.Preferences) => { this.preferences = preferences; }) @@ -46,56 +48,78 @@ export class PreferenceManager { } public async setValue(key: string, value: T): Promise { - if (this.preferences) { - this.preferences.put(key, JSON.stringify(value)).then(() => { - this.saveValue(); - }) - } else { - this.initPreference(PREFERENCES_NAME).then(() => { - this.setValue(key, value); - }); + try { + if (this.preferences) { + this.preferences.put(key, JSON.stringify(value)).then(() => { + this.saveValue(); + }) + } else { + this.initPreference(PREFERENCES_NAME).then(() => { + this.setValue(key, value); + }); + } + } catch (e) { + Logger.error(TAG, `Preferences put failed, err code:${e?.code},msg:${e?.message}`); } } public async getValue(key: string): Promise { - if (this.preferences) { - return this.preferences.get(key, '').then((res: preferences.ValueType) => { - let value: T | null = null; - if (res) { - value = JSON.parse(res as string) as T; - } - return value; - }); - } else { - return this.initPreference(PREFERENCES_NAME).then(() => { - return this.getValue(key); - }); + try { + if (this.preferences) { + return this.preferences.get(key, '').then((res: preferences.ValueType) => { + let value: T | null = null; + if (res) { + value = JSON.parse(res as string) as T; + } + return value; + }); + } else { + return this.initPreference(PREFERENCES_NAME).then(() => { + return this.getValue(key); + }); + } + } catch { + Logger.error(TAG, `Preferences get failed.`); + return null; } } public async hasValue(key: string): Promise { - if (this.preferences) { - return this.preferences.has(key); - } else { - return this.initPreference(PREFERENCES_NAME).then(() => { - return this.hasValue(key); - }); + try { + if (this.preferences) { + return this.preferences.has(key); + } else { + return this.initPreference(PREFERENCES_NAME).then(() => { + return this.hasValue(key); + }); + } + } catch { + Logger.error(TAG, `Preferences hasValue failed.`); + return false; } } public async deleteValue(key: string): Promise { - if (this.preferences) { - this.preferences.delete(key).then(() => { - this.saveValue(); - }); - } else { - this.initPreference(PREFERENCES_NAME).then(() => { - this.deleteValue(key); - }); + try { + if (this.preferences) { + this.preferences.delete(key).then(() => { + this.saveValue(); + }); + } else { + this.initPreference(PREFERENCES_NAME).then(() => { + this.deleteValue(key); + }); + } + } catch { + Logger.error(TAG, `Preferences delete Key failed.`); } } saveValue() { - this.preferences?.flush(); + try { + this.preferences?.flush(); + } catch { + Logger.error(TAG, `Preferences flush failed.`); + } } } \ No newline at end of file diff --git a/common/src/main/ets/updateservice/UpdateService.ets b/common/src/main/ets/updateservice/UpdateService.ets index 2414e13b264d61bc2688f73dc202de68acb2b8c7..4216fa80965c54418959c85efb600c507e97e536 100644 --- a/common/src/main/ets/updateservice/UpdateService.ets +++ b/common/src/main/ets/updateservice/UpdateService.ets @@ -17,6 +17,7 @@ import { updateManager } from '@kit.StoreKit'; import type { common } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; import Logger from '../util/Logger'; +import { StorageKey } from '../constant/CommonEnums'; const TAG: string = '[UpdateService]'; @@ -35,9 +36,11 @@ export class UpdateService { } public checkUpdate(): Promise { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; return new Promise((resolve: Function, reject: Function) => { try { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; + updateManager.checkAppUpdate(context) .then((checkResult: updateManager.CheckUpdateResult) => { Logger.info(TAG, `Succeeded in checking Result updateAvailable:` + checkResult.updateAvailable); @@ -59,8 +62,9 @@ export class UpdateService { } public updateVersion(): Promise { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; return new Promise((resolve: Function, reject: Function) => { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; try { updateManager.showUpdateDialog(context) .then((resultCode: updateManager.ShowUpdateResultCode) => { diff --git a/common/src/main/ets/util/BreakpointSystem.ets b/common/src/main/ets/util/BreakpointSystem.ets index 1fe1b5f3a4bc6a730ea1649156ab9018ea197bf9..a365e221f0d8f864a0f5d5441da650e91703a8e3 100644 --- a/common/src/main/ets/util/BreakpointSystem.ets +++ b/common/src/main/ets/util/BreakpointSystem.ets @@ -15,7 +15,7 @@ import { display, window } from '@kit.ArkUI'; import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; -import { ProductSeriesEnum } from '../constant/CommonEnums'; +import { ProductSeriesEnum, StorageKey } from '../constant/CommonEnums'; import { BreakpointTypeEnum, GlobalInfoModel } from '../model/GlobalInfoModel'; import Logger from './Logger'; @@ -78,9 +78,9 @@ export class BreakpointSystem { public updateCurrentBreakpoint(breakpoint: BreakpointTypeEnum): void { if (this.currentBreakpoint !== breakpoint) { this.currentBreakpoint = breakpoint; - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); globalInfoModel.currentBreakpoint = this.currentBreakpoint; - AppStorage.setOrCreate('GlobalInfoModel', globalInfoModel); + AppStorage.setOrCreate(StorageKey.GLOBAL_INFO, globalInfoModel); } } @@ -92,7 +92,7 @@ export class BreakpointSystem { try { const mainWindow: window.WindowProperties = window.getWindowProperties(); const windowWidth: number = mainWindow.windowRect.width; - const windowWidthVp = px2vp(windowWidth); + const windowWidthVp = window.getUIContext().px2vp(windowWidth); const deviceType = deviceInfo.productSeries; if (deviceType === ProductSeriesEnum.HPR) { this.updateCurrentBreakpoint(BreakpointTypeEnum.XL); diff --git a/common/src/main/ets/util/BundleManagerUtil.ets b/common/src/main/ets/util/BundleManagerUtil.ets index ef143aad239dbed8aa53913f53ed7d60a7557408..7b6eac83ae8cc41d82ebbf336272b22c50572c60 100644 --- a/common/src/main/ets/util/BundleManagerUtil.ets +++ b/common/src/main/ets/util/BundleManagerUtil.ets @@ -17,6 +17,7 @@ import { bundleManager } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; import Logger from './Logger'; import { BundleInfoData } from '../model/BundleInfoData'; +import { StorageKey } from '../constant/CommonEnums'; const TAG = '[BundleManagerUtil]'; @@ -26,7 +27,7 @@ export class BundleManagerUtil { bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT) .then((bundleInfo: bundleManager.BundleInfo) => { Logger.debug(TAG, `getBundleInfoForSelf successed. ${bundleInfo}`); - AppStorage.setOrCreate('BundleInfoData', + AppStorage.setOrCreate(StorageKey.BUNDLE_INFO, new BundleInfoData(bundleInfo.versionName, bundleInfo.versionCode, bundleInfo.name)); }); } catch (err) { diff --git a/common/src/main/ets/util/ColorPickerUtil.ets b/common/src/main/ets/util/ColorPickerUtil.ets index 83620e736c63ed0bf8823e9a474a684462a9b0ef..bab8c9360b88c7425c7a7694a381239da6670e51 100644 --- a/common/src/main/ets/util/ColorPickerUtil.ets +++ b/common/src/main/ets/util/ColorPickerUtil.ets @@ -13,47 +13,91 @@ * limitations under the License. */ +enum ColorAreaEnum { + RED = 0, + YELLOW = 1, + GREEN = 2, + CYAN = 3, + BLUE = 4, + FUCHSIA = 5, +} + export class ColorPickerUtil { - private static currentColor: string; + // Constants for color segmentation. + private static readonly COLOR_SEGMENTS = 6; + private static readonly MAX_RGB_VALUE = 255; + private static readonly FULL_OPACITY = 1.0; + // Constants for RGB string processing. Length of "rgba(". + private static readonly RGB_PREFIX_LENGTH = 5; + // Constants for color segment boundaries. + public static readonly SEGMENT_1 = 1 / 6; + public static readonly SEGMENT_2 = 2 / 6; + public static readonly SEGMENT_3 = 3 / 6; + public static readonly SEGMENT_4 = 4 / 6; + public static readonly SEGMENT_5 = 5 / 6; + public static readonly SEGMENT_6 = 6 / 6; + /** + * Creates an RGBA color string from component values + * @param red Red component (0-255) + * @param green Green component (0-255) + * @param blue Blue component (0-255) + * @param opacity Opacity (0.0-1.0) + * @returns Formatted RGBA string + */ public static setRgba(red: number, green: number, blue: number, opacity: number): string { return `rgba(${red},${green},${blue},${opacity})`; } - public static getRgbText() { - return ColorPickerUtil.currentColor; - } - + /** + * Calculates a color based on slider position + * @param value Slider value (0-100) + * @returns RGBA color string + */ public static getBlockColor(value: number): string { - // Calculate the corresponding color based on the area of the slider. - const colorPercent = value / 100; + // Calculate the corresponding color based on the area of the slider.colorPercent(0-1) + const colorPercent = value / 100 * ColorPickerUtil.COLOR_SEGMENTS; let selectedColor: string = ''; - let colorAreaPercent: number = 0; - if (colorPercent >= 0 && colorPercent <= 1 / 6) { - colorAreaPercent = colorPercent * 6; - selectedColor = ColorPickerUtil.setRgba(255, Math.floor(colorAreaPercent * 255), 0, 1.00); - } else if (colorPercent >= 1 / 6 && colorPercent <= 2 / 6) { - colorAreaPercent = (colorPercent - 1 / 6) * 6; - selectedColor = ColorPickerUtil.setRgba(Math.floor(((1 - colorAreaPercent) * 255)), 255, 0, 1.00); - } else if (colorPercent >= 2 / 6 && colorPercent <= 3 / 6) { - colorAreaPercent = (colorPercent - 2 / 6) * 6; - selectedColor = ColorPickerUtil.setRgba(0, 255, Math.floor(colorAreaPercent * 255), 1.00); - } else if (colorPercent >= 3 / 6 && colorPercent <= 4 / 6) { - colorAreaPercent = (colorPercent - 3 / 6) * 6; - selectedColor = ColorPickerUtil.setRgba(0, Math.floor(((1 - colorAreaPercent) * 255)), 255, 1.00); - } else if (colorPercent >= 4 / 6 && colorPercent <= 5 / 6) { - colorAreaPercent = (colorPercent - 4 / 6) * 6; - selectedColor = ColorPickerUtil.setRgba(Math.floor(colorAreaPercent * 255), 0, 255, 1.00); - } else if (colorPercent >= 5 / 6 && colorPercent <= 6 / 6) { - colorAreaPercent = (colorPercent - 5 / 6) * 6; - selectedColor = ColorPickerUtil.setRgba(255, 0, Math.floor(((1 - colorAreaPercent) * 255)), 1.00); + const colorSegment: number = Math.trunc(colorPercent); + const colorAreaPercent: number = colorPercent - colorSegment; + switch (colorSegment) { + case ColorAreaEnum.RED: + selectedColor = ColorPickerUtil.setRgba(ColorPickerUtil.MAX_RGB_VALUE, + Math.floor(colorAreaPercent * ColorPickerUtil.MAX_RGB_VALUE), 0, ColorPickerUtil.FULL_OPACITY); + break; + case ColorAreaEnum.YELLOW: + selectedColor = ColorPickerUtil.setRgba(Math.floor(((1 - colorAreaPercent) * ColorPickerUtil.MAX_RGB_VALUE)), + ColorPickerUtil.MAX_RGB_VALUE, 0, ColorPickerUtil.FULL_OPACITY); + break; + case ColorAreaEnum.GREEN: + selectedColor = ColorPickerUtil.setRgba(0, ColorPickerUtil.MAX_RGB_VALUE, + Math.floor(colorAreaPercent * ColorPickerUtil.MAX_RGB_VALUE), ColorPickerUtil.FULL_OPACITY); + break; + case ColorAreaEnum.CYAN: + selectedColor = ColorPickerUtil.setRgba(0, Math.floor(((1 - colorAreaPercent) * ColorPickerUtil.MAX_RGB_VALUE)), + ColorPickerUtil.MAX_RGB_VALUE, ColorPickerUtil.FULL_OPACITY); + break; + case ColorAreaEnum.BLUE: + selectedColor = ColorPickerUtil.setRgba(Math.floor(colorAreaPercent * ColorPickerUtil.MAX_RGB_VALUE), 0, + ColorPickerUtil.MAX_RGB_VALUE, ColorPickerUtil.FULL_OPACITY); + break; + case ColorAreaEnum.FUCHSIA: + selectedColor = ColorPickerUtil.setRgba(ColorPickerUtil.MAX_RGB_VALUE, 0, + Math.floor(((1 - colorAreaPercent) * ColorPickerUtil.MAX_RGB_VALUE)), ColorPickerUtil.FULL_OPACITY); + break; + default: + selectedColor = ColorPickerUtil.setRgba(ColorPickerUtil.MAX_RGB_VALUE, 0, 0, ColorPickerUtil.FULL_OPACITY); } - ColorPickerUtil.currentColor = `${selectedColor.substring(4, selectedColor.length - 3)})`; return selectedColor; } + /** + * Calculate the color number of red, blue, green area. + * @param rgb, rgba(0, 255, 1, 1.00) + * @returns the number of three area. + */ public static getRgb(rgb: string): number[] { - rgb = rgb.substring(5, rgb.length - 1); + rgb = rgb.substring(ColorPickerUtil.RGB_PREFIX_LENGTH, rgb.length - 1); const rgbArray = rgb.split(','); const redArea: number = parseFloat(rgbArray[0]); const greenArea: number = parseFloat(rgbArray[1]); @@ -61,26 +105,31 @@ export class ColorPickerUtil { return [redArea, greenArea, blueArea]; } + /** + * Calculate the color accord to red, blue, green area. + * @param rgb, rgba(0, 255, 1, 1.00) + * @returns color number (0-100) + */ public static getColorFromRgb(rgb: string): number { const rgbArray = ColorPickerUtil.getRgb(rgb); const redArea: number = rgbArray[0]; const greenArea: number = rgbArray[1]; const blueArea: number = rgbArray[2]; - const allColorCount = 255 * 6; - let colorPercent: number = 0.00; - if (redArea === 255 && blueArea === 0) { - colorPercent = greenArea / allColorCount; - } else if (greenArea === 255 && blueArea === 0) { - colorPercent = (redArea + 255) / allColorCount; - } else if (redArea === 0 && greenArea === 255) { - colorPercent = (blueArea + 255 * 2) / allColorCount; - } else if (redArea === 0 && blueArea === 255) { - colorPercent = (greenArea + 255 * 3) / allColorCount; - } else if (greenArea === 0 && blueArea === 255) { - colorPercent = (redArea + 255 * 4) / allColorCount; - } else if (redArea === 255 && greenArea === 0) { - colorPercent = (blueArea + 255 * 5) / allColorCount; + let colorArea: number = 0.00; + if (redArea === ColorPickerUtil.MAX_RGB_VALUE && blueArea === 0) { + colorArea = ColorAreaEnum.RED + greenArea / ColorPickerUtil.MAX_RGB_VALUE; + } else if (greenArea === ColorPickerUtil.MAX_RGB_VALUE && blueArea === 0) { + colorArea = ColorAreaEnum.YELLOW + (redArea / ColorPickerUtil.MAX_RGB_VALUE); + } else if (redArea === 0 && greenArea === ColorPickerUtil.MAX_RGB_VALUE) { + colorArea = ColorAreaEnum.GREEN + (blueArea / ColorPickerUtil.MAX_RGB_VALUE); + } else if (redArea === 0 && blueArea === ColorPickerUtil.MAX_RGB_VALUE) { + colorArea = ColorAreaEnum.CYAN + (greenArea / ColorPickerUtil.MAX_RGB_VALUE); + } else if (greenArea === 0 && blueArea === ColorPickerUtil.MAX_RGB_VALUE) { + colorArea = ColorAreaEnum.BLUE + (redArea / ColorPickerUtil.MAX_RGB_VALUE); + } else if (redArea === ColorPickerUtil.MAX_RGB_VALUE && greenArea === 0) { + colorArea = ColorAreaEnum.FUCHSIA + (blueArea / ColorPickerUtil.MAX_RGB_VALUE); } - return colorPercent * 100; + const colorPercent = colorArea / ColorPickerUtil.COLOR_SEGMENTS * 100; + return colorPercent; } } \ No newline at end of file diff --git a/common/src/main/ets/util/ColorUtil.ets b/common/src/main/ets/util/ColorUtil.ets index f51183162066cdddf81c3dcd6962e700868bb429..da70bb71054b12296d156d43f37f46463496195d 100644 --- a/common/src/main/ets/util/ColorUtil.ets +++ b/common/src/main/ets/util/ColorUtil.ets @@ -17,93 +17,152 @@ * Color conversion processing class. */ export class ColorUtil { + // Color adjustment constants + private static readonly SATURATION_INCREMENT = 0.35; + private static readonly BRIGHTNESS_DECREMENT = 0.4; + private static readonly MIN_BRIGHTNESS = 0.15; + private static readonly BRIGHTNESS_OFFSET = 10; + private static readonly MAX_RGB = 255; + + // HSB conversion constants + private static readonly HUE_SEGMENTS = 6; + private static readonly DEGREES_PER_SEGMENT = 60; + private static readonly FULL_CIRCLE_DEGREES = 360; + + // Color component indices + private static readonly HUE_INDEX = 0; + private static readonly SATURATION_INDEX = 1; + private static readonly BRIGHTNESS_INDEX = 2; + /** - * Generate an immersive background color for the image. - * @Prop rRGB - * @Prop gRGB - * @Prop bRGB - * @returns + * Generates an immersive background color by adjusting saturation and brightness + * @param rRGB Red component (0-255) + * @param gRGB Green component (0-255) + * @param bRGB Blue component (0-255) + * @returns Adjusted RGB values as [r, g, b] */ public static getDeepenImmersionColor(rRGB: number, gRGB: number, bRGB: number): number[] { - const hsb: number[] = ColorUtil.rgbToHsb(rRGB, gRGB, bRGB); - const hHSB = hsb[0]; - let sHSB = hsb[1]; - let bHSB = hsb[2]; - sHSB = sHSB + 0.35; - if (bHSB > 0.15) { - bHSB = bHSB - 0.4; - if (bHSB < 0.15) { - bHSB = 0.15; - } + const hsb = ColorUtil.rgbToHsb(rRGB, gRGB, bRGB); + let saturation = hsb[ColorUtil.SATURATION_INDEX]; + let brightness = hsb[ColorUtil.BRIGHTNESS_INDEX]; + + // Increase saturation + saturation += ColorUtil.SATURATION_INCREMENT; + + // Decrease brightness with minimum threshold + if (brightness > ColorUtil.MIN_BRIGHTNESS) { + brightness -= ColorUtil.BRIGHTNESS_DECREMENT; + brightness = Math.max(brightness, ColorUtil.MIN_BRIGHTNESS); } - return ColorUtil.hsbToRgb(hHSB, sHSB, bHSB); + + return ColorUtil.hsbToRgb( + hsb[ColorUtil.HUE_INDEX], + saturation, + brightness + ); } - private static rgbToHsb(rRGB: number, gRGB: number, bRGB: number): [hHsb: number, sHsb: number, bHsb: number] { - const max = Math.max(rRGB, gRGB, bRGB); - const min = Math.min(rRGB, gRGB, bRGB); - const sHSB = max === 0 ? 0 : (max - min) / max; - const bHSB = (max + 10) / 255; - let hHSB = 0; - if (max === rRGB && gRGB >= bRGB) { - hHSB = 60 * (gRGB - bRGB) / (max - min) + 0; - } - if (max === rRGB && gRGB < bRGB) { - hHSB = 60 * (gRGB - bRGB) / (max - min) + 360; - } - if (max === gRGB) { - hHSB = 60 * (bRGB - rRGB) / (max - min) + 120; - } - if (max === bRGB) { - hHSB = 60 * (rRGB - gRGB) / (max - min) + 240; + /** + * Converts RGB color values to HSB (HSV) color space + * @param rRGB Red component (0-255) + * @param gRGB Green component (0-255) + * @param bRGB Blue component (0-255) + * @returns HSB values as [hue, saturation, brightness] + */ + private static rgbToHsb( + rRGB: number, + gRGB: number, + bRGB: number + ): [number, number, number] { + const normalizedR = rRGB / ColorUtil.MAX_RGB; + const normalizedG = gRGB / ColorUtil.MAX_RGB; + const normalizedB = bRGB / ColorUtil.MAX_RGB; + const max = Math.max(normalizedR, normalizedG, normalizedB); + const min = Math.min(normalizedR, normalizedG, normalizedB); + const delta = max - min; + let hue = 0; + const saturation = max === 0 ? 0 : delta / max; + const brightness = (max * ColorUtil.MAX_RGB + ColorUtil.BRIGHTNESS_OFFSET) / ColorUtil.MAX_RGB; + + if (delta !== 0) { + if (max === normalizedR) { + hue = ColorUtil.DEGREES_PER_SEGMENT * ((normalizedG - normalizedB) / delta % ColorUtil.HUE_SEGMENTS); + } else if (max === normalizedG) { + hue = ColorUtil.DEGREES_PER_SEGMENT * ((normalizedB - normalizedR) / delta + 2); + } else { + hue = ColorUtil.DEGREES_PER_SEGMENT * ((normalizedR - normalizedG) / delta + 4); + } + if (hue < 0) { + hue += ColorUtil.FULL_CIRCLE_DEGREES; + } } - return [hHSB, sHSB, bHSB]; + + return [hue, saturation, brightness]; } - private static hsbToRgb(hHSB: number, sHSB: number, bHSB: number): number[] { - const i: number = Math.floor((hHSB / 60) % 6); - const f = (hHSB / 60) - i; - const p = bHSB * (1 - sHSB); - const q = bHSB * (1 - f * sHSB); - const t = bHSB * (1 - (1 - f) * sHSB); - let rRGB = bHSB; - let gRGB = t; - let bRGB = p; - switch (i) { + /** + * Converts HSB (HSV) color values back to RGB color space + * @param hue Hue in degrees (0-360) + * @param saturation Saturation (0-1) + * @param brightness Brightness (0-1) + * @returns RGB values as [r, g, b] in 0-255 range + */ + private static hsbToRgb( + hue: number, + saturation: number, + brightness: number + ): number[] { + const segment = Math.floor((hue / ColorUtil.DEGREES_PER_SEGMENT) % ColorUtil.HUE_SEGMENTS); + const fractional = (hue / ColorUtil.DEGREES_PER_SEGMENT) - segment; + const p = brightness * (1 - saturation); + const q = brightness * (1 - fractional * saturation); + const t = brightness * (1 - (1 - fractional) * saturation); + // rgb + let r = brightness; + let g = t; + let b = p; + switch (segment) { case 0: - rRGB = bHSB; - gRGB = t; - bRGB = p; + r = brightness; + g = t; + b = p; break; case 1: - rRGB = q; - gRGB = bHSB; - bRGB = p; + r = q; + g = brightness; + b = p; break; case 2: - rRGB = p; - gRGB = bHSB; - bRGB = t; + r = p; + g = brightness; + b = t; break; case 3: - rRGB = p; - gRGB = q; - bRGB = bHSB; + r = p; + g = q; + b = brightness; break; case 4: - rRGB = t; - gRGB = p; - bRGB = bHSB; + r = t; + g = p; + b = brightness; break; case 5: - rRGB = bHSB; - gRGB = p; - bRGB = q; + r = brightness; + g = p; + b = q; break; default: + r = 0; + g = 0; + b = 0; break; } - return [Math.max(0, Math.floor(rRGB * 255.0)), Math.max(0, Math.floor(gRGB * 255.0)), - Math.max(0, Math.floor(bRGB * 255.0))]; + const scaleToRgb = (value: number) => Math.max(0, Math.floor(value * ColorUtil.MAX_RGB)); + return [ + scaleToRgb(r), + scaleToRgb(g), + scaleToRgb(b) + ]; } } \ No newline at end of file diff --git a/common/src/main/ets/util/DynamicInstallManager.ets b/common/src/main/ets/util/DynamicInstallManager.ets index 3943c044eb6ce425d30f088718e07a816e0f8235..6815807d25233d9d7a2b2f00022f8469a3100a2e 100644 --- a/common/src/main/ets/util/DynamicInstallManager.ets +++ b/common/src/main/ets/util/DynamicInstallManager.ets @@ -19,6 +19,7 @@ import { BusinessError, emitter } from '@kit.BasicServicesKit'; import { moduleInstallManager } from '@kit.StoreKit'; import Logger from './Logger'; import { CommonConstants } from '../constant/CommonConstants'; +import { StorageKey } from '../constant/CommonEnums'; const DOWNLOAD_TIMEOUT_LIMIT: number = 1800; const TAG: string = '[DynamicInstallManager]'; @@ -31,9 +32,14 @@ export class DynamicInstallManager { ]; public static getModuleStatus(moduleName: string): moduleInstallManager.InstallStatus { - const result: moduleInstallManager.InstalledModule = moduleInstallManager.getInstalledModule(moduleName); - Logger.info(TAG, `getModuleStatus moduleName: ${result.moduleName}, installStatus: ${result.installStatus}`); - return result.installStatus; + try { + const result: moduleInstallManager.InstalledModule = moduleInstallManager.getInstalledModule(moduleName); + Logger.info(TAG, `getModuleStatus moduleName: ${result.moduleName}, installStatus: ${result.installStatus}`); + return result.installStatus; + } catch { + Logger.error(TAG, `GetModuleStatus getInstalledModule failed.`); + return moduleInstallManager.InstallStatus.NOT_INSTALLED; + } } public static fetchModule(context: common.UIAbilityContext, @@ -131,19 +137,25 @@ export class DynamicInstallManager { } public static setStartAbilityProperty(): StartOptions { - const displayData = display.getDefaultDisplaySync(); - const windowWidth = displayData.availableWidth * CommonConstants.WINDOW_RATIO; - const windowHeight = displayData.availableHeight * CommonConstants.WINDOW_RATIO; - const windowLeft = (displayData.availableWidth - windowWidth) / 2.0; - const windowTop = (displayData.availableHeight - windowHeight) / 2.0; - const option: StartOptions = { - minWindowWidth: Math.min(px2vp(windowWidth), CommonConstants.MIN_WINDOW_WIDTH), - minWindowHeight: Math.min(px2vp(windowHeight), CommonConstants.MIN_WINDOW_HEIGHT), - windowLeft: windowLeft, - windowTop: windowTop, - windowWidth: windowWidth, - windowHeight: windowHeight, - }; - return option; + try { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const displayData = display.getDefaultDisplaySync(); + const windowWidth = displayData.availableWidth * CommonConstants.WINDOW_RATIO; + const windowHeight = displayData.availableHeight * CommonConstants.WINDOW_RATIO; + const windowLeft = (displayData.availableWidth - windowWidth) / 2.0; + const windowTop = (displayData.availableHeight - windowHeight) / 2.0; + const option: StartOptions = { + minWindowWidth: Math.min(uiContext.px2vp(windowWidth), CommonConstants.MIN_WINDOW_WIDTH), + minWindowHeight: Math.min(uiContext.px2vp(windowHeight), CommonConstants.MIN_WINDOW_HEIGHT), + windowLeft: windowLeft, + windowTop: windowTop, + windowWidth: windowWidth, + windowHeight: windowHeight, + }; + return option; + } catch { + Logger.error(TAG, `SetStartAbilityProperty getDefaultDisplaySync failed.`); + return {}; + } } } \ No newline at end of file diff --git a/common/src/main/ets/util/ProcessUtil.ets b/common/src/main/ets/util/ProcessUtil.ets index 587b829e6cb0ed9b8ffd1a9bfe5cf3ccce597bad..8d20a964defe4865e204ddbd038f8a6f2367c0de 100644 --- a/common/src/main/ets/util/ProcessUtil.ets +++ b/common/src/main/ets/util/ProcessUtil.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { common } from '@kit.AbilityKit'; +import type { common, StartOptions, Want } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; import Logger from './Logger'; @@ -45,4 +45,20 @@ export class ProcessUtil { Logger.error(TAG, `moveAbilityToBackground failed error: ${err.code}, ${err.message}`); } } + + public static startAbility(context: common.UIAbilityContext, want: Want, options?: StartOptions): Promise { + try { + return context.startAbility(want, options).then(() => { + Logger.info(TAG, 'startAbility succeed'); + return true; + }).catch((err: BusinessError) => { + Logger.error(TAG, `startAbility failed, cause ${err.code}, ${err.message}`); + return false; + }); + } catch (error) { + const err: BusinessError = error as BusinessError; + Logger.error(TAG, `startAbility failed error: ${err.code}, ${err.message}`); + return Promise.resolve(false); + } + } } \ No newline at end of file diff --git a/common/src/main/ets/util/ResourceUtil.ets b/common/src/main/ets/util/ResourceUtil.ets index 207f4ec26d34365aa75bbd21468d3c21642f5854..b085b37397c9745eb00fd4562b7b4a4590f12d90 100644 --- a/common/src/main/ets/util/ResourceUtil.ets +++ b/common/src/main/ets/util/ResourceUtil.ets @@ -17,6 +17,7 @@ import { effectKit } from '@kit.ArkGraphics2D'; import { JSON, util } from '@kit.ArkTS'; import { BusinessError } from '@kit.BasicServicesKit'; import { image } from '@kit.ImageKit'; +import { StorageKey } from '../constant/CommonEnums'; import Logger from './Logger'; const TAG: string = '[ResourceUtil]'; @@ -96,8 +97,10 @@ export class ResourceUtil { } public static getColorDataByPath(mediaUrl: string): Promise { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: Context = uiContext.getHostContext() as Context; return new Promise((resolve: (value: number[]) => void, reject: (reason?: Object) => void) => { - getContext().resourceManager.getRawFileContent(mediaUrl) + context.resourceManager.getRawFileContent(mediaUrl) .then((unit8Array: Uint8Array) => { let imageSource: image.ImageSource | undefined = undefined; let pixelMap: image.PixelMap | undefined = undefined; diff --git a/common/src/main/ets/util/WebUtil.ets b/common/src/main/ets/util/WebUtil.ets index 08d7df31f601d9360ca54ea88667406654ff51b7..533117e7888e1b4283cb2dd61f0e376e4882e5b9 100644 --- a/common/src/main/ets/util/WebUtil.ets +++ b/common/src/main/ets/util/WebUtil.ets @@ -14,13 +14,15 @@ */ import { uri } from '@kit.ArkTS'; -import { BuilderNode, FrameNode, NodeController, window } from '@kit.ArkUI'; +import { BuilderNode, FrameNode, NodeController, UIContext, window } from '@kit.ArkUI'; import { webview } from '@kit.ArkWeb'; import { BusinessError } from '@kit.BasicServicesKit'; -import { ModuleNameEnum, ScrollDirectionEnum } from '../constant/CommonEnums'; +import { ModuleNameEnum, ScrollDirectionEnum, StorageKey } from '../constant/CommonEnums'; import Logger from './Logger'; import { NetworkUtil } from './NetworkUtil'; import { ConfigMapKey, ResourceUtil } from './ResourceUtil'; +import { common, Want } from '@kit.AbilityKit'; +import { ProcessUtil } from './ProcessUtil'; const TAG: string = '[WebUtil]'; @@ -32,7 +34,6 @@ const pageEventMap: Map = new Map(); const nodeRequiredMap: Map = new Map(); // Check whether web node is required again. const webLoadedMap: Map = new Map(); let currentOffset: number = 0; -let context: UIContext; const componentCodeHtml: string = `/codePreview/index.html`; @@ -76,20 +77,18 @@ function webBuilder(param: WebBuilderParam) { Logger.debug(TAG, `onPageBegin with url: ${param.webUrl}`); }) .onPageEnd(() => { - AppStorage.setOrCreate('webIsLoading', false); - WebUtil.setTrustList(param.webUrl); + AppStorage.setOrCreate(StorageKey.WEB_LOADING, false); Logger.debug(TAG, `onPageEnd with url: ${param.webUrl}`); }) .onLoadIntercept((event: OnLoadInterceptEvent) => { - const tempUrl = event.data.getRequestUrl(); - return WebUtil.checkUrl(tempUrl); + return WebUtil.handleLoadIntercept(event); }) .onSslErrorEventReceive((event) => { Logger.error(TAG, `SSL checked failed, error: ${event.error.toString()}`); event.handler.handleCancel(); }) - .onScroll((event) => { - if (param.module && event.yOffset) { + .onScroll((event: OnScrollEvent) => { + if (param.module) { const eventEmitter = eventEmitterMap.get(param.module); const scrollOffset: number = event.yOffset - currentOffset; currentOffset = event.yOffset; @@ -101,12 +100,13 @@ function webBuilder(param: WebBuilderParam) { } }) .onControllerAttached(() => { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; try { param.webController.onActive(); const userAgent = `${param.webController.getUserAgent()} Mobile`; param.webController.setCustomUserAgent(userAgent); // Setting the local file path that allows cross-domain access. - param.webController.setPathAllowingUniversalAccess([getContext().resourceDir]); + param.webController.setPathAllowingUniversalAccess([uiContext.getHostContext()!.resourceDir]); } catch (error) { const err: BusinessError = error as BusinessError; Logger.error(TAG, `Web User-Agent setting error: ${err.code}, ${err.message}.`); @@ -138,6 +138,7 @@ export class NativeActionData { } export class WebUtil { + private static uiContext: UIContext; public static readonly ARTICLE_WHITE_METHODS: string[] = ['checkPreview()', 'closePreview()']; static addNode(url: string) { @@ -146,14 +147,14 @@ export class WebUtil { public static initialize(windowStage: window.WindowStage) { try { - context = windowStage.getMainWindowSync().getUIContext(); + WebUtil.uiContext = windowStage.getMainWindowSync().getUIContext(); webNodeMap.clear(); webControllerMap.clear(); webview.WebviewController.initializeWebEngine(); - WebUtil.createWebNode(WebUtil.getComponentCodeUrl(), context, undefined, ModuleNameEnum.CODE_PREVIEW, true, - false); + WebUtil.createWebNode(WebUtil.getComponentCodeUrl(), WebUtil.uiContext, undefined, ModuleNameEnum.CODE_PREVIEW, + true, false); } catch (err) { - Logger.error(TAG, `Initialize failed. Cause: ${err.code} ${err.message}`); + Logger.error(TAG, `WebUtil initialize failed. Cause: ${err.code} ${err.message}`); } } @@ -172,15 +173,20 @@ export class WebUtil { } public static checkWebLoaded(url: string): boolean { - const loaded: boolean = !!webLoadedMap.get(url); - if (!loaded && NetworkUtil.hasDefaultNet()) { - const webController = WebUtil.getWebController(url); - AppStorage.setOrCreate('webIsLoading', true); - webLoadedMap.set(url, true); - webController?.refresh(); - return true; + try { + const loaded: boolean = !!webLoadedMap.get(url); + if (!loaded && NetworkUtil.hasDefaultNet()) { + const webController = WebUtil.getWebController(url); + AppStorage.setOrCreate(StorageKey.WEB_LOADING, true); + webLoadedMap.set(url, true); + webController?.refresh(); + return true; + } + return loaded; + } catch { + Logger.error(TAG, `CheckWebLoaded failed.`); + return false; } - return loaded; } public static createWebNode(webUrl: string, uiContext?: UIContext, nestedScrollMode?: NestedScrollMode, @@ -190,8 +196,8 @@ export class WebUtil { Logger.debug(TAG, `Has web node with url: ${webUrl}, should not create web node.`); return; } - if (!context && uiContext) { - context = uiContext; + if (!WebUtil.uiContext && uiContext) { + WebUtil.uiContext = uiContext; } Logger.debug(TAG, `initWebNode with url: ${webUrl}`); const webNode = new WebNodeController(); @@ -215,7 +221,7 @@ export class WebUtil { scrollBackward: nestedScrollMode, }; } - webNode.initWebNode(context, webBuilderParam); + webNode.initWebNode(WebUtil.uiContext, webBuilderParam); webLoadedMap.set(webUrl, NetworkUtil.hasDefaultNet()); webControllerMap.set(webUrl, webController); webNodeMap.set(webUrl, webNode); @@ -264,7 +270,8 @@ export class WebUtil { public static setTrustList(webUrl: string): void { const webController: webview.WebviewController = webControllerMap.get(webUrl)!; try { - const whitelist: string = ResourceUtil.getRawFileStringByKey(getContext(), ConfigMapKey.WHITELIST); + const whitelist: string = + ResourceUtil.getRawFileStringByKey(WebUtil.uiContext.getHostContext()!, ConfigMapKey.WHITELIST); webController?.setUrlTrustList(whitelist); } catch (error) { const err: BusinessError = error as BusinessError; @@ -272,10 +279,43 @@ export class WebUtil { } } + public static handleLoadIntercept(event: OnLoadInterceptEvent): boolean { + const tempUrl = event.data.getRequestUrl(); + if (WebUtil.checkUrl(tempUrl)) { + return false; + } + let want: Want = { + action: 'ohos.want.action.viewData', + entities: ['entity.system.browsable'], + uri: tempUrl, + parameters: { + 'ohos.ability.params.showDefaultPicker': true + } + }; + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; + ProcessUtil.startAbility(context, want); + return true; + } + public static checkUrl(url: string): boolean { const tempUri: uri.URI = new uri.URI(url); const res: uri.URI = tempUri.normalize(); Logger.debug(TAG, `Web request url : ${res.toString()}`); + // Allow application internal resource. + if (res.scheme === 'file' || res.scheme === 'resource') { + return true; + } + if (res.scheme === 'https') { + // Allow official site. + if (res.host.endsWith('huawei.com')) { + return true; + } + // Allow official sample code repo site. + if (res.host === 'gitee.com' && res.path.startsWith('/harmonyos_samples')) { + return true; + } + } return false; } @@ -291,8 +331,16 @@ export class WebUtil { pageEventMap.set(url, callback); } + public static upPage(url: string) { + webNodeMap.get(url)?.add(); + } + + public static downPage(url: string) { + webNodeMap.get(url)?.remove(); + } + public static getComponentCodeUrl() { - return getContext().resourceDir + componentCodeHtml; + return WebUtil.uiContext.getHostContext()!.resourceDir + componentCodeHtml; } } diff --git a/common/src/main/ets/util/WindowUtil.ets b/common/src/main/ets/util/WindowUtil.ets index 75e90f5a110fc8b877f0bbad6a17af69c03ffb6b..0abfd12fe0a9cbc8a87fb5fbc0eef95e7574217c 100644 --- a/common/src/main/ets/util/WindowUtil.ets +++ b/common/src/main/ets/util/WindowUtil.ets @@ -18,7 +18,7 @@ import { AbilityConstant } from '@kit.AbilityKit'; import { display, window } from '@kit.ArkUI'; import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; import { CommonConstants } from '../constant/CommonConstants'; -import { ProductSeriesEnum } from '../constant/CommonEnums'; +import { ProductSeriesEnum, StorageKey } from '../constant/CommonEnums'; import { GlobalInfoModel } from '../model/GlobalInfoModel'; import { BreakpointSystem } from './BreakpointSystem'; import Logger from './Logger'; @@ -26,132 +26,127 @@ import Logger from './Logger'; const TAG: string = '[WindowUtil]'; export class WindowUtil { - public static updateStatusBarColor(context: common.BaseContext, isDark: boolean): void { - window.getLastWindow(context).then((windowClass: window.Window) => { - try { - windowClass.setWindowSystemBarProperties({ - statusBarContentColor: isDark ? StatusBarColorType.WHITE : StatusBarColorType.BLACK - }).then(() => { - Logger.info(TAG, 'Succeeded in setting the system bar properties.'); - }).catch((err: BusinessError) => { - Logger.error(TAG, `Failed to set the system bar properties. Cause: ${err.code} ${err.message}`); - }); - } catch (error) { - const err: BusinessError = error as BusinessError; - Logger.error(TAG, `Failed to set the system bar properties. Cause: ${err.code}, ${err.message}`); - } - }).catch((error: BusinessError) => { - Logger.error(TAG, `GetLastWindow failed. code: ${error.code}, message: ${error.message}`); - }); + private static windowClass?: window.Window; + private static uiContext: UIContext; + + public static initialize(windowStage: window.WindowStage) { + try { + WindowUtil.windowClass = windowStage.getMainWindowSync(); + const uiContext: UIContext = WindowUtil.windowClass.getUIContext(); + WindowUtil.uiContext = uiContext; + AppStorage.setOrCreate(StorageKey.UI_CONTEXT, uiContext); + WindowUtil.registerBreakpoint(WindowUtil.windowClass); + WindowUtil.requestFullScreen(); + // Hide PC/2in1 title bar. + WindowUtil.hideTitleBar(); + } catch (err) { + Logger.error(TAG, `WindowUtil initialize failed. Cause: ${err.code} ${err.message}`); + } } - public static hideTitleBar(windowStage: window.WindowStage) { - windowStage.getMainWindow().then((data: window.Window) => { - try { - if (canIUse('SystemCapability.Window.SessionManager')) { - data.setWindowDecorVisible(false); - data.setWindowDecorHeight(CommonConstants.NAVIGATION_HEIGHT); - } else { - Logger.error(TAG, `setWindowDecorVisible invalid`); - } - } catch (error) { - const err: BusinessError = error as BusinessError; - Logger.error(TAG, `Failed to set the visibility of window decor. Cause: ${err.code}, ${err.message}`); - } - }).catch((err: BusinessError) => { - Logger.error(TAG, `Failed to obtain the main window. Cause: ${err.code}, ${err.message}`); - }) + public static updateStatusBarColor(isDark: boolean): void { + try { + WindowUtil.windowClass?.setWindowSystemBarProperties({ + statusBarContentColor: isDark ? StatusBarColorType.WHITE : StatusBarColorType.BLACK + }).then(() => { + Logger.info(TAG, 'Succeeded in setting the system bar properties.'); + }).catch((err: BusinessError) => { + Logger.error(TAG, `Failed to set the system bar properties. Cause: ${err.code} ${err.message}`); + }); + } catch (error) { + const err: BusinessError = error as BusinessError; + Logger.error(TAG, `Failed to set the system bar properties. Cause: ${err.code}, ${err.message}`); + } } - public static requestFullScreen(windowStage: window.WindowStage, context: Context): void { - windowStage.getMainWindow((err: BusinessError, data: window.Window) => { - if (err.code) { - Logger.error(TAG, `Failed to obtain the main window. Cause: ${err.code}, ${err.message}`); - return; - } - Logger.debug(TAG, `Succeeded in obtaining the main window. Data: ${JSON.stringify(data)}`); - const windowClass: window.Window = data; - // Realize the immersive effect. - try { - if (deviceInfo.productSeries === ProductSeriesEnum.HPR) { - WindowUtil.resetWindowSize(windowClass); - } - const promise: Promise = windowClass.setWindowLayoutFullScreen(true); - promise.then(() => { - Logger.info(TAG, 'Succeeded in setting the window layout to full-screen mode.'); - }).catch((err: BusinessError) => { - Logger.error(TAG, - `Failed to set the window layout to full-screen mode. Cause: ${err.code}, ${err.message}`); - }); - WindowUtil.getDeviceSize(context); - } catch { - Logger.error(TAG, 'Failed to set the window layout to full-screen mode. '); + private static hideTitleBar() { + try { + if (canIUse('SystemCapability.Window.SessionManager')) { + WindowUtil.windowClass?.setWindowDecorVisible(false); + WindowUtil.windowClass?.setWindowDecorHeight(CommonConstants.NAVIGATION_HEIGHT); + } else { + Logger.error(TAG, `setWindowDecorVisible invalid`); } - }); + } catch (error) { + const err: BusinessError = error as BusinessError; + Logger.error(TAG, `Failed to set the visibility of window decor. Cause: ${err.code}, ${err.message}`); + } } - private static resetWindowSize(windowClass: window.Window): void { - if (canIUse('SystemCapability.Window.SessionManager')) { - const windowSize: display.Display = display.getDefaultDisplaySync(); - const appWidth: number = windowSize.width * 9 / 10; - const appHeight: number = windowSize.height * 7 / 8; - const windowLimits: window.WindowLimits = { - maxWidth: appWidth, - maxHeight: appHeight, - minWidth: appWidth, - minHeight: appHeight, + private static requestFullScreen(): void { + // Realize the immersive effect. + try { + if (deviceInfo.productSeries === ProductSeriesEnum.HPR) { + WindowUtil.resetWindowSize(); } - windowClass.setWindowLimits(windowLimits); - windowClass.moveWindowToAsync(windowSize.width / 20, windowSize.height / 16); + const promise: Promise | undefined = WindowUtil.windowClass?.setWindowLayoutFullScreen(true); + promise?.then(() => { + Logger.info(TAG, 'Succeeded in setting the window layout to full-screen mode.'); + }).catch((err: BusinessError) => { + Logger.error(TAG, + `Failed to set the window layout to full-screen mode. Cause: ${err.code}, ${err.message}`); + }); + WindowUtil.getDeviceSize(); + } catch { + Logger.error(TAG, 'Failed to set the window layout to full-screen mode. '); } } - private static getDeviceSize(context: Context): void { - // Get device height. - window.getLastWindow(context).then((data: window.Window) => { + private static resetWindowSize(): void { + if (canIUse('SystemCapability.Window.SessionManager')) { try { - const properties = data.getWindowProperties(); - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); - globalInfoModel.deviceHeight = px2vp(properties.windowRect.height); - globalInfoModel.deviceWidth = px2vp(properties.windowRect.width); - if (canIUse('SystemCapability.Window.SessionManager')) { - const decorHeight: number = data?.getWindowDecorHeight(); - globalInfoModel.decorHeight = decorHeight; - } - AppStorage.setOrCreate('GlobalInfoModel', globalInfoModel); + const windowSize: display.Display = display.getDefaultDisplaySync(); + const appWidth: number = windowSize.width * 9 / 10; + const appHeight: number = windowSize.height * 7 / 8; + const windowLimits: window.WindowLimits = { + maxWidth: appWidth, + maxHeight: appHeight, + minWidth: appWidth, + minHeight: appHeight, + }; + WindowUtil.windowClass?.setWindowLimits(windowLimits); + WindowUtil.windowClass?.moveWindowToAsync(windowSize.width / 20, windowSize.height / 16); } catch (err) { - const error = err as BusinessError; - Logger.error(TAG, `Get and setDeviceSize failed. code: ${error.code}, message: ${error.message}`); + Logger.error(TAG, `Failed to getDefaultDisplaySync.`); } - }).catch((error: BusinessError) => { - Logger.error(TAG, `GetLastWindow failed. code: ${error.code}, message: ${error.message}`); - }); + } } - public static setMainWindowOrientation(context: Context, orientation: window.Orientation, - onSuccess?: () => void): void { - window.getLastWindow(context).then((windowClass: window.Window) => { - if (windowClass === undefined) { - Logger.error(TAG, `MainWindowClass is undefined.`); - return; + private static getDeviceSize(): void { + // Get device height. + try { + const properties = WindowUtil.windowClass?.getWindowProperties(); + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); + if (properties?.windowRect) { + globalInfoModel.deviceHeight = WindowUtil.uiContext.px2vp(properties.windowRect.height); + globalInfoModel.deviceWidth = WindowUtil.uiContext.px2vp(properties.windowRect.width); } - try { - // Setting window preferred orientation. - windowClass.setPreferredOrientation(orientation, (err: BusinessError) => { - const errCode = err.code; - if (errCode) { - Logger.error(TAG, `Failed to set window orientation. Cause code: ${err.code}, message: ${err.message}`); - return; - } - onSuccess?.(); - }); - } catch (err) { - const error = err as BusinessError; - Logger.error(TAG, `SetPreferredOrientation failed. code: ${error.code}, message: ${error.message}`); + if (canIUse('SystemCapability.Window.SessionManager')) { + const decorHeight: number = WindowUtil.windowClass?.getWindowDecorHeight() || 0; + globalInfoModel.decorHeight = decorHeight; } - }).catch((error: BusinessError) => { - Logger.error(TAG, `GetLastWindow failed. code: ${error.code}, message: ${error.message}`); - }); + AppStorage.setOrCreate(StorageKey.GLOBAL_INFO, globalInfoModel); + } catch (err) { + const error = err as BusinessError; + Logger.error(TAG, `Get and setDeviceSize failed. code: ${error.code}, message: ${error.message}`); + } + } + + public static setMainWindowOrientation(orientation: window.Orientation, onSuccess?: () => void): void { + try { + // Setting window preferred orientation. + WindowUtil.windowClass?.setPreferredOrientation(orientation, (err: BusinessError) => { + const errCode = err.code; + if (errCode) { + Logger.error(TAG, `Failed to set window orientation. Cause code: ${err.code}, message: ${err.message}`); + return; + } + onSuccess?.(); + }); + } catch (err) { + const error = err as BusinessError; + Logger.error(TAG, `SetPreferredOrientation failed. code: ${error.code}, message: ${error.message}`); + } } public static setMissionContinueActive(context: common.UIAbilityContext, active: boolean) { @@ -163,90 +158,67 @@ export class WindowUtil { }); } - public static enableFloatWindowRotate(context: Context): void { - window.getLastWindow(context).then((windowClass: window.Window) => { - if (windowClass === undefined) { - Logger.error(TAG, `MainWindowClass is undefined`); - return; - } - try { - if (canIUse('SystemCapability.Window.SessionManager')) { - windowClass.enableLandscapeMultiWindow(); - } else { - Logger.error(TAG, `enableLandscapeMultiWindow invalid`); - } - } catch (err) { - const error = err as BusinessError; - Logger.error(TAG, `enableLandscapeMultiWindow failed. code: ${error.code}, message: ${error.message}`); + public static enableFloatWindowRotate(): void { + try { + if (canIUse('SystemCapability.Window.SessionManager')) { + WindowUtil.windowClass?.enableLandscapeMultiWindow(); + } else { + Logger.error(TAG, `enableLandscapeMultiWindow invalid`); } - }).catch((error: BusinessError) => { - Logger.error(TAG, `GetLastWindow failed. code: ${error.code}, message: ${error.message}`); - }); + } catch (err) { + const error = err as BusinessError; + Logger.error(TAG, `enableLandscapeMultiWindow failed. code: ${error.code}, message: ${error.message}`); + } } - public static disableFloatWindowRotate(context: Context): void { - window.getLastWindow(context).then((windowClass: window.Window) => { - if (windowClass === undefined) { - Logger.error(TAG, `MainWindowClass is undefined`); - return; + public static disableFloatWindowRotate(): void { + try { + if (canIUse('SystemCapability.Window.SessionManager')) { + WindowUtil.windowClass?.disableLandscapeMultiWindow(); + } else { + Logger.error(TAG, `disableLandscapeMultiWindow invalid`); } - try { - if (canIUse('SystemCapability.Window.SessionManager')) { - windowClass.disableLandscapeMultiWindow(); - } else { - Logger.error(TAG, `disableLandscapeMultiWindow invalid`); - } - } catch (err) { - const error = err as BusinessError; - Logger.error(TAG, `disableLandscapeMultiWindow failed. code: ${error.code}, message: ${error.message}`); - } - }).catch((error: BusinessError) => { - Logger.error(TAG, `GetLastWindow failed. code: ${error.code}, message: ${error.message}`); - }); - ; + } catch (err) { + const error = err as BusinessError; + Logger.error(TAG, `disableLandscapeMultiWindow failed. code: ${error.code}, message: ${error.message}`); + } } - public static registerBreakPoint(windowStage: window.WindowStage) { - windowStage.getMainWindow((err: BusinessError, data: window.Window) => { - if (err.code) { - Logger.error(TAG, `Failed to get main window: ${err.message}`); - return; - } - try { - BreakpointSystem.getInstance().updateWidthBp(data); - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); - const systemAvoidArea: window.AvoidArea = data.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - globalInfoModel.statusBarHeight = px2vp(systemAvoidArea.topRect.height); - const bottomArea: window.AvoidArea = data.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - globalInfoModel.naviIndicatorHeight = px2vp(bottomArea.bottomRect.height); - AppStorage.setOrCreate('GlobalInfoModel', globalInfoModel); - data.on('windowSizeChange', () => WindowUtil.onWindowSizeChange(data)); - data.on('avoidAreaChange', (avoidAreaOption) => { - if (avoidAreaOption.type === window.AvoidAreaType.TYPE_SYSTEM || - avoidAreaOption.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { - WindowUtil.setAvoidArea(avoidAreaOption.type, avoidAreaOption.area); - } - }); - } catch (e) { - const error = e as BusinessError; - Logger.error(TAG, `getWindowAvoidArea failed. code: ${error.code}, message: ${error.message}`); - } - }); + private static registerBreakpoint(windowClass: window.Window) { + BreakpointSystem.getInstance().updateWidthBp(windowClass); + try { + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); + const systemAvoidArea: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + globalInfoModel.statusBarHeight = WindowUtil.uiContext.px2vp(systemAvoidArea.topRect.height); + const bottomArea: window.AvoidArea = + windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + globalInfoModel.naviIndicatorHeight = WindowUtil.uiContext.px2vp(bottomArea.bottomRect.height); + AppStorage.setOrCreate(StorageKey.GLOBAL_INFO, globalInfoModel); + windowClass.on('windowSizeChange', () => WindowUtil.onWindowSizeChange(windowClass)); + windowClass.on('avoidAreaChange', (avoidAreaOption) => { + if (avoidAreaOption.type === window.AvoidAreaType.TYPE_SYSTEM || + avoidAreaOption.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { + WindowUtil.setAvoidArea(avoidAreaOption.type, avoidAreaOption.area); + } + }); + } catch (err) { + Logger.error(TAG, `getWindowAvoidArea failed. error message: ${err.message}`); + } } // Get status bar height and indicator height. public static setAvoidArea(type: window.AvoidAreaType, area: window.AvoidArea) { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); if (type === window.AvoidAreaType.TYPE_SYSTEM) { - globalInfoModel.statusBarHeight = px2vp(area.topRect.height); + globalInfoModel.statusBarHeight = WindowUtil.uiContext.px2vp(area.topRect.height); } else { - globalInfoModel.naviIndicatorHeight = px2vp(area.bottomRect.height); + globalInfoModel.naviIndicatorHeight = WindowUtil.uiContext.px2vp(area.bottomRect.height); } - AppStorage.setOrCreate('GlobalInfoModel', globalInfoModel); + AppStorage.setOrCreate(StorageKey.GLOBAL_INFO, globalInfoModel); } public static onWindowSizeChange(window: window.Window) { - WindowUtil.getDeviceSize(getContext()); + WindowUtil.getDeviceSize(); BreakpointSystem.getInstance().onWindowSizeChange(window); } } diff --git a/common/src/main/ets/view/NoNetworkView.ets b/common/src/main/ets/view/NoNetworkView.ets index fa5c6f4f77bd9138486815d2961b83eac9191b83..aa52ea960b428a8891d40231b59ed657fb5e63ae 100644 --- a/common/src/main/ets/view/NoNetworkView.ets +++ b/common/src/main/ets/view/NoNetworkView.ets @@ -14,14 +14,11 @@ */ import type { common, Want } from '@kit.AbilityKit'; -import type { BusinessError } from '@kit.BasicServicesKit'; import { CommonConstants } from '../constant/CommonConstants'; -import { ColumnEnum } from '../constant/CommonEnums'; +import { ColumnEnum, StorageKey } from '../constant/CommonEnums'; import { BreakpointTypeEnum } from '../model/GlobalInfoModel'; import { BreakpointType } from '../util/BreakpointSystem'; -import Logger from '../util/Logger'; - -const TAG = '[NoNetworkView]'; +import { ProcessUtil } from '../util/ProcessUtil'; @Builder export function NoNetworkView(breakpoint: BreakpointTypeEnum, handleReload?: () => void) { @@ -52,22 +49,14 @@ export function NoNetworkView(breakpoint: BreakpointTypeEnum, handleReload?: () { buttonStyle: ButtonStyleMode.NORMAL, controlSize: ControlSize.NORMAL }) .width('100%') .onClick(() => { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; const want: Want = { bundleName: 'com.huawei.hmos.settings', abilityName: 'com.huawei.hmos.settings.MainAbility', uri: 'wifi_entry', }; - try { - context.startAbility(want).then(() => { - Logger.info(TAG, `start setting ability succeed. `); - }).catch((err: BusinessError) => { - Logger.error(TAG, `start setting ability failed. ${err.code}, ${err.message}.`); - }); - } catch (err) { - const error = err as BusinessError; - Logger.error(TAG, `StartAbility failed. code: ${error.code}, message: ${error.message}`); - } + ProcessUtil.startAbility(context, want); }) .margin({ bottom: $r('app.float.loading_size_sm') }) } diff --git a/common/src/main/resources/rawfile/mockdata/file-data.json b/common/src/main/resources/rawfile/mockdata/file-data.json index d20037d759c811cb396522709c64cd6e7239ce7e..885724662ca1620449048bf5f612223f4bfd0843 100644 --- a/common/src/main/resources/rawfile/mockdata/file-data.json +++ b/common/src/main/resources/rawfile/mockdata/file-data.json @@ -802,7 +802,7 @@ "propertyValues": "''" }, { - "propertyName": "loop", + "propertyName": "autoPlay", "propertyDesc": "自动轮播", "displayType": "boolean", "defaultProperty": "true", @@ -1173,7 +1173,7 @@ "propertyDesc": "段落行数", "displayType": "number", "defaultProperty": "2", - "propertyValues": "{ \"left\": 1, \"right\": 6, \"step\": 1 }" + "propertyValues": "{ \"left\": 1, \"right\": 5, \"step\": 1 }" }, { "propertyName": "highlightColor", diff --git a/common/src/main/resources/rawfile/mockdata/sample-details-all.json b/common/src/main/resources/rawfile/mockdata/sample-details-all.json index f4eef444eda102b682075386b6efee09b529d307..7c474c25f8da1399224db4aedc15513a04819349 100644 --- a/common/src/main/resources/rawfile/mockdata/sample-details-all.json +++ b/common/src/main/resources/rawfile/mockdata/sample-details-all.json @@ -44,7 +44,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/hdc/sample_business.png", - "originalUrl": "https://gitee.com/harmonyos_samples/MultiBusinessOffice/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/MultiBusinessOffice/blob/br_release_hmos/README.md", "moduleName": "multibusinesssample", "abilityName": "MultibusinesssampleAbility", "order": 2 @@ -121,7 +121,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_nav_bar.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-nav-bar/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-nav-bar/blob/br_release_hmos/README.md", "moduleName": "multinavbarsample", "abilityName": "MultinavbarsampleAbility", "order": 1 @@ -142,9 +142,9 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_convenient_life.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-convenient-life/blob/br_release_hmosworld_new/README.md", - "moduleName": "multiconvinientlifesample", - "abilityName": "MulticonvinientlifesampleAbility", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-convenient-life/blob/br_release_hmos/README.md", + "moduleName": "multiconvenientlifesample", + "abilityName": "MulticonvenientlifesampleAbility", "order": 1 } ] @@ -163,7 +163,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_mobile_payment.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-mobile-payment/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-mobile-payment/blob/br_release_hmos/README.md", "moduleName": "multimobilepaymentsample", "abilityName": "MultimobilepaymentsampleAbility", "order": 1 @@ -184,7 +184,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_news_read.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-news-read/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-news-read/blob/br_release_hmos/README.md", "moduleName": "multinewsreadsample", "abilityName": "MultinewsreadsampleAbility", "order": 1 @@ -205,7 +205,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_travel_accommodation.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-travel-accommodation/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-travel-accommodation/blob/br_release_hmos/README.md", "moduleName": "multitravelsample", "abilityName": "MultitravelsampleAbility", "order": 1 @@ -226,7 +226,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/multidevice/sample_multi_columns.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-columns/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-columns/blob/br_release_hmos/README.md", "moduleName": "multicolumnssample", "abilityName": "MulticolumnssampleAbility", "order": 1 @@ -247,7 +247,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/style/sample_text_effects.gif", - "originalUrl": "https://gitee.com/harmonyos_samples/text-effects/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/text-effects/blob/br_release_hmos/README.md", "moduleName": "texteffectssample", "abilityName": "TexteffectssampleAbility", "order": 1 @@ -261,7 +261,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/style/sample_multi_tab_navigation.png", - "originalUrl": "https://gitee.com/harmonyos_samples/multi-tab-navigation/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/multi-tab-navigation/blob/br_release_hmos/README.md", "moduleName": "multitabnavigationsample", "abilityName": "MultitabnavigationsampleAbility", "order": 2 @@ -275,7 +275,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/style/sample_custom_dialog_gathers.png", - "originalUrl": "https://gitee.com/harmonyos_samples/custom-dialog-gathers/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/custom-dialog-gathers/blob/br_release_hmos/README.md", "moduleName": "customdialogsample", "abilityName": "CustomdialogsampleAbility", "order": 3 @@ -296,8 +296,8 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/layout/sample_scroll_component_nested_sliding.png", - "originalUrl": "https://gitee.com/harmonyos_samples/scroll-component-nested-sliding/blob/br_release_hmosworld_new/README.md", - "moduleName": "nestedslidingsample", + "originalUrl": "https://gitee.com/harmonyos_samples/scroll-component-nested-sliding/blob/br_release_hmos/README.md", + "moduleName": "scrollcomponentsample", "abilityName": "NestedslidingsampleAbility", "order": 1 }, @@ -310,7 +310,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/layout/sample_water_flow.png", - "originalUrl": "https://gitee.com/harmonyos_samples/water-flow/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/water-flow/blob/br_release_hmos/README.md", "moduleName": "waterflowsample", "abilityName": "WaterflowsampleAbility", "order": 2 @@ -324,7 +324,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/layout/sample_component_stack.png", - "originalUrl": "https://gitee.com/harmonyos_samples/component-stack/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/component-stack/blob/br_release_hmos/README.md", "moduleName": "componentstacksample", "abilityName": "ComponentstacksampleAbility", "order": 3 @@ -338,7 +338,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/layout/sample_grid_hybrid.png", - "originalUrl": "https://gitee.com/harmonyos_samples/grid-hybrid/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/grid-hybrid/blob/br_release_hmos/README.md", "moduleName": "gridhybridsample", "abilityName": "GridhybridsampleAbility", "order": 4 @@ -359,9 +359,9 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/effect/sample_transitions_collection.gif", - "originalUrl": "https://gitee.com/harmonyos_samples/transitions-collection/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/transitions-collection/blob/br_release_hmos/README.md", "moduleName": "transitionscollectionsample", - "abilityName": "TransitionscollectionsampleAbility", + "abilityName": "TransitioncollectionsampleAbility", "order": 1 }, { @@ -373,7 +373,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/effect/sample_animation_collection.png", - "originalUrl": "https://gitee.com/harmonyos_samples/animation-collection/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/animation-collection/blob/br_release_hmos/README.md", "moduleName": "animationcollectionsample", "abilityName": "AnimationcollectionsampleAbility", "order": 2 @@ -387,7 +387,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/effect/sample_drag_framework.png", - "originalUrl": "https://gitee.com/harmonyos_samples/DragFramework/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/DragFramework/blob/br_release_hmos/README.md", "moduleName": "dragframeworksample", "abilityName": "DragframeworksampleAbility", "order": 3 @@ -408,7 +408,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/list/sample_fluent_blog.png", - "originalUrl": "https://gitee.com/harmonyos_samples/fluent-blog/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/fluent-blog/blob/br_release_hmos/README.md", "moduleName": "fluentblogsample", "abilityName": "FluentblogsampleAbility", "order": 1 @@ -422,7 +422,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/list/sample_list_exchange.png", - "originalUrl": "https://gitee.com/harmonyos_samples/list-exchange/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/list-exchange/blob/br_release_hmos/README.md", "moduleName": "listexchangesample", "abilityName": "ListexchangesampleAbility", "order": 2 @@ -436,7 +436,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/list/sample_list_item_edit.png", - "originalUrl": "https://gitee.com/harmonyos_samples/list-item-edit/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/list-item-edit/blob/br_release_hmos/README.md", "moduleName": "listitemeditsample", "abilityName": "ListitemeditsampleAbility", "order": 3 @@ -457,7 +457,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/media/sample_window_pip.png", - "originalUrl": "https://gitee.com/harmonyos_samples/window-pip/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/window-pip/blob/br_release_hmos/README.md", "moduleName": "windowpipsample", "abilityName": "WindowpipsampleAbility", "order": 1 @@ -471,7 +471,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/media/sample_multiple_image.png", - "originalUrl": "https://gitee.com/harmonyos_samples/MultipleImage/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/MultipleImage/blob/br_release_hmos/README.md", "moduleName": "multipleimagesample", "abilityName": "MultipleimagesampleAbility", "order": 2 @@ -485,7 +485,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/media/sample_audio_interaction.png", - "originalUrl": "https://gitee.com/harmonyos_samples/audio-interaction/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/audio-interaction/blob/br_release_hmos/README.md", "moduleName": "audiointeractionsample", "abilityName": "AudiointeractionsampleAbility", "order": 3 @@ -506,7 +506,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/capacity/sample_page_redirection.png", - "originalUrl": "https://gitee.com/harmonyos_samples/page-redirection/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/page-redirection/blob/br_release_hmos/README.md", "moduleName": "pageredirectionsample", "abilityName": "PageredirectionsampleAbility", "order": 1 @@ -520,7 +520,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/capacity/sample_web_pre_render.png", - "originalUrl": "https://gitee.com/harmonyos_samples/web-pre-render/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/web-pre-render/blob/br_release_hmos/README.md", "moduleName": "webprerendersample", "abilityName": "WebprerendersampleAbility", "order": 2 @@ -534,7 +534,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/capacity/sample_location_service.png", - "originalUrl": "https://gitee.com/harmonyos_samples/location-service/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/location-service/blob/br_release_hmos/README.md", "moduleName": "locationservicesample", "abilityName": "LocationservicesampleAbility", "order": 3 @@ -555,7 +555,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/data/sample_preferences.png", - "originalUrl": "https://gitee.com/harmonyos_samples/preferences/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/preferences/blob/br_release_hmos/README.md", "moduleName": "preferencessample", "abilityName": "PreferencessampleAbility", "order": 1 @@ -569,7 +569,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/scene/sample_verification_code_scenario.png", - "originalUrl": "https://gitee.com/harmonyos_samples/verification-code-scenario/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/verification-code-scenario/blob/br_release_hmos/README.md", "moduleName": "verificationcodescenariosample", "abilityName": "VerificationcodescenariosampleAbility", "order": 2 @@ -583,7 +583,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/scene/sample_image_comment.png", - "originalUrl": "https://gitee.com/harmonyos_samples/image-comment/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/image-comment/blob/br_release_hmos/README.md", "moduleName": "imagecommentsample", "abilityName": "ImagecommentsampleAbility", "order": 3 @@ -597,7 +597,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/function/data/sample_picker.png", - "originalUrl": "https://gitee.com/harmonyos_samples/picker/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/picker/blob/br_release_hmos/README.md", "moduleName": "pickersample", "abilityName": "PickersampleAbility", "order": 4 @@ -611,7 +611,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "image/sample/arkui/scene/sample_keyboard.png", - "originalUrl": "https://gitee.com/harmonyos_samples/keyboard/blob/br_release_hmosworld_new/README.md", + "originalUrl": "https://gitee.com/harmonyos_samples/keyboard/blob/br_release_hmos/README.md", "moduleName": "keyboardsample", "abilityName": "KeyboardsampleAbility", "order": 5 diff --git a/common/src/main/resources/rawfile/mockdata/wearable-sample-list.json b/common/src/main/resources/rawfile/mockdata/wearable-sample-list.json index 2bb14e84204b2b484311fa851218c50a8c03cbc1..b91c2127306b54312d5829086c3e31ba3a5428ba 100644 --- a/common/src/main/resources/rawfile/mockdata/wearable-sample-list.json +++ b/common/src/main/resources/rawfile/mockdata/wearable-sample-list.json @@ -9,7 +9,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "app.media.wearable_sample_music", - "originalUrl": "https://gitee.com/zq-kexin/WearableMusic", + "originalUrl": "https://gitee.com/harmonyos_samples/WearableMusic", "moduleName": "wearablemusicsample", "abilityName": "WearableMusicSampleAbility", "order": 1, @@ -22,7 +22,7 @@ "isFavorite": false, "mediaType": 3, "mediaUrl": "sys.symbol.video_badge_adiowaves_fill", - "originalUrl": "https://gitee.com/lv-yuanyuan001/SmartWatchShortVideo", + "originalUrl": "https://gitee.com/harmonyos_samples/SmartWatchShortVideo", "moduleName": "smartwatchshortvideosample", "abilityName": "SmartWatchShortVideoSampleAbility", "order": 1, @@ -35,7 +35,7 @@ "isFavorite": false, "mediaType": 1, "mediaUrl": "app.media.wearable_sample_map", - "originalUrl": "https://gitee.com/lv-yuanyuan001/SmartWatchMap", + "originalUrl": "https://gitee.com/harmonyos_samples/SmartWatchMap", "moduleName": "smartwatchmapsample", "abilityName": "SmartWatchMapSampleAbility", "order": 1, @@ -48,7 +48,7 @@ "isFavorite": false, "mediaType": 3, "mediaUrl": "sys.symbol.car_fill", - "originalUrl": "https://gitee.com/dong-haifan/SmartWatchCarControl", + "originalUrl": "https://gitee.com/harmonyos_samples/SmartWatchCarControl", "moduleName": "smartwatchcarcontrolsample", "abilityName": "SmartWatchCarControlSampleAbility", "order": 1, diff --git a/features/commonbusiness/src/main/ets/component/BannerCard.ets b/features/commonbusiness/src/main/ets/component/BannerCard.ets index 38a5f953b42c298f1e7d53997d1245c695ea401b..1cf051182121c42ff3769bc463f9274f47dc841c 100644 --- a/features/commonbusiness/src/main/ets/component/BannerCard.ets +++ b/features/commonbusiness/src/main/ets/component/BannerCard.ets @@ -13,22 +13,24 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import type { BannerData } from '../model/BannerData'; import type { BannerState } from '../viewmodel/BaseHomeState'; import { BannerItem } from './BannerItem'; +import { BannerProgress } from './BannerProgress'; +import { ProgressController } from './ProgressController'; const ICON_HEIGHT = 32; const ICON_PADDING = 24; const BANNER_ASPECT = 1.75; -const BANNER_DOT_HEIGHT = 2; const BANNER_DOT_SPACING = 8; +const ANIMATION_DELAY = 50; @Component export struct BannerCard { - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop @Require bannerState: BannerState; @Prop @Require tabViewType: number; handleItemClick?: (bannerData: BannerData) => void; @@ -37,10 +39,12 @@ export struct BannerCard { md: CommonConstants.SPACE_24, lg: CommonConstants.SPACE_32 }).getValue(this.globalInfoModel.currentBreakpoint); - private catchCount: number = this.bannerState.bannerResource.totalCount(); private swiperController: SwiperController = new SwiperController(); private scrollerController: Scroller = new Scroller(); private bannerOffset: number = this.bannerState.bannerHeight * BANNER_ASPECT; + private isAnimating: boolean = false; + @State catchCount: number = this.bannerState.bannerResource.totalCount(); + @State progressController: ProgressController = new ProgressController(); @State currentIndex: number = 0; @State showLeftIcon: boolean = false; @State showRightIcon: boolean = true; @@ -62,6 +66,53 @@ export struct BannerCard { } } + @Builder + BannerSwiperBuilder() { + Swiper(this.swiperController) { + LazyForEach(this.bannerState.bannerResource, (bannerData: BannerData) => { + BannerItem({ bannerData: bannerData }) + .reuseId('banner_swiper') + .onClick(() => { + this.handleItemClick?.(bannerData); + }) + }, (bannerData: BannerData) => bannerData.id.toString()) + } + .onChange((index: number) => { + this.currentIndex = index; + }) + .cachedCount(this.catchCount) + .loop(true) + .autoPlay(this.catchCount > 1) + .effectMode(EdgeEffect.None) + .indicator(false) + .width('100%') + .height(this.bannerState.bannerHeight) + .geometryTransition(CommonConstants.BANNER_GEOMETRY + this.tabViewType.toString(), { follow: true }) + .transition(TransitionEffect.OPACITY) + .onAnimationStart((index: number, targetIndex: number) => { + this.isAnimating = true; + if (index === targetIndex) { + this.progressController.restartBannerProgress(); + } else { + this.currentIndex = targetIndex; + } + }) + .onAnimationEnd(() => { + this.isAnimating = false; + }) + .onTouch((event: TouchEvent) => { + if (event.type === TouchType.Down) { + this.progressController.stopBannerProgress(); + } else if (event.type === TouchType.Up) { + if (!this.isAnimating) { + setTimeout(() => { + this.progressController.restartBannerProgress(); + }, ANIMATION_DELAY) + } + } + }) + } + build() { if (this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.LG || this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { @@ -151,36 +202,21 @@ export struct BannerCard { top: this.globalInfoModel.statusBarHeight + CommonConstants.NAVIGATION_HEIGHT + CommonConstants.SPACE_8, }) } else { - Swiper(this.swiperController) { - LazyForEach(this.bannerState.bannerResource, (bannerData: BannerData) => { - BannerItem({ bannerData: bannerData }) - .reuseId('banner_swiper') - .onClick(() => { - this.handleItemClick?.(bannerData); - }) - }, (bannerData: BannerData) => bannerData.id.toString()) + Stack({ alignContent: Alignment.Bottom }) { + this.BannerSwiperBuilder(); + BannerProgress({ + progressController: this.progressController, + currentIndex: this.currentIndex, + totalCount: this.catchCount + }) } - .onChange((index: number) => { - this.currentIndex = index; + .onVisibleAreaChange([0.0], (isVisible: boolean, currentRatio: number) => { + if (currentRatio > 0) { + this.progressController.restartBannerProgress(); + } else { + this.progressController.stopBannerProgress(); + } }) - .cachedCount(this.catchCount) - .itemSpace(0) - .loop(true) - .autoPlay(this.catchCount > 1) - .effectMode(EdgeEffect.None) - .indicator(this.catchCount > 1 ? - new DotIndicator() - .itemWidth(this.bannerWidth) - .itemHeight(BANNER_DOT_HEIGHT) - .color($r('sys.color.icon_on_tertiary')) - .selectedItemWidth(this.bannerWidth) - .selectedItemHeight(BANNER_DOT_HEIGHT) - .selectedColor($r('sys.color.icon_on_primary')) : - false) - .width('100%') - .height(this.bannerState.bannerHeight) - .geometryTransition(CommonConstants.BANNER_GEOMETRY + this.tabViewType.toString(), { follow: true }) - .transition(TransitionEffect.OPACITY) } } diff --git a/features/commonbusiness/src/main/ets/component/BannerItem.ets b/features/commonbusiness/src/main/ets/component/BannerItem.ets index 263a13bc6ba28626d8b3440dd2034cb78075dc39..8c2186d7071e35d386232fc86891d67d388e2ff5 100644 --- a/features/commonbusiness/src/main/ets/component/BannerItem.ets +++ b/features/commonbusiness/src/main/ets/component/BannerItem.ets @@ -14,14 +14,14 @@ */ import { deviceInfo } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, ProductSeriesEnum } from '@ohos/common'; import type { BannerData } from '../model/BannerData'; @Reusable @Component export struct BannerItem { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @State bannerData?: BannerData = undefined; aboutToReuse(params: Record): void { diff --git a/features/commonbusiness/src/main/ets/component/BannerProgress.ets b/features/commonbusiness/src/main/ets/component/BannerProgress.ets new file mode 100644 index 0000000000000000000000000000000000000000..e8828d26984832b5b979bcf1ac8849d1be100d93 --- /dev/null +++ b/features/commonbusiness/src/main/ets/component/BannerProgress.ets @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonConstants } from '@ohos/common'; +import { BannerConstants } from '../constant/BannerConstants'; +import { ProgressController, ProgressState } from './ProgressController'; + +@Component +export struct BannerProgress { + @State progressArray: number[] = []; + @State currentProgressValue: number = 0; + @Link @Watch('handleProgressControllerChange') progressController: ProgressController; + @Prop @Watch('updateCurrentProgress') currentIndex: number; + @Prop @Watch('updateProgressArray') totalCount: number; + private intervalID: number = -1; + + aboutToAppear(): void { + this.updateProgressArray(); + this.updateCurrentProgress(); + } + + aboutToDisappear(): void { + this.currentProgressValue = 0; + clearInterval(this.intervalID); + } + + private handleProgressControllerChange() { + if (this.progressController.getProgressState() === ProgressState.STOP) { + clearInterval(this.intervalID); + } else if (this.progressController.getProgressState() === ProgressState.RESTART) { + this.updateCurrentProgress(); + } + } + + private updateProgressArray(): void { + this.progressArray.length = this.totalCount; + this.progressArray.fill(1); + } + + private updateCurrentProgress(): void { + this.currentProgressValue = 0; + clearInterval(this.intervalID); + this.intervalID = setInterval(() => { + this.currentProgressValue += BannerConstants.FRAME_TIME; + if (this.currentProgressValue >= BannerConstants.PROGRESS_VALUE_MAX) { + clearInterval(this.intervalID); + } + }, BannerConstants.FRAME_TIME) + } + + build() { + Row({ space: CommonConstants.SPACE_6 }) { + ForEach(this.progressArray, (item: number, index: number) => { + Progress({ + value: index === this.currentIndex ? this.currentProgressValue : + (index < this.currentIndex ? BannerConstants.PROGRESS_VALUE_MAX : 0), + total: BannerConstants.PROGRESS_VALUE_MAX, + type: ProgressType.Linear + }) + .color($r('app.color.banner_progress_color')) + .style({ + strokeWidth: $r('sys.float.border_extra_larger'), + enableSmoothEffect: false, + }) + .backgroundColor($r('sys.color.icon_on_fourth')) + .flexShrink(1) + }) + } + .width('100%') + .padding({ + bottom: $r('sys.float.padding_level7'), + left: $r('sys.float.padding_level8'), + right: $r('sys.float.padding_level8'), + }) + } +} \ No newline at end of file diff --git a/features/commonbusiness/src/main/ets/component/BaseDetailComponent.ets b/features/commonbusiness/src/main/ets/component/BaseDetailComponent.ets index 40520bb3bbf56612697bb987005cd324565197f9..579be098ea808277ee06b8784cd7cd52f1d92b92 100644 --- a/features/commonbusiness/src/main/ets/component/BaseDetailComponent.ets +++ b/features/commonbusiness/src/main/ets/component/BaseDetailComponent.ets @@ -13,11 +13,12 @@ * limitations under the License. */ -import { GlobalInfoModel, LoadingFailedView, LoadingStatus, LoadingView, NoNetworkView } from '@ohos/common'; +import { GlobalInfoModel, LoadingFailedView, LoadingStatus, LoadingView, NoNetworkView, + StorageKey } from '@ohos/common'; @Component export struct BaseDetailComponent { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop loadingStatus: LoadingStatus; @BuilderParam @Require detailContentView: () => void; @BuilderParam @Require topTitleView: () => void; diff --git a/features/commonbusiness/src/main/ets/component/FullScreenNavigation.ets b/features/commonbusiness/src/main/ets/component/FullScreenNavigation.ets index b3bc0a1dac70d1ca69ce3f94f3aead1ba5721a0b..33de4b782e0247f0c33b5be8e4db21e9b974e7d0 100644 --- a/features/commonbusiness/src/main/ets/component/FullScreenNavigation.ets +++ b/features/commonbusiness/src/main/ets/component/FullScreenNavigation.ets @@ -13,15 +13,15 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import { FullScreenNavigationData } from '../model/FullScreenNavigationData'; @Component export struct FullScreenNavigation { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop topNavigationData: FullScreenNavigationData = new FullScreenNavigationData(); - @StorageProp('BlurRenderGroup') blurRenderGroup: boolean = false; + @StorageProp(StorageKey.BLUE_RENDER_GROUP) blurRenderGroup: boolean = false; @BuilderParam tabView?: () => void; build() { diff --git a/features/commonbusiness/src/main/ets/component/ProgressController.ets b/features/commonbusiness/src/main/ets/component/ProgressController.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c5ec3fd09e36a73ee5a26bb43c71abea3694d0c --- /dev/null +++ b/features/commonbusiness/src/main/ets/component/ProgressController.ets @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class ProgressController { + private progressState: ProgressState = ProgressState.STOP; + + public stopBannerProgress() { + this.progressState = ProgressState.STOP; + } + + public restartBannerProgress() { + this.progressState = ProgressState.RESTART; + } + + public getProgressState(): ProgressState { + return this.progressState; +} +} + + +export enum ProgressState { + RESTART = 0, + STOP = 1, +} \ No newline at end of file diff --git a/features/commonbusiness/src/main/ets/constant/BannerConstants.ets b/features/commonbusiness/src/main/ets/constant/BannerConstants.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef9a16814ab859acea0d806ef41ae5449564f52 --- /dev/null +++ b/features/commonbusiness/src/main/ets/constant/BannerConstants.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class BannerConstants { + public static readonly PROGRESS_VALUE_MAX: number = 2300; + /** + * The frame rate of the animation is 30fps. + */ + private static readonly FRAME_RATE: number = 30; + /** + * The time it takes for one frame. + */ + public static readonly FRAME_TIME: number = 1000 / BannerConstants.FRAME_RATE; +} \ No newline at end of file diff --git a/features/commonbusiness/src/main/ets/view/BaseHomeView.ets b/features/commonbusiness/src/main/ets/view/BaseHomeView.ets index 88df38bc54129283228037209c31a5239d17a279..a09b09845be196cefef38b52a07c1087b8ee1c9c 100644 --- a/features/commonbusiness/src/main/ets/view/BaseHomeView.ets +++ b/features/commonbusiness/src/main/ets/view/BaseHomeView.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel, LoadingModel } from '@ohos/common'; +import { GlobalInfoModel, LoadingModel, StorageKey } from '@ohos/common'; import { LoadingFailedView, LoadingStatus, LoadingView, NoNetworkView } from '@ohos/common'; @Component @@ -21,7 +21,7 @@ export struct BaseHomeView { @Prop @Require loadingModel: LoadingModel; @BuilderParam @Require contentView: () => void; @BuilderParam @Require topTitleView: () => void; - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; reloadData?: Function; build() { diff --git a/features/commonbusiness/src/main/ets/viewmodel/BaseHomeViewModel.ets b/features/commonbusiness/src/main/ets/viewmodel/BaseHomeViewModel.ets index d74347bf7aa2cda4b0c819d10087c9f9d62a557c..4a586e63b869b328fdb90a1adb2b1c0c93d72a81 100644 --- a/features/commonbusiness/src/main/ets/viewmodel/BaseHomeViewModel.ets +++ b/features/commonbusiness/src/main/ets/viewmodel/BaseHomeViewModel.ets @@ -16,7 +16,7 @@ import { ConfigurationConstant } from '@kit.AbilityKit'; import { curves } from '@kit.ArkUI'; import { deviceInfo } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BaseVM, BreakpointType, @@ -50,7 +50,7 @@ export class BaseHomeViewModel extends BaseVM extends BaseVM extends BaseVM 1) { return; } - const isDark: boolean = AppStorage.get('systemColorMode') === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; + const isDark: boolean = + AppStorage.get(StorageKey.COLOR_MODE) === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; if (isDark) { this.state.topNavigationData.titleColor = `rgba(255,255,255, 1)`; } else { @@ -154,7 +155,7 @@ export class BaseHomeViewModel extends BaseVM extends BaseVM extends BaseVM extends BaseVM 0 ? isDark : true); + if (offsetParam.tabIndex === AppStorage.get(StorageKey.CURRENT_TAB) && pageContext.navPathStack.size() === 1) { + WindowUtil.updateStatusBarColor(opacity > 0 ? isDark : true); } let colorData: number = 255; if (!isDark) { @@ -233,12 +235,11 @@ export class BaseHomeViewModel extends BaseVM extends BaseVM extends BaseVM extends BaseVM { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + uiContext.animateTo({ curve: curves.interpolatingSpring(0, 1, 273, 33) }, () => { currentPageContext.openPage({ routerName: 'BannerDetailView', param: articleParam, @@ -290,7 +292,8 @@ export class BaseHomeViewModel extends BaseVM { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + uiContext.animateTo({ curve: this.springBackAnimation, duration: 250 }, () => { this.changeBannerHeight(); this.state.topNavigationData.titleOffsetY = 0; this.state.topNavigationData.titleScale = 1; diff --git a/features/commonbusiness/src/main/resources/base/element/color.json b/features/commonbusiness/src/main/resources/base/element/color.json index d058d3d88b13d34a9daa42540fe3deb766937933..13b3fbb2cadbf73fe9457453f3b0054cfea40494 100644 --- a/features/commonbusiness/src/main/resources/base/element/color.json +++ b/features/commonbusiness/src/main/resources/base/element/color.json @@ -3,6 +3,10 @@ { "name": "blur_bg", "value": "#CCF1F3F5" + }, + { + "name": "banner_progress_color", + "value": "#EFFFFFFF" } ] } \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/component/CodePreviewComponent.ets b/features/componentlibrary/src/main/ets/component/CodePreviewComponent.ets index 3e31484b99c2eeb04823fdfb03e23fbe8f7f679b..3fd7280cd88c6964dbccdc2bd3a6c489a4d2ba54 100644 --- a/features/componentlibrary/src/main/ets/component/CodePreviewComponent.ets +++ b/features/componentlibrary/src/main/ets/component/CodePreviewComponent.ets @@ -15,15 +15,16 @@ import { common, ConfigurationConstant } from '@kit.AbilityKit'; import { uniformTypeDescriptor as utd } from '@kit.ArkData'; -import { promptAction, window } from '@kit.ArkUI'; +import { window } from '@kit.ArkUI'; import { BusinessError, pasteboard } from '@kit.BasicServicesKit'; import { systemShare } from '@kit.ShareKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, ResourceUtil, StorageKey } from '@ohos/common'; import { BreakpointTypeEnum, CommonConstants, Logger, ScreenOrientation, + Toast, WebNodeController, WindowUtil, } from '@ohos/common'; @@ -33,9 +34,9 @@ const TAG: string = '[CodePreviewComponent]'; @Component export struct CodePreviewComponent { - @StorageProp('systemColorMode') @Watch('onHandleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop @Watch('flushCode') code: string = ''; @Prop pageContainer: boolean = false; @Prop isFocus: boolean = false; @@ -128,7 +129,7 @@ export struct CodePreviewComponent { aboutToAppear?(): void { if (this.pageContainer) { try { - window.getLastWindow(getContext()).then((windowClass: window.Window) => { + window.getLastWindow(this.getUIContext().getHostContext()).then((windowClass: window.Window) => { if (windowClass === undefined) { Logger.error(TAG, `MainWindowClass is undefined`); return; @@ -188,7 +189,7 @@ export struct CodePreviewComponent { CodePreviewJSUtil.codeViewRunJS(codeToHtmlMethod, params); } - onHandleColorModeChange() { + handleColorModeChange() { if (this.colorMode !== this.systemColorMode) { this.changeColorMode(); } @@ -202,7 +203,7 @@ export struct CodePreviewComponent { this.colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT; this.isDarkMode = false; } - WindowUtil.updateStatusBarColor(getContext(this), this.isDarkMode); + WindowUtil.updateStatusBarColor(this.isDarkMode); const changeColorModeMethod: string = 'changeColorMode(%param)'; const params: string = JSON.stringify(this.colorMode); CodePreviewJSUtil.codeViewRunJS(changeColorModeMethod, params); @@ -210,11 +211,11 @@ export struct CodePreviewComponent { private changeScreenOrientation(): void { if (this.screenOrientation === ScreenOrientation.PORTRAIT) { - WindowUtil.enableFloatWindowRotate(getContext()); - WindowUtil.setMainWindowOrientation(getContext(), window.Orientation.LANDSCAPE); + WindowUtil.enableFloatWindowRotate(); + WindowUtil.setMainWindowOrientation(window.Orientation.LANDSCAPE); } else { - WindowUtil.disableFloatWindowRotate(getContext()); - WindowUtil.setMainWindowOrientation(getContext(), window.Orientation.PORTRAIT); + WindowUtil.disableFloatWindowRotate(); + WindowUtil.setMainWindowOrientation(window.Orientation.PORTRAIT); } } @@ -234,9 +235,8 @@ export struct CodePreviewComponent { } private handleShare(): void { - let context = getContext(this) as common.UIAbilityContext; - const shareDescription = - context.resourceManager.getStringSync($r('app.string.share_description').id, this.componentName); + const context = this.getUIContext().getHostContext() as common.UIAbilityContext; + const shareDescription = ResourceUtil.getResourceString(context, $r('app.string.share_description')); const shareData: systemShare.SharedData = new systemShare.SharedData({ utd: utd.UniformDataType.PLAIN_TEXT, content: this.code, @@ -244,7 +244,7 @@ export struct CodePreviewComponent { description: shareDescription }); - let controller: systemShare.ShareController = new systemShare.ShareController(shareData); + const controller: systemShare.ShareController = new systemShare.ShareController(shareData); controller.show(context, { selectionMode: systemShare.SelectionMode.SINGLE, previewMode: systemShare.SharePreviewMode.DEFAULT @@ -258,14 +258,9 @@ export struct CodePreviewComponent { const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); const systemPasteboard = pasteboard.getSystemPasteboard(); systemPasteboard.setData(pasteboardData).then(() => { - try { - promptAction.showToast({ message: $r('app.string.copy_success') }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showToast($r('app.string.copy_success')) }).catch((error: BusinessError) => { - promptAction.showToast({ message: $r('app.string.copy_fail') }); + Toast.showToast($r('app.string.copy_fail')); Logger.error(TAG, `Copy data failed, the code is ${error.code}}, the message is ${error.message}`); }) } catch (err) { @@ -349,8 +344,7 @@ export struct CodePreviewComponent { .onClick(() => this.onBackPage?.()) .onHover((isHover: boolean) => { this.backIconBgColor = !isHover ? Color.Transparent : - this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT ? - $r('sys.color.comp_background_tertiary') : $r('sys.color.icon_on_tertiary'); + this.isDarkMode ? $r('sys.color.icon_on_tertiary') : $r('sys.color.comp_background_tertiary'); }) Text(this.componentName) @@ -372,19 +366,16 @@ export struct CodePreviewComponent { .onClick(() => this.handleShare()) .onHover((isHover: boolean) => { this.shareIconBgColor = !isHover ? Color.Transparent : - this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT ? - $r('sys.color.comp_background_tertiary') : $r('sys.color.icon_on_tertiary'); + this.isDarkMode ? $r('sys.color.icon_on_tertiary') : $r('sys.color.comp_background_tertiary'); }) if (this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { Row({ space: CommonConstants.SPACE_8 }) { ForEach(this.pcBottomIconItems, (item: ItemData, index: number) => { Row() { - SymbolGlyph(this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT ? - item.lightMode.iconResource : item.darkMode.iconResource) + SymbolGlyph(this.isDarkMode ? item.darkMode.iconResource : item.lightMode.iconResource) .fontSize($r('app.float.symbol_size_large')) - .fontColor(this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT ? - [$r('sys.color.icon_primary')] : [$r('sys.color.icon_on_primary')]) + .fontColor(this.isDarkMode ? [$r('sys.color.icon_on_primary')] : [$r('sys.color.icon_primary')]) .opacity(this.isFocus ? 1 : 0.4) } .justifyContent(FlexAlign.Center) @@ -519,7 +510,7 @@ export struct CodePreviewComponent { } }) .onDisAppear(() => { - WindowUtil.disableFloatWindowRotate(getContext()); + WindowUtil.disableFloatWindowRotate(); }) .backgroundColor($r('sys.color.comp_background_primary')) .padding(this.pageContainer === false ? { diff --git a/features/componentlibrary/src/main/ets/component/ColorPickerComponent.ets b/features/componentlibrary/src/main/ets/component/ColorPickerComponent.ets index 2785ed874c1930e9c55b1b093ea9a829c27bdec7..511eae0c9e501547977b02547e85b954e59ad2fd 100644 --- a/features/componentlibrary/src/main/ets/component/ColorPickerComponent.ets +++ b/features/componentlibrary/src/main/ets/component/ColorPickerComponent.ets @@ -22,7 +22,7 @@ import type { ColorPickerAttribute } from '../viewmodel/ComponentDetailState'; @Component export struct ColorPickerComponent { @ObjectLink attribute: ColorPickerAttribute; - callback: (name: string, value: string) => void = (name: string, value: string) => { + callback: (name: string, value: string, mode?: SliderChangeMode) => void = (name: string, value: string) => { }; build() { @@ -45,18 +45,18 @@ export struct ColorPickerComponent { const curentValue: string = ColorPickerUtil.getBlockColor(value); if (this.attribute.currentValue !== String(curentValue)) { this.attribute.currentValue = curentValue; - this.callback(this.attribute.name, curentValue); + this.callback(this.attribute.name, curentValue, mode); } }) .selectedColor(Color.Transparent) .trackColor(new LinearGradient([ { color: ColorPickerUtil.setRgba(255, 0, 0, 1.00), offset: 0 }, - { color: ColorPickerUtil.setRgba(255, 255, 0, 1.00), offset: 1 / 6 }, - { color: ColorPickerUtil.setRgba(0, 255, 0, 1.00), offset: 2 / 6 }, - { color: ColorPickerUtil.setRgba(8, 255, 255, 1.00), offset: 3 / 6 }, - { color: ColorPickerUtil.setRgba(0, 0, 255, 1.00), offset: 4 / 6 }, - { color: ColorPickerUtil.setRgba(255, 0, 255, 1.00), offset: 5 / 6 }, - { color: ColorPickerUtil.setRgba(255, 0, 0, 1.00), offset: 1 }, + { color: ColorPickerUtil.setRgba(255, 255, 0, 1.00), offset: ColorPickerUtil.SEGMENT_1 }, + { color: ColorPickerUtil.setRgba(0, 255, 0, 1.00), offset: ColorPickerUtil.SEGMENT_2 }, + { color: ColorPickerUtil.setRgba(0, 255, 255, 1.00), offset: ColorPickerUtil.SEGMENT_3 }, + { color: ColorPickerUtil.setRgba(0, 0, 255, 1.00), offset: ColorPickerUtil.SEGMENT_4 }, + { color: ColorPickerUtil.setRgba(255, 0, 255, 1.00), offset: ColorPickerUtil.SEGMENT_5 }, + { color: ColorPickerUtil.setRgba(255, 0, 0, 1.00), offset: ColorPickerUtil.SEGMENT_6 }, ])) .sliderInteractionMode(SliderInteraction.SLIDE_AND_CLICK_UP) .trackThickness($r('app.float.slider_track_thick_large')) diff --git a/features/componentlibrary/src/main/ets/component/ComponentItem.ets b/features/componentlibrary/src/main/ets/component/ComponentItem.ets index a53cbb0915a399c4831c815860a0a4b6f23a9437..1f52d58a6488b7e8a50f72aba1386fd142a5c796 100644 --- a/features/componentlibrary/src/main/ets/component/ComponentItem.ets +++ b/features/componentlibrary/src/main/ets/component/ComponentItem.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BreakpointTypeEnum, CommonConstants, GlobalInfoModel } from '@ohos/common'; +import { BreakpointTypeEnum, CommonConstants, GlobalInfoModel, StorageKey } from '@ohos/common'; import type { ComponentContent } from '../model/ComponentData'; @Component @@ -21,7 +21,7 @@ export struct ComponentItem { @Prop componentContent: ComponentContent; @Prop showDivider: boolean; @Prop buttonColor: ResourceColor = $r('sys.color.interactive_active'); - private globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + private globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; build() { Column() { diff --git a/features/componentlibrary/src/main/ets/component/DetailContentView.ets b/features/componentlibrary/src/main/ets/component/DetailContentView.ets index 098066ffd77b97df3e3526e449f5b3c4dfd165a2..ff6bf5b8d0e39cd8523e3d4def231bb4414ae8aa 100644 --- a/features/componentlibrary/src/main/ets/component/DetailContentView.ets +++ b/features/componentlibrary/src/main/ets/component/DetailContentView.ets @@ -14,14 +14,8 @@ */ import { curves } from '@kit.ArkUI'; -import type { GlobalInfoModel } from '@ohos/common'; -import { - BreakpointType, - BreakpointTypeEnum, - CommonConstants, - WebNodeController, - WebUtil, -} from '@ohos/common'; +import { GlobalInfoModel, Logger, StorageKey, WebNodeController } from '@ohos/common'; +import { BreakpointType, BreakpointTypeEnum, CommonConstants, WebUtil, } from '@ohos/common'; import { CodePreviewComponent } from './CodePreviewComponent'; import type { ConfigInterface } from '../componentdetailview/ComponentDetailConfig'; import { ComponentDetailPageVM, TopNavigationChangeEvent } from '../viewmodel/ComponentDetailPageVM'; @@ -34,24 +28,25 @@ import { DetailPageConstant } from '../constant/DetailPageConstant'; import { CodePreviewJSUtil } from '../util/CodePreviewJSUtil'; const PREVIEW_HEIGHT_SM: number = DetailPageConstant.PREVIEW_HEIGHT_SM; +const TAG: string = '[DetailContentView]'; @Component export struct DetailContentView { @ObjectLink componentDetailState: ComponentDetailState; @Prop componentName: string; - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; @State isShowCodePreview: boolean = false; @State scaleValue: number = 1; @State showDivider: boolean = false; @State isShowTopDivider: boolean = false; - @State webNodeController?: WebNodeController = new WebNodeController(); + @State webNodeController?: WebNodeController = undefined; scroller: Scroller = new Scroller(); private viewModel?: ComponentDetailPageVM = ComponentDetailManager.getInstance().getDetailViewModel(this.componentName); private paddingToTop: number = 0; private paddingToBottom: number = 36; - private detailConfig: Record = AppStorage.get('componentDetailConfig')! + private detailConfig: Record = AppStorage.get(StorageKey.COMPONENT_CONFIG)! @Builder textTip(text: ResourceStr) { @@ -60,7 +55,7 @@ export struct DetailContentView { .fontColor($r('sys.color.font_secondary')) .fontWeight(FontWeight.Regular) .margin({ - top: $r('sys.float.padding_level10'), + top: $r('app.float.comp_detail_area_title_top'), bottom: $r('sys.float.padding_level4'), }) } @@ -76,19 +71,23 @@ export struct DetailContentView { } aboutToDisappear(): void { - const webController = WebUtil.getWebController(WebUtil.getComponentCodeUrl()); - webController?.scrollTo(0, 0); + try { + const webController = WebUtil.getWebController(WebUtil.getComponentCodeUrl()); + webController?.scrollTo(0, 0); + } catch { + Logger.error(TAG, `WebController scroll to zero failed.`); + } } jumpCodePreviewView() { const code = this.componentDetailState.code; const viewModel: ComponentDetailPageVM | undefined = ComponentDetailManager.getInstance().getDetailViewModel(this.componentName); - this.webNodeController?.remove(); + WebUtil.downPage(WebUtil.getComponentCodeUrl()); this.webNodeController = undefined; const toFullScreenMethod: string = 'toFullScreen()'; CodePreviewJSUtil.codeViewRunJS(toFullScreenMethod); - animateTo({ curve: curves.interpolatingSpring(0, 1, 195, 23) }, () => { + this.getUIContext().animateTo({ curve: curves.interpolatingSpring(0, 1, 195, 23) }, () => { viewModel?.jumpToCodePreview(code, () => { this.backFromCodePreview(); }); @@ -117,9 +116,6 @@ export struct DetailContentView { descriptor: this.componentDetailState.descriptor, }) } - .margin({ - top: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM ? 0 : $r('sys.float.padding_level4'), - }) .backgroundColor($r('sys.color.comp_background_primary')) .justifyContent(FlexAlign.Center) .width('100%') @@ -133,8 +129,7 @@ export struct DetailContentView { .borderRadius($r('sys.float.corner_radius_level8')) } .padding({ - top: CommonConstants.NAVIGATION_HEIGHT + this.globalInfoModel.statusBarHeight + DetailPageConstant.SPACE_NORMAL, - bottom: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM ? $r('sys.float.padding_level6') : 0, + top: CommonConstants.NAVIGATION_HEIGHT + this.globalInfoModel.statusBarHeight, left: new BreakpointType({ sm: $r('sys.float.padding_level8'), md: $r('sys.float.padding_level12'), @@ -154,7 +149,7 @@ export struct DetailContentView { .width('100%') } Scroll(this.scroller) { - Column({ space: DetailPageConstant.SPACE_NORMAL }) { + Column() { if (this.componentDetailState.attributes.length !== 0) { this.textTip($r('app.string.changeAttributes')) AttributeChangeArea({ @@ -177,10 +172,6 @@ export struct DetailContentView { .geometryTransition(CommonConstants.CODE_PREVIEW_GEOMETRY_ID, { follow: true }) .borderRadius($r('sys.float.corner_radius_level8')) .clip(true) - .margin({ - top: (this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM || - this.componentDetailState.attributes.length !== 0) ? 0 : $r('sys.float.padding_level4'), - }) .onClick(() => { this.jumpCodePreviewView(); }) @@ -203,10 +194,6 @@ export struct DetailContentView { .borderRadius($r('sys.float.corner_radius_level8')) } } - .margin({ - top: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM ? 0 : - $r('sys.float.padding_level4'), - }) .alignItems(HorizontalAlign.Start) .padding({ top: new BreakpointType({ diff --git a/features/componentlibrary/src/main/ets/component/ListCard.ets b/features/componentlibrary/src/main/ets/component/ListCard.ets index 700c16701dd4308409ab26b9ba2c085357f6ca3c..9479b14473795d6374dd9896195bdb4254564161 100644 --- a/features/componentlibrary/src/main/ets/component/ListCard.ets +++ b/features/componentlibrary/src/main/ets/component/ListCard.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, CommonConstants } from '@ohos/common'; import type { ComponentCardData, ComponentContent } from '../model/ComponentData'; import { ComponentItem } from './ComponentItem'; @@ -21,7 +21,7 @@ import { ComponentItem } from './ComponentItem'; @Reusable @Component export struct ListCard { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @State componentCardData?: ComponentCardData = undefined; handleItemClick?: (componentContent: ComponentContent) => void; diff --git a/features/componentlibrary/src/main/ets/component/RecommendListItem.ets b/features/componentlibrary/src/main/ets/component/RecommendListItem.ets index 2ef1c0d3007c3d74cd02ea5ae03e39311847d26d..f43b2cc9b0d36e4fa2aeb33f0635416459962af2 100644 --- a/features/componentlibrary/src/main/ets/component/RecommendListItem.ets +++ b/features/componentlibrary/src/main/ets/component/RecommendListItem.ets @@ -20,13 +20,14 @@ import { GlobalInfoModel, BreakpointTypeEnum, CommonConstants, + StorageKey, } from '@ohos/common'; import { DetailPageConstant } from '../constant/DetailPageConstant'; import type { RecommendData } from '../model/ComponentDetailData'; @Component export struct RecommendListItem { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop itemData: RecommendData; @State showSheet: boolean = false; diff --git a/features/componentlibrary/src/main/ets/component/SelectComponent.ets b/features/componentlibrary/src/main/ets/component/SelectComponent.ets index dbcece3fe35784e8df42117f279a3f9706b0b730..c3c933de89f961af1195f22a3ebd6c7571bd67ff 100644 --- a/features/componentlibrary/src/main/ets/component/SelectComponent.ets +++ b/features/componentlibrary/src/main/ets/component/SelectComponent.ets @@ -46,8 +46,8 @@ export struct SelectComponent { .selected(this.currentIndex) .value(this.attribute.currentValue) .font({ size: $r('sys.float.Body_M'), weight: FontWeight.Regular }) - .fontColor($r('sys.color.font_secondary')) - .optionFont({ size: $r('sys.float.Subtitle_M'), weight: FontWeight.Medium }) + .fontColor($r('sys.color.font_primary')) + .optionFont({ size: $r('sys.float.Body_L'), weight: FontWeight.Medium }) .optionFontColor($r('sys.color.font_primary')) .optionWidth($r('app.float.detail_common_component_option_width')) .menuAlign(MenuAlignType.END, { dx: 0, dy: 0 } as Offset) diff --git a/features/componentlibrary/src/main/ets/component/SliderComponent.ets b/features/componentlibrary/src/main/ets/component/SliderComponent.ets index 30fe24ac26b1adf1a876dad79c6826edc163113d..110bc0d723cb12fe7cbcf2c53e2731078c7ff503 100644 --- a/features/componentlibrary/src/main/ets/component/SliderComponent.ets +++ b/features/componentlibrary/src/main/ets/component/SliderComponent.ets @@ -63,7 +63,7 @@ export struct SliderComponent { width: $r('app.float.common_component_block_size'), height: $r('app.float.common_component_block_size'), }) - .selectedColor($r('sys.color.icon_emphasize')) + .selectedColor($r('sys.color.comp_background_emphasize')) .trackThickness($r('app.float.common_component_track_thickness')) .padding({ left: $r('sys.float.padding_level4'), right: $r('sys.float.padding_level4') }) .width('100%') diff --git a/features/componentlibrary/src/main/ets/componentdetailview/ComponentDetailConfig.ets b/features/componentlibrary/src/main/ets/componentdetailview/ComponentDetailConfig.ets index 4013a3433cd98d812db408d48544dcd72680b22f..23581595d8c0e16f1e954b615bd8a5857b66e8c4 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/ComponentDetailConfig.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/ComponentDetailConfig.ets @@ -120,6 +120,7 @@ import { ToggleAttributeFilter } from './toggleview/viewmodel/ToggleAttributeFil import { ColumnAttributeFilter } from './columnview/viewmodel/ColumnAttributeFilter' import { RowAttributeFilter } from './rowview/viewmodel/RowAttributeFilter' import { CameraPickerDescriptor } from './picker/camerapicker/viewmodel/CameraPickerDescriptor' +import { ImageAttributeFilter } from './Image/viewmodel/ImageAttributeFilter' export const componentDetailConfig: Record = { 'Button': { @@ -180,7 +181,8 @@ export const componentDetailConfig: Record = { 'Image': { previewComponentBuilder: wrapBuilder(ImageBuilder), descriptor: () => new ImageDescriptor(), - codeGenerate: new ImageCodeGenerator() + codeGenerate: new ImageCodeGenerator(), + attributeFilter: new ImageAttributeFilter(), }, 'Rating': { previewComponentBuilder: wrapBuilder(RatingBuilder), diff --git a/features/componentlibrary/src/main/ets/componentdetailview/Image/viewmodel/ImageAttributeFilter.ets b/features/componentlibrary/src/main/ets/componentdetailview/Image/viewmodel/ImageAttributeFilter.ets new file mode 100644 index 0000000000000000000000000000000000000000..676abfff564a2060dd44b4563c1b38adfc412dde --- /dev/null +++ b/features/componentlibrary/src/main/ets/componentdetailview/Image/viewmodel/ImageAttributeFilter.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ObservedArray } from '@ohos/common'; +import type { Attribute } from '../../../viewmodel/Attribute'; +import { CommonAttributeFilter } from '../../../viewmodel/CommonAttributeFilter'; + +export class ImageAttributeFilter implements CommonAttributeFilter { + public filter(attributes: ObservedArray): void { + attributes.forEach((attribute) => { + switch (attribute.name) { + case 'objectFit': + const clipAttribute = attributes.findIndex((item) => item.name === 'clip'); + const objectFitAttrs = ['ScaleDown', 'None', 'Contain'] + if (clipAttribute !== -1) { + if (objectFitAttrs.includes(attribute.currentValue)) { + attributes[clipAttribute].enable = false; + } else { + attributes[clipAttribute].enable = true; + } + } + break; + default: + break; + } + }); + } +} \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/component/ActionSheetBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/component/ActionSheetBuilder.ets index a07b59842d1197f2a5f2d82b01d67089b942c1e0..0d5e9af9d360c479a8ab82e3f89851c326771c68 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/component/ActionSheetBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/component/ActionSheetBuilder.ets @@ -13,15 +13,12 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; + +import { StorageKey, Toast } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { ActionSheetDescriptor } from '../viewmodel/ActionSheetDescriptor'; -const TAG: string = '[ActionSheetBuilder]'; - @Builder export function ActionSheetBuilder($$: DescriptorWrapper) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -30,7 +27,8 @@ export function ActionSheetBuilder($$: DescriptorWrapper) { .fontSize($r('sys.float.Body_L')) .fontColor($r('sys.color.font_emphasize')) .onClick(() => { - ActionSheet.show({ + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + uiContext.showActionSheet({ title: $r('app.string.title'), subtitle: $r('app.string.subtitle'), message: $r('app.string.content'), @@ -43,15 +41,7 @@ export function ActionSheetBuilder($$: DescriptorWrapper) { defaultFocus: true, value: $r('app.string.dialog_confirm'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.confirm_click'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.confirm_click')); }, }, alignment: DialogAlignment.Center, diff --git a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/entity/ActionSheetAttributeMapping.ets b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/entity/ActionSheetAttributeMapping.ets index 4a744f07e75b39731b33af6000ca9aef87795f66..046e14e7975ec11838231f3749368a747d3b3765 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/entity/ActionSheetAttributeMapping.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/entity/ActionSheetAttributeMapping.ets @@ -13,14 +13,10 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; +import { Toast } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import { CommonBoolMapping } from '../../common/entity/CommonMapData'; -const TAG: string = '[ActionSheetBuilder]'; - class ActionSheetInfoMapping { public code: string; public value: SheetInfo[]; @@ -43,43 +39,19 @@ const sheetOne: SheetInfo[] = [ { title: $r('app.string.item1'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'item1'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'item1')); }, }, { title: $r('app.string.item2'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'item2'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'item2')); }, }, { title: $r('app.string.item3'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'item3'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'item3')); }, }, ]; @@ -131,43 +103,19 @@ const sheetTwo: SheetInfo[] = [ { title: $r('app.string.apples'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'apples'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'apples')); }, }, { title: $r('app.string.bananas'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'bananas'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'bananas')); }, }, { title: $r('app.string.pears'), action: () => { - try { - promptAction.showToast({ - message: $r('app.string.item_click', 'pears'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.item_click', 'pears')); }, }, ]; diff --git a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/viewmodel/ActionSheetCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/viewmodel/ActionSheetCodeGenerator.ets index 51c40b6c8961c8f30c3c1aff3f4bdc3cd1010187..ec682366f169461d28ef0fb123f12a4ceb4f45e0 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/viewmodel/ActionSheetCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/actionsheetview/viewmodel/ActionSheetCodeGenerator.ets @@ -54,6 +54,7 @@ export class ActionSheetCodeGenerator implements CommonCodeGenerator { } }); return `import { promptAction } from '@kit.ArkUI'; +import type { BusinessError } from '@kit.BasicServicesKit'; @Component struct ActionSheetComponent { diff --git a/features/componentlibrary/src/main/ets/componentdetailview/aicaption/component/AICaptionBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/aicaption/component/AICaptionBuilder.ets index 415c8ed05460f195864cd32d7885e45018bb6000..cda385a3d19fa2b6bef84207dbef8a2611878bff 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/aicaption/component/AICaptionBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/aicaption/component/AICaptionBuilder.ets @@ -15,7 +15,7 @@ import { AICaptionComponent, AICaptionController, AICaptionOptions, AudioData } from '@kit.SpeechKit'; import type { BusinessError } from '@kit.BasicServicesKit'; -import { BreakpointType, GlobalInfoModel, Logger } from '@ohos/common'; +import { BreakpointType, BreakpointTypeEnum, GlobalInfoModel, Logger, StorageKey } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; @@ -28,7 +28,7 @@ export function AICaptionBuilder(_$$: DescriptorWrapper) { @Component struct CaptionComponent { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @State isShown: boolean = true; isReading: boolean = false; componentWidth: number = 0; @@ -52,7 +52,7 @@ struct CaptionComponent { let fileData: Uint8Array; this.isReading = true; try { - fileData = await getContext(this).resourceManager.getMediaContent($r('app.media.16k')); + fileData = await this.getUIContext().getHostContext()!.resourceManager.getMediaContent($r('app.media.16k').id); } catch (err) { const error: BusinessError = err as BusinessError; Logger.error(TAG, `GetMediaContent error, the code is ${error.code}}, the message is ${error.message}`); @@ -76,7 +76,11 @@ struct CaptionComponent { data: data, }; if (this.controller) { - this.controller.writeAudio(audioData); + try { + this.controller.writeAudio(audioData); + } catch { + Logger.error(TAG, `writeAudio Failed`); + } } offset = offset + bufferSize; const waitTime = bufferSize / 32; @@ -105,7 +109,8 @@ struct CaptionComponent { lg: $r('app.float.ai_caption_width'), xl: $r('app.float.ai_caption_width_xl'), }).getValue(this.globalInfoModel.currentBreakpoint)) - .height($r('app.float.ai_caption_height')) + .height(this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? + $r('app.float.ai_caption_height_xl') : $r('app.float.ai_caption_height')) .margin({ left: new BreakpointType({ xs: DetailPageConstant.MARGIN_NEGATIVE_LARGER, diff --git a/features/componentlibrary/src/main/ets/componentdetailview/aicaption/viewmodel/AICaptionCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/aicaption/viewmodel/AICaptionCodeGenerator.ets index a43543a3996bb5910027869176e9602bc1976fc9..a6ce18ff1f6638588699aef229409be1ff5cd8df 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/aicaption/viewmodel/AICaptionCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/aicaption/viewmodel/AICaptionCodeGenerator.ets @@ -45,18 +45,17 @@ struct CaptionComponent { let fileData: Uint8Array; this.isReading = true; try { - fileData = await getContext(this).resourceManager.getMediaContent($r('app.media.16k')); + // Here you need a voice file in PCM format, one that can clearly convey the text. + fileData = await this.getUIContext().getHostContext()!.resourceManager.getMediaContent($r('app.media.16k').id); } catch (err) { const error: BusinessError = err as BusinessError; console.error(\`GetMediaContent error, the code is \${error.code}, the message is \${error.message}\`); this.isReading = false; return; } - // Here you need a voice file in PCM format, one that can clearly convey the text. const bufferSize = 640; const byteLength = fileData.byteLength; let offset = 0; - const startTime = new Date().getTime(); while (offset < byteLength) { let nextOffset = offset + bufferSize if (offset > byteLength) { @@ -76,7 +75,6 @@ struct CaptionComponent { const waitTime = bufferSize / 32; await this.sleep(waitTime); } - const endTime = new Date().getTime(); this.isReading = false; } diff --git a/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/component/AlertDialogBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/component/AlertDialogBuilder.ets index d3f8c5b44235d7618e330ae9052ae302ae25cb8d..088aab8fe3dd70c18ecfb2eea8ee9be2e29353f1 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/component/AlertDialogBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/component/AlertDialogBuilder.ets @@ -13,9 +13,7 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; +import { Logger, StorageKey, Toast } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { AlertDialogDescriptor } from '../viewmodel/AlertDialogDescriptor'; @@ -31,7 +29,8 @@ export function AlertDialogBuilder($$: DescriptorWrapper) { .fontSize($r('sys.float.Body_L')) .fontColor($r('sys.color.font_emphasize')) .onClick(() => { - AlertDialog.show( + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + uiContext.showAlertDialog( { title: $r('app.string.title'), subtitle: $r('app.string.subtitle'), @@ -43,29 +42,13 @@ export function AlertDialogBuilder($$: DescriptorWrapper) { { value: $r('app.string.button_one'), action: () => { - try { - promptAction.showToast({ - message: 'Callback when button1 is clicked', - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast('Callback when button1 is clicked'); }, }, { value: $r('app.string.button_two'), action: () => { - try { - promptAction.showToast({ - message: 'Callback when button2 is clicked', - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast('Callback when button2 is clicked'); }, } ], diff --git a/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/viewmodel/AlertDialogCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/viewmodel/AlertDialogCodeGenerator.ets index ca01f2e24cb9b849d2d3e688435ac600fd87757b..a80ccab21a3d9aa6878c86f500d6fd7bd41ce109 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/viewmodel/AlertDialogCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/alertdialogview/viewmodel/AlertDialogCodeGenerator.ets @@ -31,7 +31,8 @@ export class AlertDialogCodeGenerator implements CommonCodeGenerator { break; } }); - return `import { promptAction } from '@kit.ArkUI'; + return `// AlertDialog.ets +import type { BusinessError } from '@kit.BasicServicesKit'; @Component struct AlertDialogComponent { @@ -43,7 +44,8 @@ struct AlertDialogComponent { .fontSize($r('sys.float.Body_L')) .fontColor($r('sys.color.font_emphasize')) .onClick(() => { - AlertDialog.show( + const uiContext: UIContext = this.getUIContext(); + uiContext.showAlertDialog( { title: '标题', subtitle: '副标题', @@ -57,7 +59,7 @@ struct AlertDialogComponent { value: '按钮1', action: () => { try { - promptAction.showToast({ + uiContext.getPromptAction().showToast({ message: 'Callback when button1 is clicked', duration: 2000 }); @@ -71,7 +73,7 @@ struct AlertDialogComponent { value: '按钮2', action: () => { try { - promptAction.showToast({ + uiContext.getPromptAction().showToast({ message: 'Callback when button2 is clicked', duration: 2000 }); diff --git a/features/componentlibrary/src/main/ets/componentdetailview/applinking/component/AppLinkingBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/applinking/component/AppLinkingBuilder.ets index 3bb8a851ddea119594960cbb9bc16ff16251d4c1..4c9331d11091a3e6ebb2c8ed833fa767756b8fe7 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/applinking/component/AppLinkingBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/applinking/component/AppLinkingBuilder.ets @@ -16,7 +16,7 @@ import type { common, Want } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; import { call } from '@kit.TelephonyKit'; -import { ConfigMapKey, Logger, ResourceUtil } from '@ohos/common'; +import { ConfigMapKey, Logger, ProcessUtil, ResourceUtil } from '@ohos/common'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { AppLinkingDescriptor } from '../viewmodel/AppLinkingDescriptor'; import { LinkType, typeResourcesMapData, wantParam } from '../entity/AppLinkingAttributeMapping'; @@ -32,6 +32,8 @@ export function AppLinkingBuilder($$: DescriptorWrapper) { struct AppLinkingComponent { @Prop appLinkingDescriptor: AppLinkingDescriptor; private galleryUrl: string = ''; + private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; + private uiContext: UIContext = this.getUIContext(); build() { Column() { @@ -59,12 +61,11 @@ struct AppLinkingComponent { } jumpToGallery(): void { - const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; if (!this.galleryUrl) { - this.galleryUrl = ResourceUtil.getRawFileStringByKey(context, ConfigMapKey.GALLERY_URL); + this.galleryUrl = ResourceUtil.getRawFileStringByKey(this.context, ConfigMapKey.GALLERY_URL); } try { - context.openLink(this.galleryUrl, { appLinkingOnly: false }) + this.context.openLink(this.galleryUrl, { appLinkingOnly: false }) .then(() => { Logger.info(TAG, 'OpenLink success.'); }) @@ -78,7 +79,6 @@ struct AppLinkingComponent { } jumpToMap(): void { - const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; const abilityStartCallback: common.AbilityStartCallback = { onError: (code: number, name: string, message: string) => { Logger.error(TAG, `Fail start ability, name is ${name}, code is ${code}, message is ${message}`); @@ -88,7 +88,7 @@ struct AppLinkingComponent { } } try { - context.startAbilityByType('navigation', wantParam, abilityStartCallback); + this.context.startAbilityByType('navigation', wantParam, abilityStartCallback); } catch (err) { const error: BusinessError = err as BusinessError; Logger.error(TAG, `StartAbilityByType error, the code is ${error.code}, the message is ${error.message}`); @@ -96,18 +96,12 @@ struct AppLinkingComponent { } jumpToSettings(): void { - const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; const want: Want = { bundleName: 'com.huawei.hmos.settings', abilityName: 'com.huawei.hmos.settings.MainAbility', uri: '', }; - try { - context.startAbility(want); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `StartAbility error, the code is ${error.code}, the message is ${error.message}`); - } + ProcessUtil.startAbility(this.context, want); } jumpToDial(): void { @@ -122,18 +116,19 @@ struct AppLinkingComponent { Logger.info(TAG, `MakeCall success`); } }); + return; } - } else { - AlertDialog.show({ - title: '', - message: $r('app.string.not_support_dial'), - primaryButton: { - value: $r('app.string.sure'), - action: () => { - Logger.info(TAG, 'The device does not support dial-up.'); - } - } - }); } + this.uiContext.showAlertDialog({ + title: '', + message: $r('app.string.not_support_dial'), + primaryButton: { + value: $r('app.string.sure'), + action: () => { + Logger.info(TAG, 'The device does not support dial-up.'); + } + } + }); + } } \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/componentdetailview/applinking/viewmodel/AppLinkingCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/applinking/viewmodel/AppLinkingCodeGenerator.ets index 72a1acff26aa8447b3af44104d11fb054faf7379..f4e482a7f3fb53103abae66f593ec1a1c74a7a4c 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/applinking/viewmodel/AppLinkingCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/applinking/viewmodel/AppLinkingCodeGenerator.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ConfigMapKey, ResourceUtil } from '@ohos/common'; +import { ConfigMapKey, ResourceUtil, StorageKey } from '@ohos/common'; import type { OriginAttribute } from '../../../viewmodel/Attribute'; import { CommonCodeGenerator } from '../../../viewmodel/CommonCodeGenerator'; import { @@ -38,7 +38,9 @@ export class AppLinkingCodeGenerator implements CommonCodeGenerator { }); let codeStr: string = typeInvokeCodeMapData.get(this.type)!; if (this.type === LinkType.TYPE_GALLERY) { - const linkUrl: string = ResourceUtil.getRawFileStringByKey(getContext(), ConfigMapKey.GALLERY_URL); + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: Context = uiContext.getHostContext() as Context; + const linkUrl: string = ResourceUtil.getRawFileStringByKey(context, ConfigMapKey.GALLERY_URL); codeStr = codeStr.replace('%s', linkUrl); } return `${typeImportCodeMapData.get(this.type)!} diff --git a/features/componentlibrary/src/main/ets/componentdetailview/buttonview/component/ButtonBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/buttonview/component/ButtonBuilder.ets index 2943cbc314d6f932ff3c8c48d4607398afd98332..8c873cb8c1f88664a0e834506ae314acc5a5de95 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/buttonview/component/ButtonBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/buttonview/component/ButtonBuilder.ets @@ -13,10 +13,7 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; -import { DetailPageConstant } from '../../../constant/DetailPageConstant'; +import { Toast } from '@ohos/common'; import { ButtonAttributeModifier } from '../viewmodel/ButtonAttributeModifier'; import type { ButtonDescriptor } from '../viewmodel/ButtonDescriptor'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; @@ -28,30 +25,14 @@ export function ButtonBuilder($$: DescriptorWrapper) { Button($r('app.string.button_text')) .onClick(() => { if (($$.descriptor as ButtonDescriptor).operation === 'Click') { - try { - promptAction.showToast({ - message: $r('app.string.btn_click'), - duration: DetailPageConstant.LONG_DURATION, - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.btn_click')); } }) .gesture( LongPressGesture({ repeat: true }) .onActionEnd((_event: GestureEvent) => { if (($$.descriptor as ButtonDescriptor).operation === 'LongGesture') { - try { - promptAction.showToast({ - message: $r('app.string.button_text2'), - duration: DetailPageConstant.LONG_DURATION - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showLongToast($r('app.string.button_text2')); } }) ) diff --git a/features/componentlibrary/src/main/ets/componentdetailview/buttonview/viewmodel/ButtonCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/buttonview/viewmodel/ButtonCodeGenerator.ets index 381de8e49ad23ab619401876f6a0b1896fccea8d..f783a0d67122c2affe6eb5c242cca2cd18111e51 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/buttonview/viewmodel/ButtonCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/buttonview/viewmodel/ButtonCodeGenerator.ets @@ -65,8 +65,9 @@ export class ButtonCodeGenerator implements CommonCodeGenerator { operationCode = `.gesture( LongPressGesture({ repeat: true }) .onActionEnd((event: GestureEvent) => { + const uiContext: UIContext = this.getUIContext(); try { - promptAction.showToast({ + uiContext.getPromptAction().showToast({ message: '按钮被长按', duration: 2000 }); @@ -78,8 +79,9 @@ export class ButtonCodeGenerator implements CommonCodeGenerator { )`; } else if (this.operation === 'Click') { operationCode = `.onClick(() => { + const uiContext: UIContext = this.getUIContext(); try { - promptAction.showToast({ + uiContext.getPromptAction().showToast({ message: '按钮被点击', duration: 2000 }); @@ -91,7 +93,8 @@ export class ButtonCodeGenerator implements CommonCodeGenerator { } else { operationCode = ``; } - return `import { promptAction } from '@kit.ArkUI'; + return `// Button.ets +import type { BusinessError } from '@kit.BasicServicesKit'; @Component struct ButtonComponent { diff --git a/features/componentlibrary/src/main/ets/componentdetailview/documentviewpicker/component/DocumentViewPickerBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/documentviewpicker/component/DocumentViewPickerBuilder.ets index 290ac181cb13dde26566627c2d6e8e777ab6faf5..91487c30cbc22dce405fdad2ce82149b8fe2d69c 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/documentviewpicker/component/DocumentViewPickerBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/documentviewpicker/component/DocumentViewPickerBuilder.ets @@ -31,18 +31,19 @@ export function DocumentViewPickerBuilder(_$$: DescriptorWrapper) { struct DocumentViewPickerComponent { @State message: string = ''; @State title: string = ''; + private uiContext: UIContext = this.getUIContext(); + private context: Context = this.getUIContext().getHostContext() as common.Context; readFile() { - const context = getContext(this) as common.Context; try { const documentSelectOptions = new picker.DocumentSelectOptions(); - const documentPicker = new picker.DocumentViewPicker(context); + const documentPicker = new picker.DocumentViewPicker(this.context); documentPicker.select(documentSelectOptions).then((documentSelectResult: string[]) => { if (documentSelectResult.length === 0) { return; } this.message = JSON.stringify(documentSelectResult); - this.getUIContext().showAlertDialog( + this.uiContext.showAlertDialog( { title: $r('app.string.File_path'), message: this.message, diff --git a/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/component/AIImageComponent.ets b/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/component/AIImageComponent.ets index 56273c46680c4e74f0d559b018bbb9b5fc5784b6..7ec877d8242f1a1c43e2f7b2ed8d07341bd5c9f4 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/component/AIImageComponent.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/component/AIImageComponent.ets @@ -16,7 +16,7 @@ import { Popup } from '@kit.ArkUI'; import { image } from '@kit.ImageKit'; import { BusinessError } from '@kit.BasicServicesKit'; -import { BreakpointTypeEnum, GlobalInfoModel, Logger, PreferenceManager } from '@ohos/common'; +import { BreakpointTypeEnum, GlobalInfoModel, Logger, PreferenceManager, StorageKey } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import { CommonStorageKey } from '../../common/entity/CommonStorageKey'; @@ -24,7 +24,7 @@ const TAG: string = '[AIImageComponent]'; @Component export struct AIImageComponent { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @State imagePixelMap?: image.PixelMap = undefined; @State showPopup: boolean = true; @State imageWidth: number = 0; @@ -117,11 +117,7 @@ export struct AIImageComponent { private async getPixmapFromMedia(resource: Resource) { let createPixelMap: image.PixelMap; try { - const unit8Array = await getContext(this)?.resourceManager?.getMediaContent({ - bundleName: resource.bundleName, - moduleName: resource.moduleName, - id: resource.id, - }); + const unit8Array = await this.getUIContext().getHostContext()!.resourceManager?.getMediaContent(resource.id); const imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)); createPixelMap = await imageSource.createPixelMap({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888, diff --git a/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/viewmodel/AIImageCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/viewmodel/AIImageCodeGenerator.ets index b95dfeb94dc966030d8ef3f5e4026bf496c809fa..34c7415817d4a96309197d03311b2d11eced2ea5 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/viewmodel/AIImageCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/imageaianalyzer/viewmodel/AIImageCodeGenerator.ets @@ -19,6 +19,7 @@ import { CommonCodeGenerator } from '../../../viewmodel/CommonCodeGenerator'; export class AIImageCodeGenerator implements CommonCodeGenerator { public generate(_attributes: OriginAttribute[]): string { return `import { image } from '@kit.ImageKit'; +import type { BusinessError } from '@kit.BasicServicesKit'; @Component export struct AIImageComponent { @@ -56,11 +57,7 @@ export struct AIImageComponent { private async getPixmapFromMedia(resource: Resource) { let createPixelMap: image.PixelMap; try { - const unit8Array = await getContext(this)?.resourceManager?.getMediaContent({ - bundleName: resource.bundleName, - moduleName: resource.moduleName, - id: resource.id, - }); + const unit8Array = await this.getUIContext().getHostContext()!.resourceManager?.getMediaContent(resource.id); const imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)); createPixelMap = await imageSource.createPixelMap({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888, diff --git a/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/HandWritingComponent.ets b/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/HandWritingComponent.ets index 6f4b4b8ed2f54cee3f540fd91359d977db32c4db..15810bce1dc142f9067c185d5cf078288001efe2 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/HandWritingComponent.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/HandWritingComponent.ets @@ -15,7 +15,7 @@ import { HandwriteComponent, HandwriteController } from '@kit.Penkit'; import { BusinessError } from '@kit.BasicServicesKit'; -import { BreakpointTypeEnum, GlobalInfoModel, Logger } from '@ohos/common'; +import { BreakpointTypeEnum, GlobalInfoModel, Logger, StorageKey } from '@ohos/common'; import { ComponentDetailManager } from '../../../viewmodel/ComponentDetailManager'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; @@ -24,7 +24,7 @@ const BUTTON_OFFSET: number = 16; @Component export struct HandWritingComponent { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; private controller: HandwriteController = new HandwriteController(); private initPath: string = 'savePath'; private closeButtonTop: number = BUTTON_OFFSET; @@ -72,7 +72,10 @@ export struct HandWritingComponent { .width($r('sys.float.ohos_id_button_height')) .height($r('sys.float.ohos_id_button_height')) .backgroundColor($r('sys.color.comp_background_tertiary')) - .margin({ top: this.closeButtonTop + this.globalInfoModel.statusBarHeight, right: $r('sys.float.padding_level8') }) + .margin({ + top: this.closeButtonTop + this.globalInfoModel.statusBarHeight, + right: $r('sys.float.padding_level8') + }) .onClick(() => { ComponentDetailManager.getInstance().getDetailViewModel('Penkit')?.pop(); }) diff --git a/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/PenKitBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/PenKitBuilder.ets index 70c5cafcea091a7e0a1f88f6cae9d988fe516235..6c2dd5c74a6ff3a232da5aa4f2e9b16cd9a9bf63 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/PenKitBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/penkit/component/PenKitBuilder.ets @@ -13,14 +13,10 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; +import { Toast } from '@ohos/common'; import { ComponentDetailManager } from '../../../viewmodel/ComponentDetailManager'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; -const TAG: string = '[PenKitBuilder]'; - @Builder export function PenKitBuilder($$: DescriptorWrapper) { Button($r('app.string.penKit'), { buttonStyle: ButtonStyleMode.NORMAL }) @@ -31,12 +27,7 @@ export function PenKitBuilder($$: DescriptorWrapper) { if (canIUse('SystemCapability.Stylus.Handwrite')) { ComponentDetailManager.getInstance().getDetailViewModel('Penkit')?.jumpToPenKitView(); } else { - try { - promptAction.showToast({ message: $r('app.string.function_handwrite_not_support') }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showToast($r('app.string.function_handwrite_not_support')); } }) } \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/componentdetailview/penkit/viewmodel/PenKitCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/penkit/viewmodel/PenKitCodeGenerator.ets index c49c446503446932d7c0b1c52ff2fe9aa4f2e129..ec2596f9fb28c50d54ba5f5be21d6b5ba04e3ee7 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/penkit/viewmodel/PenKitCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/penkit/viewmodel/PenKitCodeGenerator.ets @@ -48,6 +48,7 @@ export default class EntryAbility extends UIAbility { // Create a HandWritingComponent.ets file in the src/main/ets/ path to be used as a component. import { HandwriteComponent, HandwriteController } from '@kit.Penkit'; +import type { BusinessError } from '@kit.BasicServicesKit'; @Component struct HandWritingComponent { diff --git a/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/component/CameraPickerComponent.ets b/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/component/CameraPickerComponent.ets index 4c2a1185fa49520f94a37dc32dd0a93510c6d20c..b2219d923afbecfdbd3285c3a4380c64d2c29c59 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/component/CameraPickerComponent.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/component/CameraPickerComponent.ets @@ -14,10 +14,9 @@ */ import type { common } from '@kit.AbilityKit'; -import { promptAction } from '@kit.ArkUI'; import type { BusinessError } from '@kit.BasicServicesKit'; import { camera, cameraPicker } from '@kit.CameraKit'; -import { Logger } from '@ohos/common'; +import { Logger, Toast } from '@ohos/common'; import type { CameraPickerDescriptor } from '../viewmodel/CameraPickerDescriptor'; const TAG: string = '[CameraPickerBuilder]'; @@ -31,12 +30,12 @@ export struct CameraPickerComponent { @State isFilled: boolean = false; @State cameraNum: number = 0; private controller: VideoController = new VideoController(); + private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; aboutToAppear() { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; let cameraManager: camera.CameraManager; try { - cameraManager = camera.getCameraManager(context); + cameraManager = camera.getCameraManager(this.context); } catch (err) { const error: BusinessError = err as BusinessError; Logger.error(TAG, `GetCameraManager error, the code is ${error.code}, the message is ${error.message}`); @@ -74,12 +73,8 @@ export struct CameraPickerComponent { .onClick(async () => { // some device did not have any camera. if (this.cameraNum === 0) { - try { - promptAction.showToast({ message: $r('app.string.device_camera') }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } + Toast.showToast($r('app.string.device_camera')); + return; } try { @@ -87,7 +82,8 @@ export struct CameraPickerComponent { cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, }; const pickerResult: cameraPicker.PickerResult = - await cameraPicker.pick(getContext(), this.cameraPickerDescriptor.mediaTypes, pickerProfile); + await cameraPicker.pick(this.context, this.cameraPickerDescriptor.mediaTypes, + pickerProfile); if (pickerResult.resultCode === CODE_SUCC) { this.isFilled = true; this.uri = pickerResult.resultUri; diff --git a/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/viewmodel/CameraPickerCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/viewmodel/CameraPickerCodeGenerator.ets index e2d3174e0d3475e55ab777a094a0c15faacc5dc3..bcd8d408257e60de758f4abea6ebca96b135a4a5 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/viewmodel/CameraPickerCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/picker/camerapicker/viewmodel/CameraPickerCodeGenerator.ets @@ -20,8 +20,8 @@ import { pickerMediaType } from '../entity/CameraPickerMapping'; export class CameraPickerCodeGenerator implements CommonCodeGenerator { private mediaTypes: string = pickerMediaType.get('Default')!.code; - public generate(_attributes: OriginAttribute[]): string { - _attributes.forEach((attribute) => { + public generate(attributes: OriginAttribute[]): string { + attributes.forEach((attribute) => { switch (attribute.name) { case 'mediaTypes': this.mediaTypes = pickerMediaType.get(attribute.currentValue)?.code ?? this.mediaTypes; @@ -30,9 +30,10 @@ export class CameraPickerCodeGenerator implements CommonCodeGenerator { break; } }); - return `import { camera, cameraPicker } from '@kit.CameraKit'; -import { promptAction } from '@kit.ArkUI'; + return `// CameraPicker.ets +import { camera, cameraPicker } from '@kit.CameraKit'; import type { BusinessError } from '@kit.BasicServicesKit'; +import type { common } from '@kit.AbilityKit'; @Component export struct CameraPickerComponent { @@ -43,7 +44,7 @@ export struct CameraPickerComponent { private controller: VideoController = new VideoController(); aboutToAppear() { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; + const context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; let cameraManager: camera.CameraManager; try { cameraManager = camera.getCameraManager(context); @@ -82,9 +83,10 @@ export struct CameraPickerComponent { .fontColor(this.isFilled ? $r('sys.color.font_on_primary') : $r('sys.color.font_emphasize')) .margin({ bottom: $r('sys.float.padding_level10') }) .onClick(async () => { + const uiContext: UIContext = this.getUIContext(); if (this.cameraNum === 0) { try { - promptAction.showToast({ message: '该设备没有摄像头' }); + uiContext.getPromptAction().showToast({ message: '该设备没有摄像头' }); } catch (err) { const error: BusinessError = err as BusinessError; console.error(\`Show toast error, the code is \${error.code}, the message is \${error.message}\`); diff --git a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperAttributeModifier.ets b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperAttributeModifier.ets index 3007e4fe5177c99a9b04329a11d6947166b489cb..d5ba5276bd651b0755098ae34824c7a589465447 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperAttributeModifier.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperAttributeModifier.ets @@ -23,6 +23,6 @@ export class SwiperAttributeModifier extends CommonAttributeModifier descriptor.vertical), (val) => instance.vertical(val)); this.assignAttribute((descriptor => descriptor.effectMode), (val) => instance.effectMode(val)); this.assignAttribute((descriptor => descriptor.displayArrow), (val) => instance.displayArrow(val)); - this.assignAttribute((descriptor => descriptor.loop), (val) => instance.autoPlay(val)); + this.assignAttribute((descriptor => descriptor.autoPlay), (val) => instance.autoPlay(val)); } } \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperCodeGenerator.ets index 6be7f21a066e8e8c11a3bcf15f04c2e15f14bcc9..e70e05a2254a346417404175d2f79e47541d36a3 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperCodeGenerator.ets @@ -21,62 +21,55 @@ export class SwiperCodeGenerator implements CommonCodeGenerator { private isDisplayArrow: boolean = true; private displayArrow: string = ''; private indicatorType: string = 'DotIndicator'; - private indicatorCode: string = indicatorStyleMapData.get('Default')!.code; private isVertical: boolean = true; private effectMode: string = indicatorEffectMapping.get('Default')!.code; - private loop: boolean = true; + private autoPlay: boolean = true; public generate(attributes: OriginAttribute[]): string { - let code = `Swiper() { - ForEach(this.list, (item: string,index: number) => { + // Base template with consistent 4-space indentation. + const baseTemplate = `Swiper() { + ForEach(this.list, (item: string, index: number) => { Text(item.toString()) .width('90%') - .height("80%") + .height('80%') .height(160) .backgroundColor(0xAFEEEE) .textAlign(TextAlign.Center) .fontSize(30) }, (item: string) => item) - } - .loop(${this.loop})\n`; - + }`; + const generatedParts: string[] = [baseTemplate]; attributes.forEach((attribute) => { switch (attribute.name) { case 'indicator': this.indicatorType = attribute.currentValue as string; - this.indicatorCode = ` .indicator(${indicatorStyleMapData.get(this.indicatorType)?.code})`; + generatedParts.push(` .indicator(${indicatorStyleMapData.get(this.indicatorType)?.code})`); break; case 'vertical': this.isVertical = JSON.parse(attribute.currentValue); - code += ` .vertical(${this.isVertical ? 'true' : 'false'})\n`; + generatedParts.push(` .vertical(${this.isVertical ? 'true' : 'false'})`); break; case 'effectMode': this.effectMode = attribute.currentValue as string; - if (this.effectMode === 'Spring') { - code += ` .effectMode(EdgeEffect.Spring)`; - } else if (this.effectMode === 'Fade') { - code += ` .effectMode(EdgeEffect.Fade)`; - } else if (this.effectMode === 'None') { - code += ` .effectMode(EdgeEffect.None)`; - } + generatedParts.push(` .effectMode(EdgeEffect.${this.effectMode})`); break; case 'isDisplayArrow': this.isDisplayArrow = JSON.parse(attribute.currentValue); - if (this.isDisplayArrow) { - this.displayArrow = ` .displayArrow({ - showBackground: true, - isSidebarMiddle: true, - backgroundSize: 24, - backgroundColor: Color.White, - arrowSize: 18, - arrowColor: Color.Blue -})\n`; - } else { - this.displayArrow = ' .displayArrow(false)'; - } + this.displayArrow = this.isDisplayArrow + ? ` .displayArrow({ + showBackground: true, + isSidebarMiddle: true, + backgroundSize: 24, + backgroundColor: Color.White, + arrowSize: 18, + arrowColor: Color.Blue + })` + : ' .displayArrow(false)'; + generatedParts.push(this.displayArrow); break; - case 'loop': - this.loop = JSON.parse(attribute.currentValue); + case 'autoPlay': + this.autoPlay = JSON.parse(attribute.currentValue); + generatedParts.push(` .autoPlay(${this.autoPlay})`); break; default: break; @@ -95,7 +88,7 @@ struct SwiperComponent { @State list: number[] = getSwiperData(); build() { - ${code}\n${this.indicatorCode}\n${this.displayArrow} + ${generatedParts.join('\n')} } }`; } diff --git a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperDescriptor.ets b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperDescriptor.ets index 8e26afe322eee1c4c71bf1193e61601c4a1d3ff1..52c4eb833028ce247123f228befa79727d3da431 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperDescriptor.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/swiperView/viewmodel/SwiperDescriptor.ets @@ -24,7 +24,7 @@ export class SwiperDescriptor extends CommonDescriptor { public effectMode: EdgeEffect = indicatorEffectMapping.get('Default')!.value; public isDisplayArrow: boolean = true; public displayArrow: ArrowStyle | boolean = false; - public loop: boolean = true; + public autoPlay: boolean = true; public convert(attributes: OriginAttribute[]): void { attributes.forEach((attribute) => { @@ -53,8 +53,8 @@ export class SwiperDescriptor extends CommonDescriptor { this.displayArrow = false; } break; - case 'loop': - this.loop = JSON.parse(attribute.currentValue); + case 'autoPlay': + this.autoPlay = JSON.parse(attribute.currentValue); break; default: break; diff --git a/features/componentlibrary/src/main/ets/componentdetailview/textarea/component/TextAreaBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/textarea/component/TextAreaBuilder.ets index 612734940e64757dec3298c1264c39007f827667..4fc6be68666fdd71f20f5356b398087f8976edd0 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/textarea/component/TextAreaBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/textarea/component/TextAreaBuilder.ets @@ -15,7 +15,7 @@ import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; -import { GlobalInfoModel, Logger } from '@ohos/common'; +import { GlobalInfoModel, Logger, StorageKey } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { TextAreaDescriptor } from '../viewmodel/TextAreaDescriptor'; @@ -34,17 +34,19 @@ struct TextAreaComponent { // Height of the component preview area. @State textAreaInputHeight: number = 0; @State contentOffset: number = 0; + private uiContext: UIContext = this.getUIContext(); + private context: Context = this.uiContext.getHostContext() as Context; aboutToAppear(): void { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); - window.getLastWindow(getContext(this)).then(currentWindow => { - // Monitor the appearance and disappearance of the soft keyboard. - try { + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); + try { + window.getLastWindow(this.context).then(currentWindow => { + // Monitor the appearance and disappearance of the soft keyboard. currentWindow.on('avoidAreaChange', async data => { if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) { return; } - const keyboardHeight: number = px2vp(data.area.bottomRect.height); + const keyboardHeight: number = this.uiContext.px2vp(data.area.bottomRect.height); /* When the size of the component preview area exceeds half the screen, the keyboard will cover the preview area. At this time, the component needs to move up when the keyboard appears. */ @@ -54,11 +56,11 @@ struct TextAreaComponent { this.contentOffset = 0; } }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `CurrentWindow invoke error, the code is ${error.message}, the message is ${error.message}`); - } - }); + }); + } catch (err) { + const error: BusinessError = err as BusinessError; + Logger.error(TAG, `CurrentWindow invoke error, the code is ${error.message}, the message is ${error.message}`); + } } build() { diff --git a/features/componentlibrary/src/main/ets/componentdetailview/textinput/component/TextInputBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/textinput/component/TextInputBuilder.ets index 0b63431dd3b5590f3aaa3c9ba114bb4d23f844eb..f76f97a4b768cd4886ae8e9fd110108bf14f0c02 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/textinput/component/TextInputBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/textinput/component/TextInputBuilder.ets @@ -15,7 +15,7 @@ import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; -import { GlobalInfoModel, Logger } from '@ohos/common'; +import { GlobalInfoModel, Logger, StorageKey } from '@ohos/common'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; import { ComponentDetailManager } from '../../../viewmodel/ComponentDetailManager'; import { AttributeChangeEnable } from '../../../viewmodel/ComponentDetailPageVM'; @@ -36,21 +36,23 @@ struct TextInputComponent { @State isText: boolean = false; @State textInputHeight: number = 0; @State contentOffset: number = 0; + private uiContext: UIContext = this.getUIContext(); + private context: Context = this.uiContext.getHostContext() as Context; aboutToAppear(): void { ComponentDetailManager.getInstance() .getDetailViewModel('TextInput')?.sendEvent(new AttributeChangeEnable('fontColor', this.isText)); - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel') || new GlobalInfoModel(); + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO) || new GlobalInfoModel(); let keyboardHeight: number = 0; - window.getLastWindow(getContext(this)).then(currentWindow => { - // Monitor the appearance and disappearance of the soft keyboard. - try { + try { + window.getLastWindow(this.context).then(currentWindow => { + // Monitor the appearance and disappearance of the soft keyboard. currentWindow.on('avoidAreaChange', async data => { if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) { return; } - keyboardHeight = px2vp(data.area.bottomRect.height); + keyboardHeight = this.uiContext.px2vp(data.area.bottomRect.height); /* When the size of the component preview area exceeds half the screen, the keyboard will cover the preview area. At this time, the component needs to move up when the keyboard appears. */ @@ -60,11 +62,11 @@ struct TextInputComponent { this.contentOffset = 0; } }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `CurrentWindow invoke error, the code is ${error.message}, the message is ${error.message}`); - } - }); + }); + } catch (err) { + const error: BusinessError = err as BusinessError; + Logger.error(TAG, `CurrentWindow invoke error, the code is ${error.message}, the message is ${error.message}`); + } } handleAttributeChange() { diff --git a/features/componentlibrary/src/main/ets/componentdetailview/textinput/viewmodel/TextInputCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/textinput/viewmodel/TextInputCodeGenerator.ets index a9f7b863e3bce71fb97239023cf54d766ad35dc3..efbf6df372d3a074b289196d8b64b82ed4db842d 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/textinput/viewmodel/TextInputCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/textinput/viewmodel/TextInputCodeGenerator.ets @@ -46,7 +46,7 @@ export class TextInputCodeGenerator implements CommonCodeGenerator { struct TextInputComponent { build() { Column() { - TextInput({ text: '开发者你好', placeholder: '请输入' }) + TextInput({ placeholder: '请输入文字' }) .margin({ left: 36, right: 36 }) .height(48) .enterKeyType(EnterKeyType.Done) diff --git a/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/component/TextPickerDialogBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/component/TextPickerDialogBuilder.ets index 4f257d2c89c8ab0e6bbe7268add00f612cd7c7e6..fd7614d55f40996fac70ebf1dec9599ac0b62812 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/component/TextPickerDialogBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/component/TextPickerDialogBuilder.ets @@ -13,53 +13,41 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; -import { DetailPageConstant } from '../../../constant/DetailPageConstant'; +import { Toast } from '@ohos/common'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { TextPickerDialogDescriptor } from '../viewmodel/TextPickerDialogDescriptor'; -const TAG: string = '[TextPickerDialogBuilder]'; - @Builder export function TextPickerDialogBuilder($$: DescriptorWrapper) { - Column() { - Button($r('app.string.text_picker_dialog_tip')) - .margin($r('sys.float.padding_level10')) - .buttonStyle(ButtonStyleMode.NORMAL) - .fontWeight(FontWeight.Medium) - .fontSize($r('sys.float.Body_L')) - .fontColor($r('sys.color.font_emphasize')) - .onClick(() => { - TextPickerDialog.show({ - range: $r('app.strarray.text_picker_data'), - defaultPickerItemHeight: ($$.descriptor as TextPickerDialogDescriptor).itemHeight, - canLoop: ($$.descriptor as TextPickerDialogDescriptor).canLoop, - onAccept: (value: TextPickerResult) => { - try { - promptAction.showToast({ - message: `Select ${value.value}`, - duration: DetailPageConstant.LONG_DURATION - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } - }, - onCancel: () => { - try { - promptAction.showToast({ - message: 'Canceled', - duration: DetailPageConstant.LONG_DURATION - }); - } catch (err) { - const error: BusinessError = err as BusinessError; - Logger.error(TAG, `Show toast error, the code is ${error.code}}, the message is ${error.message}`); - } - }, - }); - }) + TextPickerDialogComponent({ textPickerDialogDescriptor: $$.descriptor as TextPickerDialogDescriptor }) +} + +@Component +struct TextPickerDialogComponent { + @Prop textPickerDialogDescriptor: TextPickerDialogDescriptor; + + build() { + Column() { + Button($r('app.string.text_picker_dialog_tip')) + .margin($r('sys.float.padding_level10')) + .buttonStyle(ButtonStyleMode.NORMAL) + .fontWeight(FontWeight.Medium) + .fontSize($r('sys.float.Body_L')) + .fontColor($r('sys.color.font_emphasize')) + .onClick(() => { + this.getUIContext().showTextPickerDialog({ + range: $r('app.strarray.text_picker_data'), + defaultPickerItemHeight: this.textPickerDialogDescriptor.itemHeight, + canLoop: this.textPickerDialogDescriptor.canLoop, + onAccept: (value: TextPickerResult) => { + Toast.showLongToast(`Select ${value.value}`); + }, + onCancel: () => { + Toast.showLongToast('Canceled'); + }, + }); + }) + } + .width('100%') } - .width('100%') } \ No newline at end of file diff --git a/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/viewmodel/TextPickerDialogCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/viewmodel/TextPickerDialogCodeGenerator.ets index 2fdfd6fe42bff34117dc46cab49673da60dd08a6..6367722f7cd1f9e488b62e91df0d45e3b8f0d299 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/viewmodel/TextPickerDialogCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/textpickerdialogview/viewmodel/TextPickerDialogCodeGenerator.ets @@ -15,11 +15,7 @@ import type { OriginAttribute } from '../../../viewmodel/Attribute'; import { CommonCodeGenerator } from '../../../viewmodel/CommonCodeGenerator'; -import { - canLoopMapData, - itemHeightMapData, - pickerDataCode, -} from '../entity/TextDialogAttributeMapping'; +import { canLoopMapData, itemHeightMapData, pickerDataCode, } from '../entity/TextDialogAttributeMapping'; export class TextPickerDialogCodeGenerator implements CommonCodeGenerator { private canLoop: string = canLoopMapData.get('Default')!.code; @@ -38,7 +34,7 @@ export class TextPickerDialogCodeGenerator implements CommonCodeGenerator { break; } }); - return `import { promptAction } from '@kit.ArkUI'; + return `import type { BusinessError } from '@kit.BasicServicesKit'; @Component struct TextPickerComponent { @@ -51,13 +47,13 @@ struct TextPickerComponent { .fontSize($r('sys.float.Body_L')) .fontColor($r('sys.color.font_emphasize')) .onClick(() => { - TextPickerDialog.show({ + this.getUIContext().showTextPickerDialog({ range: ${pickerDataCode}, defaultPickerItemHeight: ${this.itemHeight}, canLoop: ${this.canLoop}, onAccept: (value: TextPickerResult) => { try { - promptAction.showToast({ + this.getUIContext().getPromptAction().showToast({ message: \`Select \${value.value}\`, duration: 200 }); @@ -68,7 +64,7 @@ struct TextPickerComponent { }, onCancel: () => { try { - promptAction.showToast({ + this.getUIContext().getPromptAction().showToast({ message: 'Canceled', duration: 200 }); diff --git a/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/component/TextToSpeechBuilder.ets b/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/component/TextToSpeechBuilder.ets index 978a9b619bd2be3558bdbfd3b93fe8d2967f1d59..6745526c29c0a27ec819848877d822b9fa7d9b21 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/component/TextToSpeechBuilder.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/component/TextToSpeechBuilder.ets @@ -15,7 +15,7 @@ import type { BusinessError } from '@kit.BasicServicesKit'; import { textToSpeech } from '@kit.CoreSpeechKit'; -import { Logger } from '@ohos/common'; +import { Logger, StorageKey } from '@ohos/common'; import type { DescriptorWrapper } from '../../../viewmodel/DescriptorWrapper'; import type { TextToSpeechDescriptor } from '../viewmodel/TextToSpeechDescriptor'; import { DetailPageConstant } from '../../../constant/DetailPageConstant'; @@ -30,7 +30,7 @@ struct TextToSpeechComponent { @Prop textToSpeechDescriptor: TextToSpeechDescriptor; @State originalText: string = '古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。'; @State text: string = ''; - @StorageLink('isPlaying') @Watch('changePlayMode') isPlaying: boolean = false; + @StorageLink(StorageKey.IS_PLAYING) @Watch('changePlayMode') isPlaying: boolean = false; changePlayMode() { ComponentDetailManager.getInstance() @@ -42,7 +42,7 @@ struct TextToSpeechComponent { const isBusy = ttsEngine?.isBusy(); if (isBusy) { ttsEngine?.stop(); - AppStorage.setOrCreate('isPlaying', false); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, false); ttsEngine?.shutdown(); } } catch (err) { @@ -64,15 +64,9 @@ struct TextToSpeechComponent { Row({ space: DetailPageConstant.COMPONENT_GAP_SIZE2 }) { Button() { - if (this.isPlaying) { - Image($r('app.media.pause')) - .height($r('app.float.button_height_normal')) - .width($r('app.float.button_height_normal')) - } else { - Image($r('app.media.play_circle_fill')) - .height($r('app.float.button_height_normal')) - .width($r('app.float.button_height_normal')) - } + SymbolGlyph(this.isPlaying ? $r('sys.symbol.pause_circle_fill') : $r('sys.symbol.play_circle_fill')) + .fontSize($r('app.float.default_font_40')) + .fontColor([$r('sys.color.icon_emphasize')]) } .height($r('app.float.button_height_normal')) .width($r('app.float.button_height_normal')) @@ -87,9 +81,9 @@ struct TextToSpeechComponent { }) Button() { - Image($r('app.media.stop_circle')) - .height($r('app.float.button_height_normal')) - .width($r('app.float.button_height_normal')) + SymbolGlyph($r('sys.symbol.stop_circle_fill')) + .fontSize($r('app.float.default_font_40')) + .fontColor([$r('sys.color.ohos_id_color_alert')]) } .height($r('app.float.button_height_normal')) .width($r('app.float.button_height_normal')) @@ -102,7 +96,7 @@ struct TextToSpeechComponent { const error: BusinessError = err as BusinessError; Logger.error(TAG, `The ttsEngine invoke error, the code is ${error.code}, the message is ${error.message}`); } - AppStorage.setOrCreate('isPlaying', false); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, false); }) } .margin({ top: $r('sys.float.padding_level8') }) @@ -140,25 +134,25 @@ struct TextToSpeechComponent { const speakListener: textToSpeech.SpeakListener = { onStart(requestId: string, response: textToSpeech.StartResponse) { Logger.debug(TAG, `onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`); - AppStorage.setOrCreate('isPlaying', true); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, true); }, onComplete(requestId: string, response: textToSpeech.CompleteResponse) { Logger.info(TAG, `onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`); // Only playback completion is handled here, with no regard to stream file generation. // 'type === 1' means broadcast over situation. if (response.type === 1) { - AppStorage.setOrCreate('isPlaying', false); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, false); ttsEngine?.stop(); } }, onStop(requestId: string, response: textToSpeech.StopResponse) { Logger.debug(TAG, `onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`); - AppStorage.setOrCreate('isPlaying', false); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, false); ttsEngine?.shutdown(); }, onError(requestId: string, errorCode: number, errorMessage: string) { Logger.error(TAG, `onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`); - AppStorage.setOrCreate('isPlaying', false); + AppStorage.setOrCreate(StorageKey.IS_PLAYING, false); ttsEngine?.shutdown(); } }; @@ -177,7 +171,11 @@ struct TextToSpeechComponent { requestId: '123456-a', extraParams: extraParam, }; - ttsEngine?.speak(this.originalText, speakParams); + try { + ttsEngine?.speak(this.originalText, speakParams); + } catch { + Logger.error(TAG, `Speak Failed.`); + } }; } diff --git a/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/viewmodel/TextToSpeechCodeGenerator.ets b/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/viewmodel/TextToSpeechCodeGenerator.ets index f00faf24351bd5ebc2e7dae6cbf284b403c31600..965e180502f3d791ec8193ae574de4b97999fe6d 100644 --- a/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/viewmodel/TextToSpeechCodeGenerator.ets +++ b/features/componentlibrary/src/main/ets/componentdetailview/texttospeech/viewmodel/TextToSpeechCodeGenerator.ets @@ -17,7 +17,19 @@ import type { OriginAttribute } from '../../../viewmodel/Attribute'; import { CommonCodeGenerator } from '../../../viewmodel/CommonCodeGenerator'; export class TextToSpeechCodeGenerator implements CommonCodeGenerator { - public generate(_attributes: OriginAttribute[]): string { + public speed: number = 1; + + public generate(attributes: OriginAttribute[]): string { + // Process any attributes. + attributes.forEach(attr => { + if (attr.name === 'speed') { + this.speed = parseFloat(attr.currentValue); + } + }); + return this.generateComponentCode(); + } + + private generateComponentCode(): string { return `import { textToSpeech } from '@kit.CoreSpeechKit'; import type { BusinessError } from '@kit.BasicServicesKit'; let ttsEngine: textToSpeech.TextToSpeechEngine; @@ -151,7 +163,7 @@ struct TextToSpeechComponent { ttsEngine?.setListener(speakListener); let extraParam: Record = { 'queueMode': 0, - 'speed': 1, + 'speed': ${this.speed}, 'volume': 2, 'pitch': 1, 'languageContext': 'zh-CN', diff --git a/features/componentlibrary/src/main/ets/constant/DetailPageConstant.ets b/features/componentlibrary/src/main/ets/constant/DetailPageConstant.ets index 2d123606e2bda369fbcfecaecd3c3934f46e40cb..a28ae2a7041afd1ca74a7e797ed1c66f707f7a73 100644 --- a/features/componentlibrary/src/main/ets/constant/DetailPageConstant.ets +++ b/features/componentlibrary/src/main/ets/constant/DetailPageConstant.ets @@ -16,7 +16,6 @@ export class DetailPageConstant { public static GRID_POPUP_OFFSET_Y: number = -10; public static IMAGE_POPUP_OFFSET_Y: number = -50; - public static LONG_DURATION: number = 2000; public static ANIMATION_DURATION: number = 500; public static ANIMATION_DURATION_SHORT: number = 300; public static CUSTOM_DIALOG_CONTENT_HEIGHT: number = 100; diff --git a/features/componentlibrary/src/main/ets/model/ComponentListModel.ets b/features/componentlibrary/src/main/ets/model/ComponentListModel.ets index 809b2c1e2de9675a4df034ea9db6c5cff073dd29..4914aff78922b31226406c4634cce046f817d6ea 100644 --- a/features/componentlibrary/src/main/ets/model/ComponentListModel.ets +++ b/features/componentlibrary/src/main/ets/model/ComponentListModel.ets @@ -14,7 +14,7 @@ */ import type { BusinessError } from '@kit.BasicServicesKit'; -import type { ResponseData } from '@ohos/common'; +import { ResponseData, StorageKey } from '@ohos/common'; import { Logger } from '@ohos/common'; import { ComponentLibraryService } from '../service/ComponentLibraryService'; import type { ComponentData } from './ComponentData'; @@ -53,7 +53,7 @@ export class ComponentListModel { } public preloadComponentData(): Promise { - AppStorage.setOrCreate('componentDetailConfig', componentDetailConfig); + AppStorage.setOrCreate(StorageKey.COMPONENT_CONFIG, componentDetailConfig); this.service.getComponentDetailList().then((detailList: ComponentDetailData[]) => { this.service.setDetailsToPreference(detailList); }); diff --git a/features/componentlibrary/src/main/ets/view/CodePreview.ets b/features/componentlibrary/src/main/ets/view/CodePreview.ets index 47c3a8fd4e7f7fe67ae54f662ec7523266153a0b..c214fb390a7f4bb83b5f1fe742081d5db9e278ff 100644 --- a/features/componentlibrary/src/main/ets/view/CodePreview.ets +++ b/features/componentlibrary/src/main/ets/view/CodePreview.ets @@ -16,8 +16,15 @@ import { ConfigurationConstant } from '@kit.AbilityKit'; import { curves, window } from '@kit.ArkUI'; import { BusinessError, settings } from '@kit.BasicServicesKit'; -import { type GlobalInfoModel, Logger, CommonConstants } from '@ohos/common'; -import { BreakpointTypeEnum, ScreenOrientation, WebNodeController, WebUtil, WindowUtil } from '@ohos/common'; +import { GlobalInfoModel, StorageKey, WebNodeController } from '@ohos/common'; +import { + BreakpointTypeEnum, + CommonConstants, + Logger, + ScreenOrientation, + WebUtil, + WindowUtil, +} from '@ohos/common'; import { CodePreviewComponent } from '../component/CodePreviewComponent'; import { CodePreviewJSUtil } from '../util/CodePreviewJSUtil'; import { CodePreviewEvent, CodePreviewPageVM } from '../viewmodel/CodePreviewPageVM'; @@ -29,8 +36,9 @@ const ORIENTATION_LOCK_ON: string = '0'; @Component export struct CodePreview { - @StorageLink('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') systemColorMode: ConfigurationConstant.ColorMode = AppStorage.get('systemColorMode')!; + @StorageLink(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @State webNodeController?: WebNodeController = undefined; @State isFocus: boolean = false; @State isBack: boolean = false; @@ -42,17 +50,18 @@ export struct CodePreview { private beginOrientationLockState?: string; private code: string = ''; private componentName: string = ''; + private context: Context = this.getUIContext().getHostContext() as Context; + private uiContext: UIContext = this.getUIContext(); onBackPage(): void { this.isBack = true; - WindowUtil.updateStatusBarColor(getContext(this), - this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); + WindowUtil.updateStatusBarColor(this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); this.javascriptRun(); - this.webNodeController?.remove(); + WebUtil.downPage(WebUtil.getComponentCodeUrl()); this.webNodeController = undefined; this.resetScreenOrientation(); this.preFinishAnimation(); - animateTo({ curve: curves.interpolatingSpring(0, 1, 342, 38) }, () => { + this.uiContext.animateTo({ curve: curves.interpolatingSpring(0, 1, 342, 38) }, () => { this.viewModel?.pop(false); }); } @@ -72,9 +81,10 @@ export struct CodePreview { } aboutToDisappear(): void { - WindowUtil.setMainWindowOrientation(getContext(), window.Orientation.UNSPECIFIED); + WindowUtil.setMainWindowOrientation(window.Orientation.UNSPECIFIED); if (canIUse('SystemCapability.Applications.Settings.Core')) { - settings.unregisterKeyObserver(getContext(), settings.general.ACCELEROMETER_ROTATION_STATUS, + settings.unregisterKeyObserver(this.context, + settings.general.ACCELEROMETER_ROTATION_STATUS, settings.domainName.DEVICE_SHARED); } } @@ -87,7 +97,7 @@ export struct CodePreview { } if (canIUse('SystemCapability.Applications.Settings.Core')) { this.beginOrientationLockState = - settings.getValueSync(getContext(), settings.general.ACCELEROMETER_ROTATION_STATUS, + settings.getValueSync(this.context, settings.general.ACCELEROMETER_ROTATION_STATUS, settings.domainName.DEVICE_SHARED); this.registerKeyObserver(); } @@ -96,14 +106,14 @@ export struct CodePreview { private registerKeyObserver(): boolean { if (canIUse('SystemCapability.Applications.Settings.Core')) { try { - return settings.registerKeyObserver(getContext(), settings.general.ACCELEROMETER_ROTATION_STATUS, + return settings.registerKeyObserver(this.context, settings.general.ACCELEROMETER_ROTATION_STATUS, settings.domainName.DEVICE_SHARED, () => { this.isOrientationLockChange = true; }); - } catch (error) { - const err: BusinessError = error as BusinessError; + } catch (err) { + const error: BusinessError = err as BusinessError; Logger.error(TAG, - `RegisterKeyObserver ${settings.general.ACCELEROMETER_ROTATION_STATUS} error: ${err.code}, ${err.message}`); + `RegisterKeyObserver ${settings.general.ACCELEROMETER_ROTATION_STATUS} error: ${error.code}, ${error.message}`); return false; } } @@ -114,9 +124,9 @@ export struct CodePreview { if (!this.isOrientationLockChange && this.beginOrientationLockState === ORIENTATION_LOCK_ON) { if (this.beginBreakpoint === BreakpointTypeEnum.LG || this.beginBreakpoint === BreakpointTypeEnum.MD) { if (this.beginScreenOrientation === ScreenOrientation.LANDSCAPE) { - WindowUtil.setMainWindowOrientation(getContext(), window.Orientation.LANDSCAPE); + WindowUtil.setMainWindowOrientation(window.Orientation.LANDSCAPE); } else { - WindowUtil.setMainWindowOrientation(getContext(), window.Orientation.PORTRAIT); + WindowUtil.setMainWindowOrientation(window.Orientation.PORTRAIT); } } } diff --git a/features/componentlibrary/src/main/ets/view/ComponentDetailView.ets b/features/componentlibrary/src/main/ets/view/ComponentDetailView.ets index c060540b144ee1da772a6f11943185cd689b1dd6..8e9654d8590e0e98da1a7f6e1e3733736fd1d437 100644 --- a/features/componentlibrary/src/main/ets/view/ComponentDetailView.ets +++ b/features/componentlibrary/src/main/ets/view/ComponentDetailView.ets @@ -18,6 +18,8 @@ import { displaySync } from '@kit.ArkGraphics2D'; import { CommonConstants, LoadingStatus, + Logger, + StorageKey, TopNavigationView, WebUtil, WindowUtil, @@ -35,10 +37,13 @@ import { ComponentDetailManager } from '../viewmodel/ComponentDetailManager'; import { CodePreviewJSUtil } from '../util/CodePreviewJSUtil'; import { RecommendData } from '../model/ComponentDetailData'; +const TAG = '[ComponentDetailView]'; + @Component({ freezeWhenInactive: true }) export struct ComponentDetailView { - @StorageProp('systemColorMode') systemColorMode: ConfigurationConstant.ColorMode = AppStorage.get('systemColorMode')!; - @StorageLink('webIsLoading') @Watch('sendCodeToWeb') webIsLoading: boolean = false; + @StorageProp(StorageKey.COLOR_MODE) systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; + @StorageLink(StorageKey.WEB_LOADING) @Watch('sendCodeToWeb') webIsLoading: boolean = false; @Prop componentName: string = ''; @Prop componentId: number = 0; private displaySync = displaySync.create(); @@ -48,7 +53,7 @@ export struct ComponentDetailView { aboutToAppear(): void { const isSystemDark: boolean = (this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); - WindowUtil.updateStatusBarColor(getContext(this), isSystemDark); + WindowUtil.updateStatusBarColor(isSystemDark); } aboutToDisappear(): void { @@ -138,7 +143,11 @@ export struct ComponentDetailView { refreshCodePreviewWeb() { this.webIsLoading = true; - WebUtil.getWebController(WebUtil.getComponentCodeUrl())?.refresh(); + try { + WebUtil.getWebController(WebUtil.getComponentCodeUrl())?.refresh(); + } catch { + Logger.error(TAG, `refreshCodePreviewWeb failed.`); + } } sendCodeToWeb() { diff --git a/features/componentlibrary/src/main/ets/view/ComponentListView.ets b/features/componentlibrary/src/main/ets/view/ComponentListView.ets index 8eeed6fadefcb25320136ca468bccb2e9b179ad8..11a076238c1f7f7d76494829f151aef50f1a1263 100644 --- a/features/componentlibrary/src/main/ets/view/ComponentListView.ets +++ b/features/componentlibrary/src/main/ets/view/ComponentListView.ets @@ -14,7 +14,7 @@ */ import { ConfigurationConstant } from '@kit.AbilityKit'; -import type { GlobalInfoModel, PageContext } from '@ohos/common'; +import { GlobalInfoModel, PageContext, StorageKey } from '@ohos/common'; import { BreakpointType, CommonConstants } from '@ohos/common'; import type { BannerData } from '@ohos/commonbusiness'; import { @@ -38,13 +38,13 @@ import { ComponentListEventType, ComponentListViewModel } from '../viewmodel/Com @Component({ freezeWhenInactive: true }) export struct ComponentListView { - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; viewModel: ComponentListViewModel = ComponentListViewModel.getInstance(); @State componentListState: ComponentListState = this.viewModel.getState(); - private componentListPageContext: PageContext = AppStorage.get('componentListPageContext')!; + private componentListPageContext: PageContext = AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)!; private scroller: Scroller = new Scroller(); aboutToAppear(): void { diff --git a/features/componentlibrary/src/main/ets/viewmodel/CodePreviewPageVM.ets b/features/componentlibrary/src/main/ets/viewmodel/CodePreviewPageVM.ets index 6412b74eba3b76da70bb6c15bf90e1710595e277..b23c0177f823e8c7a93a8837c2e3f15cbe541f3d 100644 --- a/features/componentlibrary/src/main/ets/viewmodel/CodePreviewPageVM.ets +++ b/features/componentlibrary/src/main/ets/viewmodel/CodePreviewPageVM.ets @@ -21,6 +21,7 @@ import { ModuleNameEnum, PageContext, ScrollDirectionEnum, + StorageKey, WebUtil } from '@ohos/common'; import { CodePreviewState } from './CodePreviewState'; @@ -28,7 +29,7 @@ import { DetailPageConstant } from '../constant/DetailPageConstant'; export class CodePreviewPageVM extends BaseVM { private static instance: CodePreviewPageVM; - private globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + private globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; constructor() { super(new CodePreviewState(0, 0, 1)); @@ -49,9 +50,8 @@ export class CodePreviewPageVM extends BaseVM { } public pop(animated?: boolean): void { - const pageContext: PageContext = - this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get('componentListPageContext')! : - AppStorage.get('pageContext')!; + const pageContext: PageContext = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? + AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)! : AppStorage.get(StorageKey.HOME_PAGE_CONTEXT)!; pageContext.popPage(animated); } @@ -66,11 +66,12 @@ export class CodePreviewPageVM extends BaseVM { } private changeScrollDirection = (direction: string, offset: number): void => { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; if (globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { return; } - animateTo({ + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + uiContext.animateTo({ duration: 300, curve: Curve.EaseOut, }, () => { diff --git a/features/componentlibrary/src/main/ets/viewmodel/ComponentDetailPageVM.ets b/features/componentlibrary/src/main/ets/viewmodel/ComponentDetailPageVM.ets index 9ef73ea7e9b40e895f097c4673675386d63b2fbd..a4db1f91bc8dff325384d26eb0ea16e5d2f84784 100644 --- a/features/componentlibrary/src/main/ets/viewmodel/ComponentDetailPageVM.ets +++ b/features/componentlibrary/src/main/ets/viewmodel/ComponentDetailPageVM.ets @@ -23,6 +23,7 @@ import { LoadingStatus, ObservedArray, PageContext, + StorageKey, TopNavigationData, } from '@ohos/common'; import { @@ -53,11 +54,11 @@ export class ComponentDetailPageVM extends BaseVM { public originAttributes: OriginAttribute[] = []; public fullAttributes: ObservedArray = []; private detailPageModel = ComponentDetailModel.getInstance(); - private globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + private globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; private detailData?: ComponentDetailData; constructor(componentName: string) { - const componentDetailConfig: Record = AppStorage.get('componentDetailConfig')!; + const componentDetailConfig: Record = AppStorage.get(StorageKey.COMPONENT_CONFIG)!; super(new ComponentDetailState(componentDetailConfig[componentName].descriptor(), [], '', [], LoadingStatus.OFF, new TopNavigationData())); this.componentName = componentName; @@ -112,15 +113,14 @@ export class ComponentDetailPageVM extends BaseVM { } public pop(animated?: boolean) { - const pageContext: PageContext = - this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get('componentListPageContext')! : - AppStorage.get('pageContext')!; + const pageContext: PageContext = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? + AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)! : AppStorage.get(StorageKey.HOME_PAGE_CONTEXT)!; pageContext.popPage(animated); } public jumpToCodePreview(code: string, preRebuild: () => void) { const pageContext: PageContext = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? - AppStorage.get('componentListPageContext')! : AppStorage.get('pageContext')!; + AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)! : AppStorage.get(StorageKey.HOME_PAGE_CONTEXT)!; pageContext.openPage({ routerName: 'CodePreviewView', param: { @@ -133,7 +133,7 @@ export class ComponentDetailPageVM extends BaseVM { public jumpToPenKitView() { const pageContext: PageContext = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? - AppStorage.get('componentListPageContext')! : AppStorage.get('pageContext')!; + AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)! : AppStorage.get(StorageKey.HOME_PAGE_CONTEXT)!; pageContext.openPage({ routerName: 'PenKitView', }); @@ -246,7 +246,7 @@ export class ComponentDetailPageVM extends BaseVM { private processAttribute(attributes: AttributeData[]) { let curValueArray: string[] = []; - const systemColorMode: ConfigurationConstant.ColorMode = AppStorage.get('systemColorMode')!; + const systemColorMode: ConfigurationConstant.ColorMode = AppStorage.get(StorageKey.COLOR_MODE)!; const originAttributeList: OriginAttribute[] = []; const attributeList: ObservedArray = []; attributes.forEach((attribute: AttributeData) => { diff --git a/features/componentlibrary/src/main/ets/viewmodel/ComponentListViewModel.ets b/features/componentlibrary/src/main/ets/viewmodel/ComponentListViewModel.ets index f12c1063e3e5ef96f01d34fc16c3eaeb263278de..c21f0dc24b8b93240afe66014c4d30c50456b401 100644 --- a/features/componentlibrary/src/main/ets/viewmodel/ComponentListViewModel.ets +++ b/features/componentlibrary/src/main/ets/viewmodel/ComponentListViewModel.ets @@ -15,7 +15,7 @@ import { ConfigurationConstant } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel, ResponseData, } from '@ohos/common'; +import { GlobalInfoModel, ResponseData, StorageKey, } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, @@ -44,7 +44,7 @@ const TAG = '[ComponentListViewModel]'; export class ComponentListViewModel extends BaseHomeViewModel { private static instance: ComponentListViewModel; - private globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + private globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; private componentListModel: ComponentListModel = ComponentListModel.getInstance(); private bannerColumnSection: SectionOptions = { itemsCount: 1, @@ -90,11 +90,11 @@ export class ComponentListViewModel extends BaseHomeViewModel) => { if (result.data.bannerInfos) { @@ -107,17 +107,17 @@ export class ComponentListViewModel extends BaseHomeViewModel this.state.currentPage * this.pageSize); - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; if (globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.LG && globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.XL) { this.state.topNavigationData.titleColor = StatusBarColorType.WHITE; - WindowUtil.updateStatusBarColor(getContext(), true); + WindowUtil.updateStatusBarColor(true); TAB_CONTENT_STATUSES[TabBarType.HOME] = true; } this.state.loadingModel.loadingStatus = LoadingStatus.SUCCESS; }) .catch((error: BusinessError) => { - WindowUtil.updateStatusBarColor(getContext(), isDark); + WindowUtil.updateStatusBarColor(isDark); TAB_CONTENT_STATUSES[TabBarType.HOME] = isDark; if (error.code === RequestErrorCode.ERROR_NETWORK_CONNECT_FAILED) { this.state.loadingModel.loadingStatus = LoadingStatus.NO_NETWORK; @@ -167,9 +167,8 @@ export class ComponentListViewModel extends BaseHomeViewModel void; - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; scroller: Scroller = new Scroller(); reloadData?: Function; diff --git a/features/devpractices/src/main/ets/component/CategorySamples.ets b/features/devpractices/src/main/ets/component/CategorySamples.ets index 468dab7d702181c96cbc3814925eba3fab2ef6c3..7bcbede020a59a2882ab78cc73831e1b58048073 100644 --- a/features/devpractices/src/main/ets/component/CategorySamples.ets +++ b/features/devpractices/src/main/ets/component/CategorySamples.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, ColumnEnum, CommonConstants, LoadingMore, LoadingStatus, NoMore } from '@ohos/common'; import { CardStyleTypeEnum, SampleDetailParams } from '@ohos/commonbusiness'; import { SampleConstant } from '../common/SampleConstant'; @@ -29,7 +29,7 @@ import { SampleScrollCard } from './SampleScrollCard'; export struct CategorySamples { scroller: Scroller = new Scroller(); viewModel: PracticeViewModel = PracticeViewModel.getInstance(); - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop sampleCategory: SampleCategory; aboutToAppear(): void { diff --git a/features/devpractices/src/main/ets/component/PictureAboveTextCard.ets b/features/devpractices/src/main/ets/component/PictureAboveTextCard.ets index ec49025665dd7ebd5e8d470e0dea9f4ff509062a..37100055a6b5b15addbe87aae6f5593e4948886f 100644 --- a/features/devpractices/src/main/ets/component/PictureAboveTextCard.ets +++ b/features/devpractices/src/main/ets/component/PictureAboveTextCard.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BreakpointType, BreakpointTypeEnum, CommonConstants, GlobalInfoModel } from '@ohos/common'; +import { BreakpointType, BreakpointTypeEnum, CommonConstants, GlobalInfoModel, StorageKey } from '@ohos/common'; import type { SampleCardData, SampleContent } from '../model/SampleData'; import { TagLabel } from './TagLabel'; import { ConfigurationConstant } from '@kit.AbilityKit'; @@ -24,9 +24,10 @@ const TAG_PADDING: number = 32; @Component export struct PictureAboveTextCard { - @StorageProp('GlobalInfoModel') @Watch('calculateTagMaxWidth') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') systemColorMode: ConfigurationConstant.ColorMode = AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('calculateTagMaxWidth') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @Prop sampleCardData: SampleCardData; @State sampleContent?: SampleContent = undefined; @State maxWidth: number = 0; @@ -46,7 +47,7 @@ export struct PictureAboveTextCard { const paddingVal = new BreakpointType({ sm: CommonConstants.SPACE_16, md: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? CommonConstants.SPACE_32 : - CommonConstants.SPACE_24, + CommonConstants.SPACE_24, lg: CommonConstants.SPACE_32, xl: CommonConstants.SPACE_32, }).getValue(this.globalInfoModel.currentBreakpoint); @@ -68,7 +69,7 @@ export struct PictureAboveTextCard { Image($rawfile(this.sampleContent?.mediaUrl)) .alt($r('app.media.img_placeholder')) .height('100%') - .height('100%') + .width('100%') .objectFit(ImageFit.Contain) .draggable(true) } @@ -94,8 +95,10 @@ export struct PictureAboveTextCard { .alignItems(HorizontalAlign.Start) .layoutWeight(1) - Button({ type: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? ButtonType.ROUNDED_RECTANGLE : - ButtonType.Circle }) { + Button({ + type: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? ButtonType.Normal : + ButtonType.Circle + }) { SymbolGlyph($r('sys.symbol.chevron_right')) .fontColor([this.sampleCardData.cardStyleType === CardStyleTypeEnum.PICTURE_TO_SWIPER ? $r('app.color.icon_secondary_color') : $r('sys.color.icon_secondary')]) @@ -104,6 +107,7 @@ export struct PictureAboveTextCard { .margin({ left: $r('sys.float.padding_level6') }) .height($r('app.float.card_button_height')) .aspectRatio(1) + .borderRadius($r('sys.float.corner_radius_level4')) .backgroundColor($r('sys.color.comp_background_tertiary')) } .padding({ diff --git a/features/devpractices/src/main/ets/component/SampleCard.ets b/features/devpractices/src/main/ets/component/SampleCard.ets index ecd839bc445f3abbc8b2e5ec2c31573169296e89..a3c550f0e00826075a8d8b982d95b81349a46c8b 100644 --- a/features/devpractices/src/main/ets/component/SampleCard.ets +++ b/features/devpractices/src/main/ets/component/SampleCard.ets @@ -26,6 +26,7 @@ import { WebUrlType, WebUtil, type GlobalInfoModel, + StorageKey, } from '@ohos/common'; import { SampleDetailConstant } from '../constant/CommonConstants'; import { BindSheetEvent, SampleDetailPageVM, LoadSampleEvent } from '../viewmodel/SampleDetailPageVM'; @@ -36,13 +37,14 @@ const TAG = '[SampleCard]'; @Component export struct SampleCard { viewModel: SampleDetailPageVM = SampleDetailPageVM.getInstance(); - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Consume currentIndex: number; @Prop sampleIndex: number; @ObjectLink sampleCard: SampleCardData; @State backIconBgColor: ResourceColor = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? Color.Transparent : $r('sys.color.comp_background_tertiary'); + private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; aboutToAppear(): void { WebUtil.createWebNode(this.sampleCard.originalUrl, this.getUIContext(), NestedScrollMode.SELF_ONLY); @@ -61,8 +63,7 @@ export struct SampleCard { description: this.sampleCard.originalUrl }); let controller: systemShare.ShareController = new systemShare.ShareController(shareData); - let context = getContext(this) as common.UIAbilityContext; - controller.show(context, { + controller.show(this.context, { selectionMode: systemShare.SelectionMode.SINGLE, previewMode: systemShare.SharePreviewMode.DEFAULT }).catch((error: BusinessError) => { @@ -166,13 +167,13 @@ export struct SampleCard { .borderRadius($r('sys.float.corner_radius_level7')) .height($r('app.float.progress_height')) .color($r('sys.color.background_emphasize')) - .backgroundColor($r('sys.color.comp_background_primary_contrary')) + .backgroundColor($r('sys.color.background_primary')) .style({ borderColor: $r('sys.color.background_emphasize'), - borderWidth: $r('sys.float.border_small'), + borderWidth: $r('sys.float.border_larger'), content: `${this.sampleCard.downloadProgress}%`, - font: { size: $r('sys.float.Subtitle_S'), style: FontStyle.Normal, weight: FontWeight.Medium }, - fontColor: Color.Black, + font: { size: $r('sys.float.Body_S'), style: FontStyle.Normal, weight: FontWeight.Medium }, + fontColor: $r('sys.color.font_primary'), }) } else { Button(this.sampleCard.installed ? $r('app.string.experience_sample') : $r('app.string.download_sample')) @@ -212,7 +213,7 @@ export struct SampleCard { @Extend(Button) function cardButtonStyle(backgroundColor: ResourceColor, fontColor: ResourceColor) { .layoutWeight(1) - .fontSize($r('sys.float.Subtitle_S')) + .fontSize($r('sys.float.Body_M')) .fontWeight(FontWeight.Medium) .fontColor(fontColor) .backgroundColor(backgroundColor) diff --git a/features/devpractices/src/main/ets/component/SampleComponent.ets b/features/devpractices/src/main/ets/component/SampleComponent.ets index 0abaddf1dfb3a7118b89d03e5e14695b1c372492..58dc99ffefdc6512291fd92d2bd842133d94f3d4 100644 --- a/features/devpractices/src/main/ets/component/SampleComponent.ets +++ b/features/devpractices/src/main/ets/component/SampleComponent.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, ColumnEnum, CommonConstants, VideoComponent } from '@ohos/common'; import { MediaTypeEnum } from '@ohos/commonbusiness'; import { SampleDetailData } from '../viewmodel/SampleDetailState'; @@ -21,7 +21,7 @@ import { SampleCard } from './SampleCard'; @Component export struct SampleComponent { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @ObjectLink singleSampleData: SampleDetailData; @Prop @Require sampleIndex: number; @Prop showIndicator: boolean = false; diff --git a/features/devpractices/src/main/ets/component/SampleScrollCard.ets b/features/devpractices/src/main/ets/component/SampleScrollCard.ets index ec6136c5859d8d08df293c55be41aee70dd5d18d..96502a8f93d8fd8d75efa67c2ae69a8694b1ec09 100644 --- a/features/devpractices/src/main/ets/component/SampleScrollCard.ets +++ b/features/devpractices/src/main/ets/component/SampleScrollCard.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import { SampleCardData, SampleContent } from '../model/SampleData'; import { TagLabel } from './TagLabel'; @@ -21,11 +21,13 @@ import { TagLabel } from './TagLabel'; const ITEM_HEIGHT: number = 340; const ITEM_ASPECT: number = 0.74; const LOG_MAX_WIDTH: number = 202; +const DISPLAY_COUNT: number = 3; +const MARGIN_COUNT: number = 2; @Component export struct SampleScrollCard { - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop sampleCardData: SampleCardData; handleItemClick?: Function; @State sampleItemWidth: number = ITEM_HEIGHT * ITEM_ASPECT; @@ -59,14 +61,11 @@ export struct SampleScrollCard { lg: CommonConstants.SPACE_32, }).getValue(this.globalInfoModel.currentBreakpoint); if ((this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.LG || - this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) && - this.sampleCardData.sampleContents.length === 3) { - this.sampleItemWidth = (this.globalInfoModel.deviceWidth - barWidth - 64 - 32) / 3; - } else if (this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM || - this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.MD) { - this.sampleItemWidth = ITEM_HEIGHT * ITEM_ASPECT; + this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL)) { + this.sampleItemWidth = (this.globalInfoModel.deviceWidth - barWidth - CommonConstants.SPACE_32 * MARGIN_COUNT - + CommonConstants.SPACE_16 * (DISPLAY_COUNT - 1)) / DISPLAY_COUNT; } else { - this.sampleItemWidth = Math.floor((this.globalInfoModel.deviceWidth - barWidth - 64 - 32) / 3.5); + this.sampleItemWidth = ITEM_HEIGHT * ITEM_ASPECT; } } diff --git a/features/devpractices/src/main/ets/component/TagLabel.ets b/features/devpractices/src/main/ets/component/TagLabel.ets index 46b75ee1f7cbe9093e08ab98675cc18f8fe2e81c..6e9fd03536928242948fc5377a5c2b7e30082fe6 100644 --- a/features/devpractices/src/main/ets/component/TagLabel.ets +++ b/features/devpractices/src/main/ets/component/TagLabel.ets @@ -14,7 +14,7 @@ */ import { MeasureText } from '@kit.ArkUI'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import { CardStyleTypeEnum } from '@ohos/commonbusiness'; import { SampleDetailConstant } from '../constant/CommonConstants'; @@ -36,7 +36,7 @@ export struct TagLabel { @Prop cardStyleType: CardStyleTypeEnum; @State tagList: TagInfo[] = []; @State showEllipsis: boolean = false; - @State globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @State globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @State displayPopup: boolean = false; private allTagStr: string = ''; @@ -49,7 +49,7 @@ export struct TagLabel { let currentWidth: number = 0; const ellipsisWidth = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? MIN_WIDTH : 0; this.tags.forEach((tag: string) => { - const tagWidth: number = Math.ceil(px2vp(MeasureText.measureText({ + const tagWidth: number = Math.ceil(this.getUIContext().px2vp(this.getUIContext().getMeasureUtils().measureText({ textContent: tag, fontSize: $r('sys.float.Body_S') }))) + PADDING_WIDTH + CommonConstants.SPACE_8; diff --git a/features/devpractices/src/main/ets/view/PracticeDetailView.ets b/features/devpractices/src/main/ets/view/PracticeDetailView.ets index 2c2695c03f9f5f1b44d53575d3741bf13fed46c8..14238278b3f525e6fb2fc58916943234e4dec6c1 100644 --- a/features/devpractices/src/main/ets/view/PracticeDetailView.ets +++ b/features/devpractices/src/main/ets/view/PracticeDetailView.ets @@ -14,18 +14,12 @@ */ import { ConfigurationConstant } from '@kit.AbilityKit'; -import { promptAction } from '@kit.ArkUI'; -import type { GlobalInfoModel } from '@ohos/common'; -import { CommonConstants, LoadingStatus, TopNavigationView, WindowUtil } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; +import { CommonConstants, LoadingStatus, Toast, TopNavigationView, WindowUtil } from '@ohos/common'; import { BaseDetailComponent, SampleDetailParams } from '@ohos/commonbusiness'; import { SampleComponent } from '../component/SampleComponent'; import type { SampleDetailData, SampleDetailState } from '../viewmodel/SampleDetailState'; -import { - InitSampleDetailEvent, - PopEvent, - SampleDetailPageVM, - SetIndexEvent, -} from '../viewmodel/SampleDetailPageVM'; +import { InitSampleDetailEvent, PopEvent, SampleDetailPageVM, SetIndexEvent } from '../viewmodel/SampleDetailPageVM'; @Builder export function SampleDetailViewBuilder() { @@ -34,9 +28,9 @@ export function SampleDetailViewBuilder() { @Component export struct SampleDetailView { - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; viewModel: SampleDetailPageVM = SampleDetailPageVM.getInstance(); @State sampleDetailState: SampleDetailState = this.viewModel.getState(); @State loadingStatus: LoadingStatus = LoadingStatus.IDLE; @@ -49,7 +43,7 @@ export struct SampleDetailView { handleColorModeChange() { const isSystemDark: boolean = (this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); - WindowUtil.updateStatusBarColor(getContext(this), isSystemDark); + WindowUtil.updateStatusBarColor(isSystemDark); } private onBack(): void { @@ -85,7 +79,7 @@ export struct SampleDetailView { .onAction(() => { if (this.sampleDetailState.sampleDatas[this.currentIndex].sampleCard.downloadProgress >= 0 && this.sampleDetailState.sampleCount > 1) { - promptAction.showToast({ message: $r('app.string.swiper_gesture') }); + Toast.showToast($r('app.string.swiper_gesture')); } }) ) diff --git a/features/devpractices/src/main/ets/view/PracticesView.ets b/features/devpractices/src/main/ets/view/PracticesView.ets index ed1b7acda9db9d870155dab8b46f4e33a75546c0..3e359d75ec9f5d3922d3ef63e8f515df63dbc4ca 100644 --- a/features/devpractices/src/main/ets/view/PracticesView.ets +++ b/features/devpractices/src/main/ets/view/PracticesView.ets @@ -14,7 +14,7 @@ */ import { ConfigurationConstant } from '@kit.AbilityKit'; -import type { GlobalInfoModel, PageContext } from '@ohos/common'; +import { GlobalInfoModel, PageContext, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import type { BannerData } from '@ohos/commonbusiness'; import { @@ -34,10 +34,10 @@ import { LoadSamplePageParam, PracticeEventType, PracticeViewModel } from '../vi @Component({ freezeWhenInactive: true }) export struct PracticesView { viewModel: PracticeViewModel = PracticeViewModel.getInstance(); - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @State naviStatusHeight: number = CommonConstants.NAVIGATION_HEIGHT + this.globalInfoModel.statusBarHeight; @State currentIndex: number = 0; @State practiceState: PracticeState = this.viewModel.getState(); @@ -45,7 +45,7 @@ export struct PracticesView { private categoryTabController: TabsController = new TabsController(); private listScroller: Scroller = new Scroller(); private headerScroller: Scroller = new Scroller(); - private samplePageContext: PageContext = AppStorage.get('samplePageContext')!; + private samplePageContext: PageContext = AppStorage.get(StorageKey.SAMPLE_PAGE_CONTEXT)!; private cornerNum: Length = this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? $r('sys.float.corner_radius_level4') : '50%'; aboutToAppear(): void { diff --git a/features/devpractices/src/main/ets/viewmodel/PracticeViewModel.ets b/features/devpractices/src/main/ets/viewmodel/PracticeViewModel.ets index 941cb5259ff322538c955b85c4fab3c190da608e..f8f1219c640990b1a3907857e3fc5f89b84941c0 100644 --- a/features/devpractices/src/main/ets/viewmodel/PracticeViewModel.ets +++ b/features/devpractices/src/main/ets/viewmodel/PracticeViewModel.ets @@ -15,7 +15,7 @@ import { ConfigurationConstant } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel, ResponseData } from '@ohos/common'; +import { GlobalInfoModel, ResponseData, StorageKey } from '@ohos/common'; import { BreakpointTypeEnum, LoadingModel, @@ -71,11 +71,12 @@ export class PracticeViewModel extends BaseHomeViewModel { } protected loadSamplePage(param: LoadSamplePageParam): void { - const isDark: boolean = AppStorage.get('systemColorMode') === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; + const isDark: boolean = AppStorage.get(StorageKey.COLOR_MODE) === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; this.state.loadingModel.loadingStatus = LoadingStatus.LOADING; this.state.topNavigationData.titleColor = isDark ? StatusBarColorType.WHITE : StatusBarColorType.BLACK; this.state.topNavigationData.isBlur = false; - WindowUtil.updateStatusBarColor(getContext(), isDark); + this.state.topNavigationData.showTab = false; + WindowUtil.updateStatusBarColor(isDark); this.sampleModel.getSamplePage(1, this.pageSize) .then((result: ResponseData) => { if (result.data.bannerInfos) { @@ -94,11 +95,11 @@ export class PracticeViewModel extends BaseHomeViewModel { categoryList.push(sampleCategory); }); this.state.sampleCategories = categoryList; - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; if (globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.LG && globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.XL) { this.state.topNavigationData.titleColor = StatusBarColorType.WHITE; - WindowUtil.updateStatusBarColor(getContext(), true); + WindowUtil.updateStatusBarColor(true); TAB_CONTENT_STATUSES[TabBarType.SAMPLE] = true; } this.state.loadingModel.loadingStatus = LoadingStatus.SUCCESS; @@ -106,7 +107,7 @@ export class PracticeViewModel extends BaseHomeViewModel { }) .catch((error: BusinessError) => { Logger.error(TAG, `load PracticePage Failed, ${error.code} ${error.message}`); - WindowUtil.updateStatusBarColor(getContext(), isDark); + WindowUtil.updateStatusBarColor(isDark); TAB_CONTENT_STATUSES[TabBarType.SAMPLE] = isDark; if (error.code === RequestErrorCode.ERROR_NETWORK_CONNECT_FAILED) { this.state.loadingModel.loadingStatus = LoadingStatus.NO_NETWORK; @@ -139,10 +140,10 @@ export class PracticeViewModel extends BaseHomeViewModel { } protected jumpDetailView(param: SampleDetailParams): void { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; const pageContext: PageContext = - globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get('samplePageContext')! : - AppStorage.get('pageContext') as PageContext; + globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get(StorageKey.SAMPLE_PAGE_CONTEXT)! : + AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; pageContext.openPage({ routerName: 'SampleDetailView', param: param, diff --git a/features/devpractices/src/main/ets/viewmodel/SampleDetailPageVM.ets b/features/devpractices/src/main/ets/viewmodel/SampleDetailPageVM.ets index 1a069b88bb14d4f70276d10d2a8c65c928599ba1..82f3797348fd9b6c8597c29c783e42b7633d096c 100644 --- a/features/devpractices/src/main/ets/viewmodel/SampleDetailPageVM.ets +++ b/features/devpractices/src/main/ets/viewmodel/SampleDetailPageVM.ets @@ -14,7 +14,6 @@ */ import type { common } from '@kit.AbilityKit'; -import { promptAction } from '@kit.ArkUI'; import { BusinessError, emitter } from '@kit.BasicServicesKit'; import { connection } from '@kit.NetworkKit'; import { moduleInstallManager } from '@kit.StoreKit'; @@ -28,6 +27,8 @@ import { LoadingStatus, Logger, PageContext, + StorageKey, + Toast, } from '@ohos/common'; import { SampleCardData, SampleDetailData, SampleDetailState } from './SampleDetailState'; import type { SingleSampleData } from '../model/SampleDetailData'; @@ -109,7 +110,7 @@ export class SampleDetailPageVM extends BaseVM { private pop(): void { if (this.state.installingStatus) { - promptAction.showToast({ message: $r('app.string.installing_status') }); + Toast.showToast($r('app.string.installing_status')); } else { this.state.isBackPressed = true; if (this.state.downloadingStatus) { @@ -119,10 +120,10 @@ export class SampleDetailPageVM extends BaseVM { } emitter.off(CommonConstants.DYNAMIC_INSTALL_EVENT); Logger.info(TAG, 'cancelDownloadListener success'); - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; const pageContext: PageContext = - globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get('samplePageContext')! : - AppStorage.get('pageContext') as PageContext; + globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get(StorageKey.SAMPLE_PAGE_CONTEXT)! : + AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; pageContext.popPage(); } } @@ -175,7 +176,9 @@ export class SampleDetailPageVM extends BaseVM { this.setSampleInstalledStatus(this.state.currentIndex, true); this.setSampleDownloadingStatus(this.state.currentIndex, false, -1); this.setInstallingStatus(false); - DynamicInstallManager.loadModule(getContext(this) as common.UIAbilityContext, + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; + DynamicInstallManager.loadModule(context, this.state.sampleDatas[this.state.currentIndex].sampleCard.abilityName); Logger.info(TAG, `loadSampleCallback installed : ${this.state.sampleDatas[this.state.currentIndex].sampleCard.abilityName}`); @@ -196,9 +199,9 @@ export class SampleDetailPageVM extends BaseVM { } const currentSampleType = this.state.sampleDatas[this.state.currentIndex].sampleCard.sampleType; if (currentSampleType === SampleTypeEnum.COMMON_CLIENT) { - promptAction.showToast({ message: $r('app.string.client_prompt') }); + Toast.showToast($r('app.string.client_prompt')); } else if (currentSampleType === SampleTypeEnum.WEARABLE_CLIENT) { - promptAction.showToast({ message: $r('app.string.watch_prompt') }); + Toast.showToast($r('app.string.watch_prompt')); } else { this.startTask(); } @@ -206,9 +209,11 @@ export class SampleDetailPageVM extends BaseVM { private startTask(): void { if (this.state.sampleDatas[this.state.currentIndex].sampleCard.installed) { - const ctx: common.UIAbilityContext = getContext() as common.UIAbilityContext; + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; try { - DynamicInstallManager.loadModule(ctx, this.state.sampleDatas[this.state.currentIndex].sampleCard.abilityName); + DynamicInstallManager.loadModule(context, + this.state.sampleDatas[this.state.currentIndex].sampleCard.abilityName); } catch (error) { Logger.error(TAG, `Failed to loadModule, error code: ${error.code}, error data: ${error.message}`); } @@ -234,21 +239,22 @@ export class SampleDetailPageVM extends BaseVM { private startDownload(): void { Logger.info(TAG, `start download sample: ${this.state.sampleDatas[this.state.currentIndex].sampleCard.title}`); - const ctx: common.UIAbilityContext = getContext() as common.UIAbilityContext; - DynamicInstallManager.fetchModule(ctx, this.state.sampleDatas[this.state.currentIndex].sampleCard.moduleName) + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; + DynamicInstallManager.fetchModule(context, this.state.sampleDatas[this.state.currentIndex].sampleCard.moduleName) .then((data: moduleInstallManager.ModuleInstallSessionState) => { if (data.code === moduleInstallManager.RequestErrorCode.SUCCESS) { this.state.taskId = data.taskId; } else if (data.code === moduleInstallManager.RequestErrorCode.DOWNLOAD_WAIT_WIFI) { - moduleInstallManager.showCellularDataConfirmation(ctx, data.taskId); + moduleInstallManager.showCellularDataConfirmation(context, data.taskId); this.state.taskId = data.taskId; } else { if (data.code === moduleInstallManager.RequestErrorCode.MODULE_UNAVAILABLE) { - promptAction.showToast({ message: $r('app.string.module_nonexistent') }); + Toast.showToast($r('app.string.module_nonexistent')); } else if (data.code === moduleInstallManager.RequestErrorCode.NETWORK_ERROR) { - promptAction.showToast({ message: $r('app.string.internet_error') }); + Toast.showToast($r('app.string.internet_error')); } else if (data.code === moduleInstallManager.RequestErrorCode.INVALID_REQUEST) { - promptAction.showToast({ message: $r('app.string.requestinfo_error') }); + Toast.showToast($r('app.string.requestinfo_error')); } this.setSampleDownloadingStatus(this.state.currentIndex, false, -1); } diff --git a/features/exploration/src/main/ets/component/ArticleWebComponent.ets b/features/exploration/src/main/ets/component/ArticleWebComponent.ets index 8514ea2a0de5388be4b02e61d9ff74e116f321b9..521939b8e969d92c63c952879b364ffbfa72300b 100644 --- a/features/exploration/src/main/ets/component/ArticleWebComponent.ets +++ b/features/exploration/src/main/ets/component/ArticleWebComponent.ets @@ -24,6 +24,7 @@ import { LoadingStatus, Logger, NativeActionData, + StorageKey, TopNavigationView, WebSheetBuilder, WebUtil, @@ -46,9 +47,9 @@ export struct ArticleWebComponent { @Prop @Require detailsUrl: string; @Prop tabViewType: number = -1; @Link loadingStatus: LoadingStatus; - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @State bindSheetShow: boolean = false; @State bindSheetSrc: string = ''; @State detailState: ExplorationDetailState = this.viewModel.getState(); @@ -80,7 +81,7 @@ export struct ArticleWebComponent { handleColorModeChange() { const isSystemDark: boolean = (this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); - WindowUtil.updateStatusBarColor(getContext(this), isSystemDark); + WindowUtil.updateStatusBarColor(isSystemDark); } registerJsFunction() { @@ -135,11 +136,9 @@ export struct ArticleWebComponent { .allowDrop(null) .onPageEnd(() => { this.loadingStatus = LoadingStatus.SUCCESS; - WebUtil.setTrustList(this.detailsUrl); }) .onLoadIntercept((event: OnLoadInterceptEvent) => { - const tempUrl = event.data.getRequestUrl(); - return WebUtil.checkUrl(tempUrl); + return WebUtil.handleLoadIntercept(event); }) .onConsole((event: OnConsoleEvent) => { Logger.error(TAG, event.message.getMessage()) @@ -152,7 +151,9 @@ export struct ArticleWebComponent { .onControllerAttached(() => { WebUtil.setWebController(this.detailsUrl, this.webController); // Setting the local file path that allows cross-domain access. - this.webController.setPathAllowingUniversalAccess([getContext().resourceDir]); + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: Context = uiContext.getHostContext() as Context; + this.webController.setPathAllowingUniversalAccess([context.resourceDir]); }) .onScroll((event) => { this.handleWebScroll(event.yOffset); diff --git a/features/exploration/src/main/ets/component/DeveloperCard.ets b/features/exploration/src/main/ets/component/DeveloperCard.ets index 960d0ca248326f3c6c9f08ccd05e4ffe690ea537..1263161bf9fbc177b9d672793a3894526f5273f1 100644 --- a/features/exploration/src/main/ets/component/DeveloperCard.ets +++ b/features/exploration/src/main/ets/component/DeveloperCard.ets @@ -14,7 +14,7 @@ */ import { deviceInfo } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants, ProductSeriesEnum } from '@ohos/common'; import type { DiscoverContent } from '../model/DiscoverData'; import { DeveloperItem } from './DeveloperItem'; @@ -24,7 +24,7 @@ const DEVELOPER_ITEM_RATIO_VERDE = 240 / 408; @Component export struct DeveloperCard { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop @Require discoverContents: DiscoverContent[]; handleItemClick?: Function; diff --git a/features/exploration/src/main/ets/component/ExperienceCard.ets b/features/exploration/src/main/ets/component/ExperienceCard.ets index 37667f2aa67cde5aceff5b3d1f0fefd7cf77e961..dbfdfc61c4b154a5f84cb34211e6b4908c432dd3 100644 --- a/features/exploration/src/main/ets/component/ExperienceCard.ets +++ b/features/exploration/src/main/ets/component/ExperienceCard.ets @@ -15,7 +15,7 @@ import { curves } from '@kit.ArkUI'; import { deviceInfo } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants, ProductSeriesEnum } from '@ohos/common'; import type { DiscoverContent } from '../model/DiscoverData'; import { ExperienceItem } from './ExperienceItem'; @@ -26,12 +26,12 @@ const ENLARGE_COEFFICIENTS = 2; @Component export struct ExperienceCard { - @StorageProp('GlobalInfoModel') @Watch('calculateItemWidth') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('calculateItemWidth') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop @Require discoverContents: DiscoverContent[]; handleItemClick?: Function; componentWidth: number = this.globalInfoModel.deviceWidth; - scroller: Scroller = new Scroller() + scroller: Scroller = new Scroller(); @State enlargeIndex: number = -1; @State itemWidth: number = 0; @@ -47,7 +47,7 @@ export struct ExperienceCard { } onHoverAction(isHover: boolean, index: number) { - animateTo({ curve: curves.interpolatingSpring(0, 1, 288, 30) }, () => { + this.getUIContext().animateTo({ curve: curves.interpolatingSpring(0, 1, 288, 30) }, () => { if (isHover && this.enlargeIndex !== index) { const currentOffsetX: number = this.scroller.currentOffset().xOffset; // Items at the edge of the screen are not processed. @@ -102,7 +102,10 @@ export struct ExperienceCard { } else { Swiper() { ForEach(this.discoverContents, (discoverContent: DiscoverContent) => { - ExperienceItem({ discoverContent: discoverContent }) + ExperienceItem({ + discoverContent: discoverContent, + hasPadding: this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.SM, + }) .onClick(() => { this.handleItemClick?.(discoverContent); }) diff --git a/features/exploration/src/main/ets/component/ExperienceItem.ets b/features/exploration/src/main/ets/component/ExperienceItem.ets index 277166921b8262709d56e6f05fec6d80d72d3278..6ea5e902a3dde8a87c7e51a0f2873a6a6086b265 100644 --- a/features/exploration/src/main/ets/component/ExperienceItem.ets +++ b/features/exploration/src/main/ets/component/ExperienceItem.ets @@ -20,6 +20,7 @@ import type { DiscoverContent } from '../model/DiscoverData'; @Component export struct ExperienceItem { @Prop discoverContent: DiscoverContent; + @Prop hasPadding: boolean = false; @State bgTopColor: string = ''; @State bgBottomColor: string = ''; @@ -51,7 +52,7 @@ export struct ExperienceItem { .padding({ left: $r('sys.float.padding_level8'), right: $r('sys.float.padding_level8'), - bottom: $r('sys.float.padding_level8'), + bottom: this.hasPadding ? $r('sys.float.corner_radius_level16') : $r('sys.float.padding_level8'), top: $r('sys.float.padding_level6'), }) .height($r('app.float.img_card_content_height')) diff --git a/features/exploration/src/main/ets/component/FeedCard.ets b/features/exploration/src/main/ets/component/FeedCard.ets index a4530732d21a04e9c4df80fca8147b830a173fcc..40846ae6f83778cba7db104c4fd8cf72ff6b2616 100644 --- a/features/exploration/src/main/ets/component/FeedCard.ets +++ b/features/exploration/src/main/ets/component/FeedCard.ets @@ -13,14 +13,14 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import type { DiscoverContent } from '../model/DiscoverData'; import { FeedItem } from './FeedItem'; @Component export struct FeedCard { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop @Require discoverContents: DiscoverContent[]; handleItemClick?: Function; diff --git a/features/exploration/src/main/ets/component/FeedItem.ets b/features/exploration/src/main/ets/component/FeedItem.ets index ca35c51304bb5fb135b968eac48ba0029a1fb595..0800de6264645882e3d066f133aec961a04a8ab7 100644 --- a/features/exploration/src/main/ets/component/FeedItem.ets +++ b/features/exploration/src/main/ets/component/FeedItem.ets @@ -13,13 +13,13 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType } from '@ohos/common'; import type { DiscoverContent } from '../model/DiscoverData'; @Component export struct FeedItem { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop discoverContent: DiscoverContent; build() { diff --git a/features/exploration/src/main/ets/view/ArticleDetailView.ets b/features/exploration/src/main/ets/view/ArticleDetailView.ets index 3de2ef0394182468e80cba840e0568d3a6aa3d1b..cdf567e9a8ad1241b80d84609b88da8c0ea10ec4 100644 --- a/features/exploration/src/main/ets/view/ArticleDetailView.ets +++ b/features/exploration/src/main/ets/view/ArticleDetailView.ets @@ -91,7 +91,11 @@ struct ArticleDetailView { } popAction(isAnimation: boolean) { - this.webController.onInactive(); + try { + this.webController.onInactive(); + } catch { + Logger.error(TAG, `PopAction onInactive failed.`); + } this.viewModel.sendEvent({ type: ExplorationDetailEventType.POP, param: { animation: isAnimation, tabBarView: -1 }, diff --git a/features/exploration/src/main/ets/view/BannerDetailView.ets b/features/exploration/src/main/ets/view/BannerDetailView.ets index 6c4490e662e2c73c4ae2a2ca3d21b7d9361e7536..2f583d6da4b7d33391f73f493507ca25bb12a75d 100644 --- a/features/exploration/src/main/ets/view/BannerDetailView.ets +++ b/features/exploration/src/main/ets/view/BannerDetailView.ets @@ -98,7 +98,7 @@ struct BannerDetailView { popAction(isAnimation: boolean) { this.isPopTransition = true; this.isChangePage = true; - animateTo({ + this.getUIContext().animateTo({ curve: curves.interpolatingSpring(0, 1, 363, 38), }, () => { WebUtil.getWebController(this.discoverContent.detailsUrl)?.onInactive(); diff --git a/features/exploration/src/main/ets/view/ExplorationView.ets b/features/exploration/src/main/ets/view/ExplorationView.ets index 2327cd797af698ab5ee84c59197b6ec31d4ea952..93ccac7647f15cfe32a3ceb15489a7d092fb8338 100644 --- a/features/exploration/src/main/ets/view/ExplorationView.ets +++ b/features/exploration/src/main/ets/view/ExplorationView.ets @@ -14,7 +14,7 @@ */ import { ConfigurationConstant } from '@kit.AbilityKit'; -import type { GlobalInfoModel, PageContext } from '@ohos/common'; +import { GlobalInfoModel, PageContext, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import type { BannerData } from '@ohos/commonbusiness'; import { @@ -38,13 +38,13 @@ import { ExplorationEventType, ExplorationViewModel } from '../viewmodel/Explora @Component({ freezeWhenInactive: true }) export struct ExplorationView { viewModel: ExplorationViewModel = ExplorationViewModel.getInstance(); - @StorageProp('GlobalInfoModel') @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = - AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) @Watch('handleBreakPointChange') globalInfoModel: GlobalInfoModel = + AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @State explorationState: ExplorationState = this.viewModel.getState(); private listScroller: Scroller = new Scroller(); - private explorationPageContext: PageContext = AppStorage.get('explorationPageContext')!; + private explorationPageContext: PageContext = AppStorage.get(StorageKey.EXPLORATION_PAGE_CONTEXT)!; aboutToAppear(): void { this.viewModel.sendEvent({ type: ExplorationEventType.LOAD_DISCOVERY_PAGE, param: null }); diff --git a/features/exploration/src/main/ets/viewmodel/ArticleDetailViewModel.ets b/features/exploration/src/main/ets/viewmodel/ArticleDetailViewModel.ets index 930a1aa77d1b2142b148aad03f4b4cb683575b5a..2ee321019e7a86a65ae6fe16f955b55f2a27df30 100644 --- a/features/exploration/src/main/ets/viewmodel/ArticleDetailViewModel.ets +++ b/features/exploration/src/main/ets/viewmodel/ArticleDetailViewModel.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseVM, BreakpointTypeEnum, GlobalInfoModel, LoadingStatus, PageContext } from '@ohos/common'; +import { BaseVM, BreakpointTypeEnum, GlobalInfoModel, LoadingStatus, PageContext, StorageKey } from '@ohos/common'; import { ComponentDetailParams, SampleDetailParams, TabBarType } from '@ohos/commonbusiness'; import type { DiscoverContent } from '../model/DiscoverData'; import { ExplorationDetailState } from './ExplorationDetailState'; @@ -45,15 +45,15 @@ export class ArticleDetailViewModel extends BaseVM { } private pop(animated: boolean = true, tabBarView: number = TabBarType.HOME): void { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - let currentPathStack: PageContext = AppStorage.get('pageContext') as PageContext; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + let currentPathStack: PageContext = AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; if (globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { if (tabBarView === TabBarType.HOME) { - currentPathStack = AppStorage.get('componentListPageContext')!; + currentPathStack = AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT)!; } else if (tabBarView === TabBarType.SAMPLE) { - currentPathStack = AppStorage.get('samplePageContext')!; + currentPathStack = AppStorage.get(StorageKey.SAMPLE_PAGE_CONTEXT)!; } else { - currentPathStack = AppStorage.get('explorationPageContext')!; + currentPathStack = AppStorage.get(StorageKey.EXPLORATION_PAGE_CONTEXT)!; } } currentPathStack.popPage(animated); @@ -61,15 +61,15 @@ export class ArticleDetailViewModel extends BaseVM { private jumpNativePage(param: NativePageParam): void { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - let pageContext: PageContext = AppStorage.get('pageContext') as PageContext; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + let pageContext: PageContext = AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; if (globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { if (param.tabBarView === TabBarType.HOME) { - pageContext = AppStorage.get('componentListPageContext') as PageContext; + pageContext = AppStorage.get(StorageKey.COMPONENT_PAGE_CONTEXT) as PageContext; } else if (param.tabBarView === TabBarType.SAMPLE) { - pageContext = AppStorage.get('samplePageContext') as PageContext; + pageContext = AppStorage.get(StorageKey.SAMPLE_PAGE_CONTEXT) as PageContext; } else { - pageContext = AppStorage.get('explorationPageContext') as PageContext; + pageContext = AppStorage.get(StorageKey.EXPLORATION_PAGE_CONTEXT) as PageContext; } } pageContext.openPage({ diff --git a/features/exploration/src/main/ets/viewmodel/ExplorationViewModel.ets b/features/exploration/src/main/ets/viewmodel/ExplorationViewModel.ets index 136b239e179d1bccb01a8d9c31f5fd2178bb8e41..b4fd87207d036e2f474f89580cdbc073f9e92139 100644 --- a/features/exploration/src/main/ets/viewmodel/ExplorationViewModel.ets +++ b/features/exploration/src/main/ets/viewmodel/ExplorationViewModel.ets @@ -15,7 +15,7 @@ import { ConfigurationConstant } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointTypeEnum, LoadingStatus, @@ -68,11 +68,11 @@ export class ExplorationViewModel extends BaseHomeViewModel { } protected loadDiscoverList(): void { - const isDark: boolean = AppStorage.get('systemColorMode') === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; + const isDark: boolean = AppStorage.get(StorageKey.COLOR_MODE) === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; this.state.loadingModel.loadingStatus = LoadingStatus.LOADING; this.state.topNavigationData.titleColor = isDark ? StatusBarColorType.WHITE : StatusBarColorType.BLACK; this.state.topNavigationData.isBlur = false; - WindowUtil.updateStatusBarColor(getContext(), isDark); + WindowUtil.updateStatusBarColor(isDark); this.model.getDiscoveryPage() .then((result: DiscoverData) => { result.bannerInfos?.forEach((item: BannerData) => { @@ -80,18 +80,18 @@ export class ExplorationViewModel extends BaseHomeViewModel { }); this.state.bannerState.bannerResource.setDataArray([...(result.bannerInfos || [])]); this.state.discoveryData = result.discoveryData; - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; if (globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.LG && globalInfoModel.currentBreakpoint !== BreakpointTypeEnum.XL) { this.state.topNavigationData.titleColor = StatusBarColorType.WHITE; - WindowUtil.updateStatusBarColor(getContext(), true); + WindowUtil.updateStatusBarColor(true); TAB_CONTENT_STATUSES[TabBarType.PRACTICE] = true; } this.state.loadingModel.loadingStatus = LoadingStatus.SUCCESS; Logger.info(TAG, `Request DiscoveryPage Success`); }) .catch((error: BusinessError) => { - WindowUtil.updateStatusBarColor(getContext(), isDark); + WindowUtil.updateStatusBarColor(isDark); TAB_CONTENT_STATUSES[TabBarType.PRACTICE] = isDark; if (error.code === RequestErrorCode.ERROR_NETWORK_CONNECT_FAILED) { this.state.loadingModel.loadingStatus = LoadingStatus.NO_NETWORK; @@ -102,10 +102,10 @@ export class ExplorationViewModel extends BaseHomeViewModel { } protected jumpDetailView(content: DiscoverContent): void { - const globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - const pathStack: PageContext = - globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? AppStorage.get('explorationPageContext')! : - AppStorage.get('pageContext') as PageContext; + const globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + const pathStack: PageContext = globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL ? + AppStorage.get(StorageKey.EXPLORATION_PAGE_CONTEXT)! : + AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; const articleParam: ArticleDetailParams = { id: content.id, isArticle: true, diff --git a/features/mine/src/main/ets/component/AboutItemCard.ets b/features/mine/src/main/ets/component/AboutItemCard.ets index 732a1e8d4e766f5a6c2a549b0a0983058b5d60d5..a755f7fe20b8e6f2def15a55aff5f26b0a6797be 100644 --- a/features/mine/src/main/ets/component/AboutItemCard.ets +++ b/features/mine/src/main/ets/component/AboutItemCard.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { BundleInfoData } from '@ohos/common'; +import { BundleInfoData, StorageKey } from '@ohos/common'; import type { AboutState } from '../viewmodel/AboutState'; import { AboutVM, CheckVersionEvent, UpdateVersionEvent } from '../viewmodel/AboutVM'; @@ -48,7 +48,7 @@ export struct AboutItemCard { .fontColor($r('sys.color.font_primary')) } - Text(AppStorage.get('BundleInfoData')?.versionName as string) + Text(AppStorage.get(StorageKey.BUNDLE_INFO)?.versionName as string) .margin({ top: $r('sys.float.padding_level2') }) .fontWeight(FontWeight.Regular) .fontSize($r('sys.float.Subtitle_S')) diff --git a/features/mine/src/main/ets/component/CardItem.ets b/features/mine/src/main/ets/component/CardItem.ets index ce068fc4b4ddbc689c19191f4c63561e4e2f3705..f0236320e34ad52784398f27714c90ea432b3cdc 100644 --- a/features/mine/src/main/ets/component/CardItem.ets +++ b/features/mine/src/main/ets/component/CardItem.ets @@ -13,13 +13,13 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointTypeEnum, CommonConstants } from '@ohos/common'; import { AboutBuilder } from '../view/AboutView'; @Component export struct CardItem { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; @Prop isShow: boolean; textContent?: Resource; symbolSrc?: Resource; diff --git a/features/mine/src/main/ets/view/MineView.ets b/features/mine/src/main/ets/view/MineView.ets index 699f3275242cedf1edc498c7a2383616e1be3366..a057bf496489c8835e9fd4381cf78fae42ae0794 100644 --- a/features/mine/src/main/ets/view/MineView.ets +++ b/features/mine/src/main/ets/view/MineView.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, BreakpointTypeEnum, CommonConstants, TopNavigationView } from '@ohos/common'; import { AboutBindSheetEvent, MinePageVM } from '../viewmodel/MinePageVM'; import { MinePageState } from '../viewmodel/MinePageState'; @@ -23,7 +23,7 @@ import { CardItem } from '../component/CardItem'; export struct MineView { viewModel: MinePageVM = MinePageVM.getInstance(); @State minePageState: MinePageState = this.viewModel.getState(); - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; throttle(func: Function, interval: number) { let lastTime = 0; diff --git a/features/mine/src/main/ets/viewmodel/AboutVM.ets b/features/mine/src/main/ets/viewmodel/AboutVM.ets index b8bf718b30fa17cb5cb36f7f560793c976e530dc..ba46c6bb936e1702bdb20396e785682494454906 100644 --- a/features/mine/src/main/ets/viewmodel/AboutVM.ets +++ b/features/mine/src/main/ets/viewmodel/AboutVM.ets @@ -15,7 +15,7 @@ import type { common, Want } from '@kit.AbilityKit'; import type { BusinessError } from '@kit.BasicServicesKit'; -import type { BundleInfoData } from '@ohos/common'; +import { BundleInfoData, StorageKey } from '@ohos/common'; import { BaseVM, BaseVMEvent, ConfigMapKey, Logger, ResourceUtil, UpdateService } from '@ohos/common'; import { AboutState } from './AboutState'; @@ -42,7 +42,8 @@ export class AboutVM extends BaseVM { } else if (event instanceof UpdateVersionEvent) { this.updateVersion(); } else if (event instanceof ViewRegistrationInfoEvent) { - const context: common.UIAbilityContext = getContext() as common.UIAbilityContext; + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; this.jumpToBrowser(context); } } @@ -50,7 +51,7 @@ export class AboutVM extends BaseVM { private checkVersion(): void { this.updateService.checkUpdate().then((existNewVersion: boolean) => { this.state.laterVersionExist = existNewVersion; - this.state.currentVersion = AppStorage.get('BundleInfoData')?.versionName as string; + this.state.currentVersion = AppStorage.get(StorageKey.BUNDLE_INFO)?.versionName as string; }); } @@ -62,10 +63,11 @@ export class AboutVM extends BaseVM { } private jumpToBrowser(context: common.UIAbilityContext): void { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; const want: Want = { action: 'ohos.want.action.viewData', entities: ['entity.system.browsable'], - uri: ResourceUtil.getRawFileStringByKey(getContext(), ConfigMapKey.MIIT_URL), + uri: ResourceUtil.getRawFileStringByKey(uiContext.getHostContext() as Context, ConfigMapKey.MIIT_URL), }; context.startAbility(want) .then(() => { diff --git a/features/mine/src/main/resources/base/media/app_icon.png b/features/mine/src/main/resources/base/media/app_icon.png index 99bd6a94a18cb81bd8a0af3329eec20cb4748c7c..a83bff5728efffd65851ab961c1fbce5cab09889 100644 Binary files a/features/mine/src/main/resources/base/media/app_icon.png and b/features/mine/src/main/resources/base/media/app_icon.png differ diff --git a/products/phone/src/main/ets/component/CustomSideBar.ets b/products/phone/src/main/ets/component/CustomSideBar.ets index 2fde41c6d51ddddb7fd780f55ce630e533d5ab39..624e30b0793a22f2bdb5f24b508f80a8bfd20f6b 100644 --- a/products/phone/src/main/ets/component/CustomSideBar.ets +++ b/products/phone/src/main/ets/component/CustomSideBar.ets @@ -64,7 +64,7 @@ export struct CustomSideBar { .aspectRatio(1) .borderRadius($r('sys.float.corner_radius_level4')) .margin({ right: $r('sys.float.padding_level6') }) - Text($r('app.string.EntryAbility_label')) + Text($r('app.string.HMOSAbility_label')) .fontColor($r('sys.color.font_primary')) .fontSize($r('sys.float.Body_L')) } diff --git a/products/phone/src/main/ets/component/CustomTabBar.ets b/products/phone/src/main/ets/component/CustomTabBar.ets index 924d4b9283270d6ee1d709ed36e4ac050a157100..763f5f0467ce8b7ae88024344e2a5999c91de2bc 100644 --- a/products/phone/src/main/ets/component/CustomTabBar.ets +++ b/products/phone/src/main/ets/component/CustomTabBar.ets @@ -13,15 +13,15 @@ * limitations under the License. */ -import type { GlobalInfoModel } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; import { BreakpointType, CommonConstants } from '@ohos/common'; import type { TabBarData } from '../model/TabBarModel'; import { TABS_LIST } from '../model/TabBarModel'; @Component export struct CustomTabBar { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - @StorageProp('BlurRenderGroup') blurRenderGroup: boolean = false; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.BLUE_RENDER_GROUP) blurRenderGroup: boolean = false; @Prop @Require currentIndex: number; tabBarChange: (index: number) => void = (index: number) => { }; diff --git a/products/phone/src/main/ets/entryability/EntryAbility.ets b/products/phone/src/main/ets/entryability/EntryAbility.ets index 9f252b274c777d08d714d0f66183cf1e7daf070b..38d7c7f23ba4397271320d209606cc378abf6ae5 100644 --- a/products/phone/src/main/ets/entryability/EntryAbility.ets +++ b/products/phone/src/main/ets/entryability/EntryAbility.ets @@ -16,21 +16,33 @@ import { AbilityConstant, Configuration, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; -import { BundleManagerUtil, Logger, PageContext, WindowUtil, DynamicInstallManager, WebUtil } from '@ohos/common'; +import { + BundleManagerUtil, + Logger, + PageContext, + WindowUtil, + DynamicInstallManager, + WebUtil, + StorageKey, +} from '@ohos/common'; import GlobalUIAbilityContext from '../util/ContextConfig'; const TAG = '[EntryAbility]'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - Logger.info(TAG, 'Ability onCreate'); + Logger.info(TAG, `Ability onCreate launchReason: ${launchParam.launchReason}`); this.checkAndHandleParams(want); - AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode); - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + AppStorage.setOrCreate(StorageKey.COLOR_MODE, this.context.config.colorMode); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch { + Logger.error(TAG, `onCreate setColorMode failed`); + } } onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { - Logger.info(TAG, `onNewWant`); + Logger.info(TAG, `onNewWant launchReason: ${launchParam.launchReason}`); this.checkAndHandleParams(want); } @@ -55,21 +67,18 @@ export default class EntryAbility extends UIAbility { Logger.info(TAG, 'Ability onWindowStageCreate'); // Use for penkit component GlobalUIAbilityContext.setContext(this.context); - WindowUtil.requestFullScreen(windowStage, this.context); - WindowUtil.registerBreakPoint(windowStage); BundleManagerUtil.getBundleInfo(); - AppStorage.setOrCreate('pageContext', new PageContext()); - AppStorage.setOrCreate('samplePageContext', new PageContext()); - AppStorage.setOrCreate('componentListPageContext', new PageContext()); - AppStorage.setOrCreate('explorationPageContext', new PageContext()); + AppStorage.setOrCreate(StorageKey.HOME_PAGE_CONTEXT, new PageContext()); + AppStorage.setOrCreate(StorageKey.SAMPLE_PAGE_CONTEXT, new PageContext()); + AppStorage.setOrCreate(StorageKey.COMPONENT_PAGE_CONTEXT, new PageContext()); + AppStorage.setOrCreate(StorageKey.EXPLORATION_PAGE_CONTEXT, new PageContext()); windowStage.loadContent('page/SplashPage', (err: BusinessError) => { WebUtil.initialize(windowStage); + WindowUtil.initialize(windowStage); if (err.code) { Logger.error(TAG, `Failed to load the content. Cause: ${err.code} ${err.message}`); return; } - // Hide PC/2in1 title bar after loadContent success. - WindowUtil.hideTitleBar(windowStage); Logger.info(TAG, 'Succeeded in loading the content.'); }); } @@ -77,10 +86,10 @@ export default class EntryAbility extends UIAbility { onConfigurationUpdate(newConfig: Configuration): void { const newColorMode: ConfigurationConstant.ColorMode = newConfig.colorMode || ConfigurationConstant.ColorMode.COLOR_MODE_DARK; - const currentColorMode = AppStorage.get('systemColorMode'); + const currentColorMode = AppStorage.get(StorageKey.COLOR_MODE); // When the system dark/light color mode is different form the app color mode,modify the app's color mode. if (newColorMode !== currentColorMode) { - AppStorage.setOrCreate('systemColorMode', newColorMode); + AppStorage.setOrCreate(StorageKey.COLOR_MODE, newColorMode); } } diff --git a/products/phone/src/main/ets/page/MainPage.ets b/products/phone/src/main/ets/page/MainPage.ets index 9b96778560db911566dc9ee30b8c910b2c0cee4c..d6f105cf9baa13f6879640bc21cfb49e5d65d061 100644 --- a/products/phone/src/main/ets/page/MainPage.ets +++ b/products/phone/src/main/ets/page/MainPage.ets @@ -15,9 +15,8 @@ import type { common } from '@kit.AbilityKit'; import { ConfigurationConstant } from '@kit.AbilityKit'; -import { promptAction } from '@kit.ArkUI'; -import type { GlobalInfoModel } from '@ohos/common'; -import { BreakpointTypeEnum, CommonConstants, ProcessUtil, WindowUtil } from '@ohos/common'; +import { GlobalInfoModel, StorageKey } from '@ohos/common'; +import { BreakpointTypeEnum, CommonConstants, ProcessUtil, Toast, WindowUtil } from '@ohos/common'; import { TAB_CONTENT_STATUSES, TabBarType } from '@ohos/commonbusiness'; import { ComponentListView } from '@ohos/componentlibrary'; import { PracticesView } from '@ohos/devpractices'; @@ -35,9 +34,9 @@ export function MainPageBuilder() { @Component({ freezeWhenInactive: true }) struct MainPage { - @StorageProp('GlobalInfoModel') globalInfoModel: GlobalInfoModel = AppStorage.get('GlobalInfoModel')!; - @StorageProp('systemColorMode') @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = - AppStorage.get('systemColorMode')!; + @StorageProp(StorageKey.GLOBAL_INFO) globalInfoModel: GlobalInfoModel = AppStorage.get(StorageKey.GLOBAL_INFO)!; + @StorageProp(StorageKey.COLOR_MODE) @Watch('handleColorModeChange') systemColorMode: ConfigurationConstant.ColorMode = + AppStorage.get(StorageKey.COLOR_MODE)!; @State currentIndex: number = 0; private tabController: TabsController = new TabsController(); private backPressTime: number = 0; @@ -83,29 +82,29 @@ struct MainPage { } aboutToAppear(): void { - AppStorage.setOrCreate('currentTabIndex', 0); + AppStorage.setOrCreate(StorageKey.CURRENT_TAB, 0); } onBackPress(): boolean { const newTime = new Date().getTime(); if (this.backPressTime && newTime - this.backPressTime < PRESS_TIME) { - ProcessUtil.moveAbilityToBackground(getContext(this) as common.UIAbilityContext); + ProcessUtil.moveAbilityToBackground(this.getUIContext().getHostContext() as common.UIAbilityContext); return false; } this.backPressTime = newTime; - promptAction.showToast({ message: $r('app.string.back_toast'), duration: PRESS_TIME }); + Toast.showToast($r('app.string.back_toast')); return true; } changeTabStatus(index: number) { - AppStorage.setOrCreate('currentTabIndex', index); + AppStorage.setOrCreate(StorageKey.CURRENT_TAB, index); const selectedIndex = index; const isSystemDark: boolean = (this.systemColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); if (selectedIndex === TabBarType.MINE || this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.LG || this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) { - WindowUtil.updateStatusBarColor(getContext(this), isSystemDark); + WindowUtil.updateStatusBarColor(isSystemDark); } else { - WindowUtil.updateStatusBarColor(getContext(this), isSystemDark || TAB_CONTENT_STATUSES[selectedIndex]); + WindowUtil.updateStatusBarColor(isSystemDark || TAB_CONTENT_STATUSES[selectedIndex]); } } @@ -137,6 +136,7 @@ struct MainPage { Visibility.Visible) } } + .autoHide(false) .showSideBar(this.globalInfoModel.currentBreakpoint === BreakpointTypeEnum.XL) .showControlButton(false) } @@ -151,11 +151,11 @@ struct MainPage { this.isShown = true; this.handleColorModeChange(); CommonConstants.PROMISE_WAIT(500).then(() => { - AppStorage.setOrCreate('BlurRenderGroup', false); + AppStorage.setOrCreate(StorageKey.BLUE_RENDER_GROUP, false); }) }) .onHidden(() => { - AppStorage.setOrCreate('BlurRenderGroup', true); + AppStorage.setOrCreate(StorageKey.BLUE_RENDER_GROUP, true); this.isShown = false; }) .height('100%') diff --git a/products/phone/src/main/ets/page/SplashPage.ets b/products/phone/src/main/ets/page/SplashPage.ets index f0f37c1c1a7e3a5d345cfa09a5b1bfa1bc9e2701..eeed6bef73e9a8f42d55e30ae278ffc84d51c9c7 100644 --- a/products/phone/src/main/ets/page/SplashPage.ets +++ b/products/phone/src/main/ets/page/SplashPage.ets @@ -14,7 +14,7 @@ */ import { ConfigurationConstant } from '@kit.AbilityKit'; -import { CommonConstants, Logger, PageContext, WindowUtil, } from '@ohos/common'; +import { CommonConstants, Logger, PageContext, StorageKey, WindowUtil, } from '@ohos/common'; import { SplashEventTypeEnum, SplashViewModel } from '../viewmodel/SplashViewModel'; const TAG: string = '[SplashPage]'; @@ -22,20 +22,21 @@ const TAG: string = '[SplashPage]'; @Entry @Component struct SplashPage { - private pageContext: PageContext = AppStorage.get('pageContext') as PageContext; + private pageContext: PageContext = AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; private appPathInfo: NavPathStack = this.pageContext.navPathStack; private viewModel: SplashViewModel = new SplashViewModel(); onPageHide() { Logger.info(TAG, 'onPageHide'); - WindowUtil.updateStatusBarColor(getContext(this), - AppStorage.get('systemColorMode') === ConfigurationConstant.ColorMode.COLOR_MODE_DARK); + const isSystemDark: boolean = + AppStorage.get(StorageKey.COLOR_MODE) === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; + WindowUtil.updateStatusBarColor(isSystemDark); } aboutToAppear(): void { - WindowUtil.updateStatusBarColor(getContext(this), true); + WindowUtil.updateStatusBarColor(true); this.viewModel.sendEvent(SplashEventTypeEnum.CHECK_FIRST_START); - animateTo({ + this.getUIContext().animateTo({ delay: CommonConstants.ANIMATION_DELAY, duration: CommonConstants.ANIMATION_DURATION, onFinish: () => { diff --git a/products/phone/src/main/ets/viewmodel/SplashViewModel.ets b/products/phone/src/main/ets/viewmodel/SplashViewModel.ets index d708ca64b0da3b89206694e13a19f2c26a9d618f..e0d96733284dadf4e57e70a280669828e530e3de 100644 --- a/products/phone/src/main/ets/viewmodel/SplashViewModel.ets +++ b/products/phone/src/main/ets/viewmodel/SplashViewModel.ets @@ -14,7 +14,7 @@ */ import type { BusinessError } from '@kit.BasicServicesKit'; -import { BaseState, BaseVM, Logger, PageContext, PreferenceManager } from '@ohos/common'; +import { BaseState, BaseVM, Logger, PageContext, PreferenceManager, StorageKey } from '@ohos/common'; import { DiscoverModel } from '@ohos/exploration'; import { ComponentListModel } from '@ohos/componentlibrary'; import { SampleModel } from '@ohos/devpractices'; @@ -22,7 +22,7 @@ import { SampleModel } from '@ohos/devpractices'; const TAG: string = '[SplashViewModel]'; export class SplashViewModel extends BaseVM { - private pageContext: PageContext = AppStorage.get('pageContext') as PageContext; + private pageContext: PageContext = AppStorage.get(StorageKey.HOME_PAGE_CONTEXT) as PageContext; private componentListModel: ComponentListModel = ComponentListModel.getInstance(); private sampleModel: SampleModel = SampleModel.getInstance(); private discoverModel: DiscoverModel = DiscoverModel.getInstance(); diff --git a/products/phone/src/main/module.json5 b/products/phone/src/main/module.json5 index bbcd6677c2b32bea2f695a4b1bd3d320d7e702e9..8dee2fb695bac287064588e108f0703fbe706b7a 100644 --- a/products/phone/src/main/module.json5 +++ b/products/phone/src/main/module.json5 @@ -13,13 +13,19 @@ "installationFree": false, "pages": "$profile:main_pages", "routerMap": "$profile:router_map", + "metadata": [ + { + "name": "client_id", + "value": "112510453", + } + ], "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ets", "description": "$string:EntryAbility_desc", - "icon": "$media:layered_image", - "label": "$string:EntryAbility_label", + "icon": "$media:hmos_layered_image", + "label": "$string:HMOSAbility_label", "startWindowIcon": "$media:ic_start_icon_800", "startWindowBackground": "$color:start_window_background", "exported": true, diff --git a/products/phone/src/main/resources/base/element/string.json b/products/phone/src/main/resources/base/element/string.json index 98eb03e515534f4eb147bfe835788519f3afe19b..75cf17eb08551678073f4e75d7153b49e1f16e26 100644 --- a/products/phone/src/main/resources/base/element/string.json +++ b/products/phone/src/main/resources/base/element/string.json @@ -9,7 +9,7 @@ "value": "description" }, { - "name": "EntryAbility_label", + "name": "HMOSAbility_label", "value": "Sample in HarmonyOS" }, { diff --git a/products/phone/src/main/resources/base/media/hmos_layered_image.json b/products/phone/src/main/resources/base/media/hmos_layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..ab180cdfef55bcd5248e3aef53bad8d621a6443a --- /dev/null +++ b/products/phone/src/main/resources/base/media/hmos_layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:ic_background", + "foreground" : "$media:ic_foreground" + } +} \ No newline at end of file diff --git a/products/phone/src/main/resources/base/media/ic_foreground.png b/products/phone/src/main/resources/base/media/ic_foreground.png index 633d7243b55c07163b416bef06b83b630a6696f4..3cc9e44f965c521a46fad6660b7fe6d091f45418 100644 Binary files a/products/phone/src/main/resources/base/media/ic_foreground.png and b/products/phone/src/main/resources/base/media/ic_foreground.png differ diff --git a/products/phone/src/main/resources/base/media/ic_start_icon.png b/products/phone/src/main/resources/base/media/ic_start_icon.png index 99bd6a94a18cb81bd8a0af3329eec20cb4748c7c..a83bff5728efffd65851ab961c1fbce5cab09889 100644 Binary files a/products/phone/src/main/resources/base/media/ic_start_icon.png and b/products/phone/src/main/resources/base/media/ic_start_icon.png differ diff --git a/products/phone/src/main/resources/en_US/element/string.json b/products/phone/src/main/resources/en_US/element/string.json index 98eb03e515534f4eb147bfe835788519f3afe19b..75cf17eb08551678073f4e75d7153b49e1f16e26 100644 --- a/products/phone/src/main/resources/en_US/element/string.json +++ b/products/phone/src/main/resources/en_US/element/string.json @@ -9,7 +9,7 @@ "value": "description" }, { - "name": "EntryAbility_label", + "name": "HMOSAbility_label", "value": "Sample in HarmonyOS" }, { diff --git a/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_grid_hybrid.png b/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_grid_hybrid.png index 31237e3e680060fb1605c6d05919b8ce1c90b575..10e98c19e3699850df680f098e32768e7a5bfe2d 100644 Binary files a/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_grid_hybrid.png and b/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_grid_hybrid.png differ diff --git a/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_water_flow.png b/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_water_flow.png index 9b23af1962d259ffd7d05643f27dc048451509e2..6d77b8c8ca67a2c205cc76c0c2b16765361f17da 100644 Binary files a/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_water_flow.png and b/products/phone/src/main/resources/rawfile/image/sample/arkui/layout/sample_water_flow.png differ diff --git a/products/phone/src/main/resources/rawfile/image/sample/arkui/list/sample_list_item_edit.png b/products/phone/src/main/resources/rawfile/image/sample/arkui/list/sample_list_item_edit.png index 2ef0de92d72c8c0b32b4d634c178f9cc8bca3b68..640eba59016f5edd8c9ce0cc135e98c882e82fb1 100644 Binary files a/products/phone/src/main/resources/rawfile/image/sample/arkui/list/sample_list_item_edit.png and b/products/phone/src/main/resources/rawfile/image/sample/arkui/list/sample_list_item_edit.png differ diff --git a/products/phone/src/main/resources/rawfile/image/sample/arkui/style/sample_custom_dialog_gathers.png b/products/phone/src/main/resources/rawfile/image/sample/arkui/style/sample_custom_dialog_gathers.png index 7d3799a82b1287526fe046e34e8bb9937d91ebf0..d67a6e4662361f1941b302e2f4e255e45b9a1b4f 100644 Binary files a/products/phone/src/main/resources/rawfile/image/sample/arkui/style/sample_custom_dialog_gathers.png and b/products/phone/src/main/resources/rawfile/image/sample/arkui/style/sample_custom_dialog_gathers.png differ diff --git a/products/phone/src/main/resources/resfile/articlecols/articles/design-animation/index.html b/products/phone/src/main/resources/resfile/articlecols/articles/design-animation/index.html index ec49340714e6fac775f8ff06f8d6939048002414..fd329ef837a49be10f22f0c41cafe9518e33863b 100644 --- a/products/phone/src/main/resources/resfile/articlecols/articles/design-animation/index.html +++ b/products/phone/src/main/resources/resfile/articlecols/articles/design-animation/index.html @@ -40,8 +40,6 @@

运动一致

  • 在动作编排时应遵循运动路径方式一致
  • 不一致的运动会分散用户视觉焦点
  • 运用适当的编排手法,引导用户聚焦操作任务
图1-7
- -
@@ -49,7 +47,8 @@ href="article_uxanimation_1" target="_blank" rel="noopener noreferrer">UX设计指南-动效。

-
+ + diff --git a/products/phone/src/main/resources/resfile/articlecols/articles/layered-architecture-design/index.html b/products/phone/src/main/resources/resfile/articlecols/articles/layered-architecture-design/index.html index a20b976f3ce4ffff554d596bfd27706fcb5d29b2..7823ee5067d795c9d989b4f18bf08c1a89b1283c 100644 --- a/products/phone/src/main/resources/resfile/articlecols/articles/layered-architecture-design/index.html +++ b/products/phone/src/main/resources/resfile/articlecols/articles/layered-architecture-design/index.html @@ -226,7 +226,7 @@

2. 对于多Hap场景,如果多Hap之间没有公用的资产,直接采用Hap+Har方式;反之多Hap之间有公共资产时,可以考虑将公共资产打包成Hsp。

3. Hsp包在运行时需动态加载执行,可能会导致性能问题。

-

4. 多包(Hap/Hsp)引用相同的Har时,会造成多宝间的代码和资源重复拷贝,导致应用包体积过大。

+

4. 多包(Hap/Hsp)引用相同的Har时,会造成多包间的代码和资源重复拷贝,导致应用包体积过大。

以上三种场景均有相关Sample代码:代码地址,实况窗更加丰富内容可以参考Live View Kit-实现多场景实况窗展示功能,实况窗更加丰富内容可以参考实况窗服务文章。

diff --git a/products/phone/src/main/resources/resfile/articlecols/common/config/articleUrlConfig.json b/products/phone/src/main/resources/resfile/articlecols/common/config/articleUrlConfig.json index 84d5ac172bd8f2f181e5b44ca2f298b5b20badd4..5c2e69743aca1440fd0ebb2fd44487e95f174a31 100644 --- a/products/phone/src/main/resources/resfile/articlecols/common/config/articleUrlConfig.json +++ b/products/phone/src/main/resources/resfile/articlecols/common/config/articleUrlConfig.json @@ -10,21 +10,21 @@ "continue_9": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-continuation-guide", "continue_10": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_NEXT-DistributedMail", "layer_1": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/store-moduleinstall_arkts", - "layer_2": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/foreword", + "layer_2": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/foreword", "liveview_1": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/liveview-introduction#section4266105713209", "liveview_2": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/liveview-design-formula#section19663288592", "liveview_3": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/liveview-design-formula#section168541692013", "liveview_4": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/liveview-design-formula#section887024865911", "liveview_5": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/live-view-kit-guide", "multidevice_1": "https://developer.huawei.com/consumer/cn/doc/design-guides/design-concepts-0000001795698445", - "multidevice_2": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/introduction#工程结构", + "multidevice_2": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-overview#section516822912543", "multidevice_3": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/page-development", "multidevice_4": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/adaptive-layout", "multidevice_5": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/responsive-layout", "multidevice_6": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-layered-architecture-design", - "multidevice_7": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-bp-practice", + "multidevice_7": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-responsive-layout#section1532120147301", "multidevice_8": "https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-gridrow", - "multidevice_9": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/responsive-layout#媒体查询", + "multidevice_9": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-responsive-layout#section1950102518311", "safety_1": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/security-component-overview", "safety_2": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-picker", "safety_3": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/security-component-overview#运作机制", @@ -84,18 +84,18 @@ "design_4": "https://developer.huawei.com/consumer/cn/activity/", "empowerment_1": "https://developer.huawei.com/consumer/cn/doc/guidebook/harmonyecoapp-guidebook-0000001761818040", "empowerment_2": "https://developer.huawei.com/consumer/cn/app/knowledge-map/", - "empowerment_3": "https://developer.huawei.com/consumer/cn/teaching-video/", + "empowerment_3": "https://developer.huawei.com/consumer/cn/training/study-path/101667550095504391", "empowerment_4": "https://developer.huawei.com/consumer/cn/codelabsPortal/getstarted/101718800110527001", "empowerment_5": "https://developer.huawei.com/consumer/cn/codelabsPortal/serviceTypes", "empowerment_6": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-dev-guide", "empowerment_7": "https://developer.huawei.com/consumer/cn/doc/harmonyos-references/development-intro-api", "empowerment_8": "https://developer.huawei.com/consumer/cn/samples/", - "empowerment_9": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-develop-once-deploy-everywhere", + "empowerment_9": "https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-overview", "empowerment_10": "https://developer.huawei.com/consumer/cn/forum/", "empowerment_11": "https://developer.huawei.com/consumer/cn/customerService/#/bot-dev-top/fap-top/faq-talk-top", - "uxexperirnce_1": "https://developer.huawei.com/consumer/cn/doc/design-guides/multi-device-responsive-design-0000001796704861", + "uxexperirnce_1": "https://developer.huawei.com/consumer/cn/doc/design-guides/practices-overview-0000001746498066", "uxexperirnce_2": "https://developer.huawei.com/consumer/cn/doc/design-guides/ux-guidelines-overview-0000001760867048", - "uxexperirnce_3": "https://developer.huawei.com/consumer/cn/doc/design-guides/responsive-design-overview-0000001746498066", + "uxexperirnce_3": "https://developer.huawei.com/consumer/cn/doc/design-guides/practices-overview-0000001746498066", "uxexperirnce_4": "https://developer.huawei.com/consumer/cn/design/resource/", "quickstart_1": "https://developer.huawei.com/consumer/cn/codelabsPortal/getstarted/101718800110527001", "quickstart_2": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-HelloWorld", diff --git a/products/phone/src/main/resources/resfile/articlecols/common/dist/main.css b/products/phone/src/main/resources/resfile/articlecols/common/dist/main.css index de0b96261322d804c280886e12bb557d93ffa158..a5db9bbc3492f4ef5937eb0ad6645033407a25e4 100644 --- a/products/phone/src/main/resources/resfile/articlecols/common/dist/main.css +++ b/products/phone/src/main/resources/resfile/articlecols/common/dist/main.css @@ -1,9 +1,9 @@ pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-formula{color:#a626a4}.hljs-section,.hljs-name,.hljs-selector-tag,.hljs-deletion,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-string,.hljs-regexp,.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string{color:#50a14f}.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-type,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-number{color:#986801}.hljs-symbol,.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-title.class_,.hljs-class .hljs-title{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}/*! -* Viewer.js v1.11.3 +* Viewer.js v1.11.7 * https://fengyuanchen.github.io/viewerjs * * Copyright 2015-present Chen Fengyuan * Released under the MIT license * -* Date: 2023-03-05T07:01:15.525Z -*/.viewer-close:before,.viewer-flip-horizontal:before,.viewer-flip-vertical:before,.viewer-fullscreen-exit:before,.viewer-fullscreen:before,.viewer-next:before,.viewer-one-to-one:before,.viewer-play:before,.viewer-prev:before,.viewer-reset:before,.viewer-rotate-left:before,.viewer-rotate-right:before,.viewer-zoom-in:before,.viewer-zoom-out:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-size:280px;color:transparent;display:block;font-size:0;height:20px;line-height:0;width:20px}.viewer-zoom-in:before{background-position:0 0;content:"Zoom In"}.viewer-zoom-out:before{background-position:-20px 0;content:"Zoom Out"}.viewer-one-to-one:before{background-position:-40px 0;content:"One to One"}.viewer-reset:before{background-position:-60px 0;content:"Reset"}.viewer-prev:before{background-position:-80px 0;content:"Previous"}.viewer-play:before{background-position:-100px 0;content:"Play"}.viewer-next:before{background-position:-120px 0;content:"Next"}.viewer-rotate-left:before{background-position:-140px 0;content:"Rotate Left"}.viewer-rotate-right:before{background-position:-160px 0;content:"Rotate Right"}.viewer-flip-horizontal:before{background-position:-180px 0;content:"Flip Horizontal"}.viewer-flip-vertical:before{background-position:-200px 0;content:"Flip Vertical"}.viewer-fullscreen:before{background-position:-220px 0;content:"Enter Full Screen"}.viewer-fullscreen-exit:before{background-position:-240px 0;content:"Exit Full Screen"}.viewer-close:before{background-position:-260px 0;content:"Close"}.viewer-container{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;bottom:0;direction:ltr;font-size:0;left:0;line-height:0;overflow:hidden;position:absolute;right:0;top:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.viewer-container ::-moz-selection,.viewer-container::-moz-selection{background-color:transparent}.viewer-container ::selection,.viewer-container::selection{background-color:transparent}.viewer-container:focus{outline:0}.viewer-container img{display:block;height:auto;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.viewer-canvas{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.viewer-canvas>img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:#00000080;overflow:hidden}.viewer-list{box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:transparent;cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;transition:opacity .15s;width:30px}.viewer-list>li:focus,.viewer-list>li:hover{opacity:.75}.viewer-list>li:focus{outline:0}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:focus,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0;z-index:1}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:6px 3px}.viewer-toolbar>ul>li{background-color:#00000080;border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:focus,.viewer-toolbar>ul>li:hover{background-color:#000c}.viewer-toolbar>ul>li:focus{box-shadow:0 0 3px #fff;outline:0;position:relative;z-index:1}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:#000c;border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1.2;margin:5px 5%;max-width:90%;min-height:14px;opacity:.8;overflow:hidden;text-overflow:ellipsis;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{-webkit-app-region:no-drag;background-color:#00000080;border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:#000c}.viewer-button:focus{box-shadow:0 0 3px #fff;outline:0}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:#00000080}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{transition:all .3s}@keyframes viewer-spinner{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.viewer-loading:after{animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:#ffffff80;border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} +* Date: 2024-11-24T04:32:14.526Z +*/.viewer-close:before,.viewer-flip-horizontal:before,.viewer-flip-vertical:before,.viewer-fullscreen-exit:before,.viewer-fullscreen:before,.viewer-next:before,.viewer-one-to-one:before,.viewer-play:before,.viewer-prev:before,.viewer-reset:before,.viewer-rotate-left:before,.viewer-rotate-right:before,.viewer-zoom-in:before,.viewer-zoom-out:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 560 40'%3E%3Cpath fill='%23fff' d='M49.6 17.9h20.2v3.9H49.6zm123.1 2 10.9-11 2.7 2.8-8.2 8.2 8.2 8.2-2.7 2.7-10.9-10.9zm94 0-10.8-11-2.7 2.8 8.1 8.2-8.1 8.2 2.7 2.7 10.8-10.9zM212 9.3l20.1 10.6L212 30.5V9.3zm161.5 4.6-7.2 6 7.2 5.9v-4h12.4v4l7.3-5.9-7.3-6v4h-12.4v-4zm40.2 12.3 5.9 7.2 5.9-7.2h-4V13.6h4l-5.9-7.3-5.9 7.3h4v12.6h-4zm35.9-16.5h6.3v2h-4.3V16h-2V9.7Zm14 0h6.2V16h-2v-4.3h-4.2v-2Zm6.2 14V30h-6.2v-2h4.2v-4.3h2Zm-14 6.3h-6.2v-6.3h2v4.4h4.3v2Zm-438 .1v-8.3H9.6v-3.9h8.2V9.7h3.9v8.2h8.1v3.9h-8.1v8.3h-3.9zM93.6 9.7h-5.8v3.9h2V30h3.8V9.7zm16.1 0h-5.8v3.9h1.9V30h3.9V9.7zm-11.9 4.1h3.9v3.9h-3.9zm0 8.2h3.9v3.9h-3.9zm244.6-11.7 7.2 5.9-7.2 6v-3.6c-5.4-.4-7.8.8-8.7 2.8-.8 1.7-1.8 4.9 2.8 8.2-6.3-2-7.5-6.9-6-11.3 1.6-4.4 8-5 11.9-4.9v-3.1Zm147.2 13.4h6.3V30h-2v-4.3h-4.3v-2zm14 6.3v-6.3h6.2v2h-4.3V30h-1.9zm6.2-14h-6.2V9.7h1.9V14h4.3v2zm-13.9 0h-6.3v-2h4.3V9.7h2V16zm33.3 12.5 8.6-8.6-8.6-8.7 1.9-1.9 8.6 8.7 8.6-8.7 1.9 1.9-8.6 8.7 8.6 8.6-1.9 2-8.6-8.7-8.6 8.7-1.9-2zM297 10.3l-7.1 5.9 7.2 6v-3.6c5.3-.4 7.7.8 8.7 2.8.8 1.7 1.7 4.9-2.9 8.2 6.3-2 7.5-6.9 6-11.3-1.6-4.4-7.9-5-11.8-4.9v-3.1Zm-157.3-.6c2.3 0 4.4.7 6 2l2.5-3 1.9 9.2h-9.3l2.6-3.1a6.2 6.2 0 0 0-9.9 5.1c0 3.4 2.8 6.3 6.2 6.3 2.8 0 5.1-1.9 6-4.4h4c-1 4.7-5 8.3-10 8.3a10 10 0 0 1-10-10.2 10 10 0 0 1 10-10.2Z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:280px;color:transparent;display:block;font-size:0;height:20px;line-height:0;width:20px}.viewer-zoom-in:before{background-position:0 0;content:"Zoom In"}.viewer-zoom-out:before{background-position:-20px 0;content:"Zoom Out"}.viewer-one-to-one:before{background-position:-40px 0;content:"One to One"}.viewer-reset:before{background-position:-60px 0;content:"Reset"}.viewer-prev:before{background-position:-80px 0;content:"Previous"}.viewer-play:before{background-position:-100px 0;content:"Play"}.viewer-next:before{background-position:-120px 0;content:"Next"}.viewer-rotate-left:before{background-position:-140px 0;content:"Rotate Left"}.viewer-rotate-right:before{background-position:-160px 0;content:"Rotate Right"}.viewer-flip-horizontal:before{background-position:-180px 0;content:"Flip Horizontal"}.viewer-flip-vertical:before{background-position:-200px 0;content:"Flip Vertical"}.viewer-fullscreen:before{background-position:-220px 0;content:"Enter Full Screen"}.viewer-fullscreen-exit:before{background-position:-240px 0;content:"Exit Full Screen"}.viewer-close:before{background-position:-260px 0;content:"Close"}.viewer-container{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;bottom:0;direction:ltr;font-size:0;left:0;line-height:0;overflow:hidden;position:absolute;right:0;top:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.viewer-container ::-moz-selection,.viewer-container::-moz-selection{background-color:transparent}.viewer-container ::selection,.viewer-container::selection{background-color:transparent}.viewer-container:focus{outline:0}.viewer-container img{display:block;height:auto;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.viewer-canvas{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.viewer-canvas>img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:#00000080;overflow:hidden}.viewer-list{box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:transparent;cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;transition:opacity .15s;width:30px}.viewer-list>li:focus,.viewer-list>li:hover{opacity:.75}.viewer-list>li:focus{outline:0}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:focus,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0;z-index:1}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:6px 3px}.viewer-toolbar>ul>li{background-color:#00000080;border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:focus,.viewer-toolbar>ul>li:hover{background-color:#000c}.viewer-toolbar>ul>li:focus{box-shadow:0 0 3px #fff;outline:0;position:relative;z-index:1}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:#000c;border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1.2;margin:5px 5%;max-width:90%;min-height:14px;opacity:.8;overflow:hidden;text-overflow:ellipsis;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{-webkit-app-region:no-drag;background-color:#00000080;border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:#000c}.viewer-button:focus{box-shadow:0 0 3px #fff;outline:0}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:#00000080}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{transition:all .3s}@keyframes viewer-spinner{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.viewer-loading:after{animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:#ffffff80;border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} diff --git a/products/phone/src/main/resources/resfile/articlecols/common/dist/main.js b/products/phone/src/main/resources/resfile/articlecols/common/dist/main.js index 86a17b45830811f081c2161c07490a7fb179ec7b..6b262925bb2d7ea4d87151b829d1e24876b927b3 100644 --- a/products/phone/src/main/resources/resfile/articlecols/common/dist/main.js +++ b/products/phone/src/main/resources/resfile/articlecols/common/dist/main.js @@ -1 +1 @@ -import{H as Qt}from"../../../dist/common.js";import"../../../dist/common2.js";const St={backdrop:!0,button:!0,navbar:!0,title:!0,toolbar:!0,className:"",container:"body",filter:null,fullscreen:!0,inheritedAttributes:["crossOrigin","decoding","isMap","loading","referrerPolicy","sizes","srcset","useMap"],initialCoverage:.9,initialViewIndex:0,inline:!1,interval:5e3,keyboard:!0,focus:!0,loading:!0,loop:!0,minWidth:200,minHeight:100,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,slideOnTouch:!0,toggleOnDblclick:!0,tooltip:!0,transition:!0,zIndex:2015,zIndexInline:0,zoomRatio:.1,minZoomRatio:.01,maxZoomRatio:100,url:"src",ready:null,show:null,shown:null,hide:null,hidden:null,view:null,viewed:null,move:null,moved:null,rotate:null,rotated:null,scale:null,scaled:null,zoom:null,zoomed:null,play:null,stop:null},te='
',ht=typeof window<"u"&&typeof window.document<"u",M=ht?window:{},Y=ht&&M.document.documentElement?"ontouchstart"in M.document.documentElement:!1,bt=ht?"PointerEvent"in M:!1,f="viewer",ot="move",Kt="switch",K="zoom",et=`${f}-active`,ee=`${f}-close`,at=`${f}-fade`,mt=`${f}-fixed`,ie=`${f}-fullscreen`,It=`${f}-fullscreen-exit`,F=`${f}-hide`,se=`${f}-hide-md-down`,ne=`${f}-hide-sm-down`,oe=`${f}-hide-xs-down`,D=`${f}-in`,G=`${f}-invisible`,U=`${f}-loading`,ae=`${f}-move`,Nt=`${f}-open`,H=`${f}-show`,v=`${f}-transition`,Z="click",gt="dblclick",At="dragstart",Ct="focusin",xt="keydown",k="load",W="error",re=Y?"touchend touchcancel":"mouseup",le=Y?"touchmove":"mousemove",he=Y?"touchstart":"mousedown",Dt=bt?"pointerdown":he,kt=bt?"pointermove":le,Lt=bt?"pointerup pointercancel":re,zt="resize",z="transitionend",Ot="wheel",Rt="ready",_t="show",Mt="shown",Vt="hide",$t="hidden",Ft="view",J="viewed",Wt="move",Ht="moved",Pt="rotate",qt="rotated",Xt="scale",Bt="scaled",Yt="zoom",Ut="zoomed",Zt="play",jt="stop",lt=`${f}Action`,wt=/\s\s*/,it=["zoom-in","zoom-out","one-to-one","reset","prev","play","next","rotate-left","rotate-right","flip-horizontal","flip-vertical"];function Q(t){return typeof t=="string"}const ce=Number.isNaN||M.isNaN;function y(t){return typeof t=="number"&&!ce(t)}function q(t){return typeof t>"u"}function j(t){return typeof t=="object"&&t!==null}const{hasOwnProperty:de}=Object.prototype;function X(t){if(!j(t))return!1;try{const{constructor:e}=t,{prototype:i}=e;return e&&i&&de.call(i,"isPrototypeOf")}catch{return!1}}function p(t){return typeof t=="function"}function w(t,e){if(t&&p(e))if(Array.isArray(t)||y(t.length)){const{length:i}=t;let s;for(s=0;s{e.call(t,t[i],i,t)});return t}const C=Object.assign||function(e,...i){return j(e)&&i.length>0&&i.forEach(s=>{j(s)&&Object.keys(s).forEach(n=>{e[n]=s[n]})}),e},ue=/^(?:width|height|left|top|marginLeft|marginTop)$/;function O(t,e){const{style:i}=t;w(e,(s,n)=>{ue.test(n)&&y(s)&&(s+="px"),i[n]=s})}function fe(t){return Q(t)?t.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"):t}function P(t,e){return!t||!e?!1:t.classList?t.classList.contains(e):t.className.indexOf(e)>-1}function c(t,e){if(!t||!e)return;if(y(t.length)){w(t,s=>{c(s,e)});return}if(t.classList){t.classList.add(e);return}const i=t.className.trim();i?i.indexOf(e)<0&&(t.className=`${i} ${e}`):t.className=e}function g(t,e){if(!(!t||!e)){if(y(t.length)){w(t,i=>{g(i,e)});return}if(t.classList){t.classList.remove(e);return}t.className.indexOf(e)>=0&&(t.className=t.className.replace(e,""))}}function tt(t,e,i){if(e){if(y(t.length)){w(t,s=>{tt(s,e,i)});return}i?c(t,e):g(t,e)}}const me=/([a-z\d])([A-Z])/g;function Et(t){return t.replace(me,"$1-$2").toLowerCase()}function B(t,e){return j(t[e])?t[e]:t.dataset?t.dataset[e]:t.getAttribute(`data-${Et(e)}`)}function pt(t,e,i){j(i)?t[e]=i:t.dataset?t.dataset[e]=i:t.setAttribute(`data-${Et(e)}`,i)}const Gt=(()=>{let t=!1;if(ht){let e=!1;const i=()=>{},s=Object.defineProperty({},"once",{get(){return t=!0,e},set(n){e=n}});M.addEventListener("test",i,s),M.removeEventListener("test",i,s)}return t})();function b(t,e,i,s={}){let n=i;e.trim().split(wt).forEach(o=>{if(!Gt){const{listeners:a}=t;a&&a[o]&&a[o][i]&&(n=a[o][i],delete a[o][i],Object.keys(a[o]).length===0&&delete a[o],Object.keys(a).length===0&&delete t.listeners)}t.removeEventListener(o,n,s)})}function d(t,e,i,s={}){let n=i;e.trim().split(wt).forEach(o=>{if(s.once&&!Gt){const{listeners:a={}}=t;n=(...r)=>{delete a[o][i],t.removeEventListener(o,n,s),i.apply(t,r)},a[o]||(a[o]={}),a[o][i]&&t.removeEventListener(o,a[o][i],s),a[o][i]=n,t.listeners=a}t.addEventListener(o,n,s)})}function T(t,e,i,s){let n;return p(Event)&&p(CustomEvent)?n=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:i,...s}):(n=document.createEvent("CustomEvent"),n.initCustomEvent(e,!0,!0,i)),t.dispatchEvent(n)}function ge(t){const e=t.getBoundingClientRect();return{left:e.left+(window.pageXOffset-document.documentElement.clientLeft),top:e.top+(window.pageYOffset-document.documentElement.clientTop)}}function rt({rotate:t,scaleX:e,scaleY:i,translateX:s,translateY:n}){const o=[];y(s)&&s!==0&&o.push(`translateX(${s}px)`),y(n)&&n!==0&&o.push(`translateY(${n}px)`),y(t)&&t!==0&&o.push(`rotate(${t}deg)`),y(e)&&e!==1&&o.push(`scaleX(${e})`),y(i)&&i!==1&&o.push(`scaleY(${i})`);const a=o.length?o.join(" "):"none";return{WebkitTransform:a,msTransform:a,transform:a}}function pe(t){return Q(t)?decodeURIComponent(t.replace(/^.*\//,"").replace(/[?&#].*$/,"")):""}const ft=M.navigator&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(M.navigator.userAgent);function Jt(t,e,i){const s=document.createElement("img");if(t.naturalWidth&&!ft)return i(t.naturalWidth,t.naturalHeight),s;const n=document.body||document.documentElement;return s.onload=()=>{i(s.width,s.height),ft||n.removeChild(s)},w(e.inheritedAttributes,o=>{const a=t.getAttribute(o);a!==null&&s.setAttribute(o,a)}),s.src=t.src,ft||(s.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",n.appendChild(s)),s}function st(t){switch(t){case 2:return oe;case 3:return ne;case 4:return se;default:return""}}function be(t){const e={...t},i=[];return w(t,(s,n)=>{delete e[n],w(e,o=>{const a=Math.abs(s.startX-o.startX),r=Math.abs(s.startY-o.startY),l=Math.abs(s.endX-o.endX),h=Math.abs(s.endY-o.endY),m=Math.sqrt(a*a+r*r),E=(Math.sqrt(l*l+h*h)-m)/m;i.push(E)})}),i.sort((s,n)=>Math.abs(s){e+=n,i+=o,s+=1}),e/=s,i/=s,{pageX:e,pageY:i}}const Ee={render(){this.initContainer(),this.initViewer(),this.initList(),this.renderViewer()},initBody(){const{ownerDocument:t}=this.element,e=t.body||t.documentElement;this.body=e,this.scrollbarWidth=window.innerWidth-t.documentElement.clientWidth,this.initialBodyPaddingRight=e.style.paddingRight,this.initialBodyComputedPaddingRight=window.getComputedStyle(e).paddingRight},initContainer(){this.containerData={width:window.innerWidth,height:window.innerHeight}},initViewer(){const{options:t,parent:e}=this;let i;t.inline&&(i={width:Math.max(e.offsetWidth,t.minWidth),height:Math.max(e.offsetHeight,t.minHeight)},this.parentData=i),(this.fulled||!i)&&(i=this.containerData),this.viewerData=C({},i)},renderViewer(){this.options.inline&&!this.fulled&&O(this.viewer,this.viewerData)},initList(){const{element:t,options:e,list:i}=this,s=[];i.innerHTML="",w(this.images,(n,o)=>{const{src:a}=n,r=n.alt||pe(a),l=this.getImageURL(n);if(a||l){const h=document.createElement("li"),m=document.createElement("img");w(e.inheritedAttributes,u=>{const E=n.getAttribute(u);E!==null&&m.setAttribute(u,E)}),e.navbar&&(m.src=a||l),m.alt=r,m.setAttribute("data-original-url",l||a),h.setAttribute("data-index",o),h.setAttribute("data-viewer-action","view"),h.setAttribute("role","button"),e.keyboard&&h.setAttribute("tabindex",0),h.appendChild(m),i.appendChild(h),s.push(h)}}),this.items=s,w(s,n=>{const o=n.firstElementChild;let a,r;pt(o,"filled",!0),e.loading&&c(n,U),d(o,k,a=l=>{b(o,W,r),e.loading&&g(n,U),this.loadImage(l)},{once:!0}),d(o,W,r=()=>{b(o,k,a),e.loading&&g(n,U)},{once:!0})}),e.transition&&d(t,J,()=>{c(i,v)},{once:!0})},renderList(){const{index:t}=this,e=this.items[t];if(!e)return;const i=e.nextElementSibling,s=parseInt(window.getComputedStyle(i||e).marginLeft,10),{offsetWidth:n}=e,o=n+s;O(this.list,C({width:o*this.length-s},rt({translateX:(this.viewerData.width-n)/2-o*t})))},resetList(){const{list:t}=this;t.innerHTML="",g(t,v),O(t,rt({translateX:0}))},initImage(t){const{options:e,image:i,viewerData:s}=this,n=this.footer.offsetHeight,o=s.width,a=Math.max(s.height-n,n),r=this.imageData||{};let l;this.imageInitializing={abort:()=>{l.onload=null}},l=Jt(i,e,(h,m)=>{const u=h/m;let E=Math.max(0,Math.min(1,e.initialCoverage)),N=o,I=a;this.imageInitializing=!1,a*u>o?I=o/u:N=a*u,E=y(E)?E:.9,N=Math.min(N*E,h),I=Math.min(I*E,m);const A=(o-N)/2,S=(a-I)/2,L={left:A,top:S,x:A,y:S,width:N,height:I,oldRatio:1,ratio:N/h,aspectRatio:u,naturalWidth:h,naturalHeight:m},x=C({},L);e.rotatable&&(L.rotate=r.rotate||0,x.rotate=0),e.scalable&&(L.scaleX=r.scaleX||1,L.scaleY=r.scaleY||1,x.scaleX=1,x.scaleY=1),this.imageData=L,this.initialImageData=x,t&&t()})},renderImage(t){const{image:e,imageData:i}=this;if(O(e,C({width:i.width,height:i.height,marginLeft:i.x,marginTop:i.y},rt(i))),t)if((this.viewing||this.moving||this.rotating||this.scaling||this.zooming)&&this.options.transition&&P(e,v)){const s=()=>{this.imageRendering=!1,t()};this.imageRendering={abort:()=>{b(e,z,s)}},d(e,z,s,{once:!0})}else t()},resetImage(){if(this.viewing||this.viewed){const{image:t}=this;this.viewing&&this.viewing.abort(),t.parentNode.removeChild(t),this.image=null}}},ye={bind(){const{options:t,viewer:e,canvas:i}=this,s=this.element.ownerDocument;d(e,Z,this.onClick=this.click.bind(this)),d(e,At,this.onDragStart=this.dragstart.bind(this)),d(i,Dt,this.onPointerDown=this.pointerdown.bind(this)),d(s,kt,this.onPointerMove=this.pointermove.bind(this)),d(s,Lt,this.onPointerUp=this.pointerup.bind(this)),d(s,xt,this.onKeyDown=this.keydown.bind(this)),d(window,zt,this.onResize=this.resize.bind(this)),t.zoomable&&t.zoomOnWheel&&d(e,Ot,this.onWheel=this.wheel.bind(this),{passive:!1,capture:!0}),t.toggleOnDblclick&&d(i,gt,this.onDblclick=this.dblclick.bind(this))},unbind(){const{options:t,viewer:e,canvas:i}=this,s=this.element.ownerDocument;b(e,Z,this.onClick),b(e,At,this.onDragStart),b(i,Dt,this.onPointerDown),b(s,kt,this.onPointerMove),b(s,Lt,this.onPointerUp),b(s,xt,this.onKeyDown),b(window,zt,this.onResize),t.zoomable&&t.zoomOnWheel&&b(e,Ot,this.onWheel,{passive:!1,capture:!0}),t.toggleOnDblclick&&b(i,gt,this.onDblclick)}},ve={click(t){const{options:e,imageData:i}=this;let{target:s}=t,n=B(s,lt);switch(!n&&s.localName==="img"&&s.parentElement.localName==="li"&&(s=s.parentElement,n=B(s,lt)),Y&&t.isTrusted&&s===this.canvas&&clearTimeout(this.clickCanvasTimeout),n){case"mix":this.played?this.stop():e.inline?this.fulled?this.exit():this.full():this.hide();break;case"hide":this.pointerMoved||this.hide();break;case"view":this.view(B(s,"index"));break;case"zoom-in":this.zoom(.1,!0);break;case"zoom-out":this.zoom(-.1,!0);break;case"one-to-one":this.toggle();break;case"reset":this.reset();break;case"prev":this.prev(e.loop);break;case"play":this.play(e.fullscreen);break;case"next":this.next(e.loop);break;case"rotate-left":this.rotate(-90);break;case"rotate-right":this.rotate(90);break;case"flip-horizontal":this.scaleX(-i.scaleX||-1);break;case"flip-vertical":this.scaleY(-i.scaleY||-1);break;default:this.played&&this.stop()}},dblclick(t){t.preventDefault(),this.viewed&&t.target===this.image&&(Y&&t.isTrusted&&clearTimeout(this.doubleClickImageTimeout),this.toggle(t.isTrusted?t:t.detail&&t.detail.originalEvent))},load(){this.timeout&&(clearTimeout(this.timeout),this.timeout=!1);const{element:t,options:e,image:i,index:s,viewerData:n}=this;g(i,G),e.loading&&g(this.canvas,U),i.style.cssText=`height:0;margin-left:${n.width/2}px;margin-top:${n.height/2}px;max-width:none!important;position:relative;width:0;`,this.initImage(()=>{tt(i,ae,e.movable),tt(i,v,e.transition),this.renderImage(()=>{this.viewed=!0,this.viewing=!1,p(e.viewed)&&d(t,J,e.viewed,{once:!0}),T(t,J,{originalImage:this.images[s],index:s,image:i},{cancelable:!1})})})},loadImage(t){const e=t.target,i=e.parentNode,s=i.offsetWidth||30,n=i.offsetHeight||50,o=!!B(e,"filled");Jt(e,this.options,(a,r)=>{const l=a/r;let h=s,m=n;n*l>s?o?h=n*l:m=s/l:o?m=s/l:h=n*l,O(e,C({width:h,height:m},rt({translateX:(s-h)/2,translateY:(n-m)/2})))})},keydown(t){const{options:e}=this;if(!e.keyboard)return;const i=t.keyCode||t.which||t.charCode;switch(i){case 13:this.viewer.contains(t.target)&&this.click(t);break}if(this.fulled)switch(i){case 27:this.played?this.stop():e.inline?this.fulled&&this.exit():this.hide();break;case 32:this.played&&this.stop();break;case 37:this.played&&this.playing?this.playing.prev():this.prev(e.loop);break;case 38:t.preventDefault(),this.zoom(e.zoomRatio,!0);break;case 39:this.played&&this.playing?this.playing.next():this.next(e.loop);break;case 40:t.preventDefault(),this.zoom(-e.zoomRatio,!0);break;case 48:case 49:t.ctrlKey&&(t.preventDefault(),this.toggle());break}},dragstart(t){t.target.localName==="img"&&t.preventDefault()},pointerdown(t){const{options:e,pointers:i}=this,{buttons:s,button:n}=t;if(this.pointerMoved=!1,!this.viewed||this.showing||this.viewing||this.hiding||(t.type==="mousedown"||t.type==="pointerdown"&&t.pointerType==="mouse")&&(y(s)&&s!==1||y(n)&&n!==0||t.ctrlKey))return;t.preventDefault(),t.changedTouches?w(t.changedTouches,a=>{i[a.identifier]=nt(a)}):i[t.pointerId||0]=nt(t);let o=e.movable?ot:!1;e.zoomOnTouch&&e.zoomable&&Object.keys(i).length>1?o=K:e.slideOnTouch&&(t.pointerType==="touch"||t.type==="touchstart")&&this.isSwitchable()&&(o=Kt),e.transition&&(o===ot||o===K)&&g(this.image,v),this.action=o},pointermove(t){const{pointers:e,action:i}=this;!this.viewed||!i||(t.preventDefault(),t.changedTouches?w(t.changedTouches,s=>{C(e[s.identifier]||{},nt(s,!0))}):C(e[t.pointerId||0]||{},nt(t,!0)),this.change(t))},pointerup(t){const{options:e,action:i,pointers:s}=this;let n;t.changedTouches?w(t.changedTouches,o=>{n=s[o.identifier],delete s[o.identifier]}):(n=s[t.pointerId||0],delete s[t.pointerId||0]),i&&(t.preventDefault(),e.transition&&(i===ot||i===K)&&c(this.image,v),this.action=!1,Y&&i!==K&&n&&Date.now()-n.timeStamp<500&&(clearTimeout(this.clickCanvasTimeout),clearTimeout(this.doubleClickImageTimeout),e.toggleOnDblclick&&this.viewed&&t.target===this.image?this.imageClicked?(this.imageClicked=!1,this.doubleClickImageTimeout=setTimeout(()=>{T(this.image,gt,{originalEvent:t})},50)):(this.imageClicked=!0,this.doubleClickImageTimeout=setTimeout(()=>{this.imageClicked=!1},500)):(this.imageClicked=!1,e.backdrop&&e.backdrop!=="static"&&t.target===this.canvas&&(this.clickCanvasTimeout=setTimeout(()=>{T(this.canvas,Z,{originalEvent:t})},50)))))},resize(){if(!(!this.isShown||this.hiding)&&(this.fulled&&(this.close(),this.initBody(),this.open()),this.initContainer(),this.initViewer(),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage()}),this.played)){if(this.options.fullscreen&&this.fulled&&!(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)){this.stop();return}w(this.player.getElementsByTagName("img"),t=>{d(t,k,this.loadImage.bind(this),{once:!0}),T(t,k)})}},wheel(t){if(!this.viewed||(t.preventDefault(),this.wheeling))return;this.wheeling=!0,setTimeout(()=>{this.wheeling=!1},50);const e=Number(this.options.zoomRatio)||.1;let i=1;t.deltaY?i=t.deltaY>0?1:-1:t.wheelDelta?i=-t.wheelDelta/120:t.detail&&(i=t.detail>0?1:-1),this.zoom(-i*e,!0,null,t)}},Te={show(t=!1){const{element:e,options:i}=this;if(i.inline||this.showing||this.isShown||this.showing)return this;if(!this.ready)return this.build(),this.ready&&this.show(t),this;if(p(i.show)&&d(e,_t,i.show,{once:!0}),T(e,_t)===!1||!this.ready)return this;this.hiding&&this.transitioning.abort(),this.showing=!0,this.open();const{viewer:s}=this;if(g(s,F),s.setAttribute("role","dialog"),s.setAttribute("aria-labelledby",this.title.id),s.setAttribute("aria-modal",!0),s.removeAttribute("aria-hidden"),i.transition&&!t){const n=this.shown.bind(this);this.transitioning={abort:()=>{b(s,z,n),g(s,D)}},c(s,v),s.initialOffsetWidth=s.offsetWidth,d(s,z,n,{once:!0}),c(s,D)}else c(s,D),this.shown();return this},hide(t=!1){const{element:e,options:i}=this;if(i.inline||this.hiding||!(this.isShown||this.showing))return this;if(p(i.hide)&&d(e,Vt,i.hide,{once:!0}),T(e,Vt)===!1)return this;this.showing&&this.transitioning.abort(),this.hiding=!0,this.played?this.stop():this.viewing&&this.viewing.abort();const{viewer:s,image:n}=this,o=()=>{g(s,D),this.hidden()};if(i.transition&&!t){const a=l=>{l&&l.target===s&&(b(s,z,a),this.hidden())},r=()=>{P(s,v)?(d(s,z,a),g(s,D)):o()};this.transitioning={abort:()=>{this.viewed&&P(n,v)?b(n,z,r):P(s,v)&&b(s,z,a)}},this.viewed&&P(n,v)?(d(n,z,r,{once:!0}),this.zoomTo(0,!1,null,null,!0)):r()}else o();return this},view(t=this.options.initialViewIndex){if(t=Number(t)||0,this.hiding||this.played||t<0||t>=this.length||this.viewed&&t===this.index)return this;if(!this.isShown)return this.index=t,this.show();this.viewing&&this.viewing.abort();const{element:e,options:i,title:s,canvas:n}=this,o=this.items[t],a=o.querySelector("img"),r=B(a,"originalUrl"),l=a.getAttribute("alt"),h=document.createElement("img");if(w(i.inheritedAttributes,I=>{const A=a.getAttribute(I);A!==null&&h.setAttribute(I,A)}),h.src=r,h.alt=l,p(i.view)&&d(e,Ft,i.view,{once:!0}),T(e,Ft,{originalImage:this.images[t],index:t,image:h})===!1||!this.isShown||this.hiding||this.played)return this;const m=this.items[this.index];m&&(g(m,et),m.removeAttribute("aria-selected")),c(o,et),o.setAttribute("aria-selected",!0),i.focus&&o.focus(),this.image=h,this.viewed=!1,this.index=t,this.imageData={},c(h,G),i.loading&&c(n,U),n.innerHTML="",n.appendChild(h),this.renderList(),s.innerHTML="";const u=()=>{const{imageData:I}=this,A=Array.isArray(i.title)?i.title[1]:i.title;s.innerHTML=fe(p(A)?A.call(this,h,I):`${l} (${I.naturalWidth} × ${I.naturalHeight})`)};let E,N;return d(e,J,u,{once:!0}),this.viewing={abort:()=>{b(e,J,u),h.complete?this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort():(h.src="",b(h,k,E),this.timeout&&clearTimeout(this.timeout))}},h.complete?this.load():(d(h,k,E=()=>{b(h,W,N),this.load()},{once:!0}),d(h,W,N=()=>{b(h,k,E),this.timeout&&(clearTimeout(this.timeout),this.timeout=!1),g(h,G),i.loading&&g(this.canvas,U)},{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>{g(h,G),this.timeout=!1},1e3)),this},prev(t=!1){let e=this.index-1;return e<0&&(e=t?this.length-1:0),this.view(e),this},next(t=!1){const e=this.length-1;let i=this.index+1;return i>e&&(i=t?0:e),this.view(i),this},move(t,e=t){const{imageData:i}=this;return this.moveTo(q(t)?t:i.x+Number(t),q(e)?e:i.y+Number(e)),this},moveTo(t,e=t,i=null){const{element:s,options:n,imageData:o}=this;if(t=Number(t),e=Number(e),this.viewed&&!this.played&&n.movable){const a=o.x,r=o.y;let l=!1;if(y(t)?l=!0:t=a,y(e)?l=!0:e=r,l){if(p(n.move)&&d(s,Wt,n.move,{once:!0}),T(s,Wt,{x:t,y:e,oldX:a,oldY:r,originalEvent:i})===!1)return this;o.x=t,o.y=e,o.left=t,o.top=e,this.moving=!0,this.renderImage(()=>{this.moving=!1,p(n.moved)&&d(s,Ht,n.moved,{once:!0}),T(s,Ht,{x:t,y:e,oldX:a,oldY:r,originalEvent:i},{cancelable:!1})})}}return this},rotate(t){return this.rotateTo((this.imageData.rotate||0)+Number(t)),this},rotateTo(t){const{element:e,options:i,imageData:s}=this;if(t=Number(t),y(t)&&this.viewed&&!this.played&&i.rotatable){const n=s.rotate;if(p(i.rotate)&&d(e,Pt,i.rotate,{once:!0}),T(e,Pt,{degree:t,oldDegree:n})===!1)return this;s.rotate=t,this.rotating=!0,this.renderImage(()=>{this.rotating=!1,p(i.rotated)&&d(e,qt,i.rotated,{once:!0}),T(e,qt,{degree:t,oldDegree:n},{cancelable:!1})})}return this},scaleX(t){return this.scale(t,this.imageData.scaleY),this},scaleY(t){return this.scale(this.imageData.scaleX,t),this},scale(t,e=t){const{element:i,options:s,imageData:n}=this;if(t=Number(t),e=Number(e),this.viewed&&!this.played&&s.scalable){const o=n.scaleX,a=n.scaleY;let r=!1;if(y(t)?r=!0:t=o,y(e)?r=!0:e=a,r){if(p(s.scale)&&d(i,Xt,s.scale,{once:!0}),T(i,Xt,{scaleX:t,scaleY:e,oldScaleX:o,oldScaleY:a})===!1)return this;n.scaleX=t,n.scaleY=e,this.scaling=!0,this.renderImage(()=>{this.scaling=!1,p(s.scaled)&&d(i,Bt,s.scaled,{once:!0}),T(i,Bt,{scaleX:t,scaleY:e,oldScaleX:o,oldScaleY:a},{cancelable:!1})})}}return this},zoom(t,e=!1,i=null,s=null){const{imageData:n}=this;return t=Number(t),t<0?t=1/(1-t):t=1+t,this.zoomTo(n.width*t/n.naturalWidth,e,i,s),this},zoomTo(t,e=!1,i=null,s=null,n=!1){const{element:o,options:a,pointers:r,imageData:l}=this,{x:h,y:m,width:u,height:E,naturalWidth:N,naturalHeight:I}=l;if(t=Math.max(0,t),y(t)&&this.viewed&&!this.played&&(n||a.zoomable)){if(!n){const V=Math.max(.01,a.minZoomRatio),$=Math.min(100,a.maxZoomRatio);t=Math.min(Math.max(t,V),$)}if(s)switch(s.type){case"wheel":a.zoomRatio>=.055&&t>.95&&t<1.05&&(t=1);break;case"pointermove":case"touchmove":case"mousemove":t>.99&&t<1.01&&(t=1);break}const A=N*t,S=I*t,L=A-u,x=S-E,R=l.ratio;if(p(a.zoom)&&d(o,Yt,a.zoom,{once:!0}),T(o,Yt,{ratio:t,oldRatio:R,originalEvent:s})===!1)return this;if(this.zooming=!0,s){const V=ge(this.viewer),$=r&&Object.keys(r).length>0?we(r):{pageX:s.pageX,pageY:s.pageY};l.x-=L*(($.pageX-V.left-h)/u),l.y-=x*(($.pageY-V.top-m)/E)}else X(i)&&y(i.x)&&y(i.y)?(l.x-=L*((i.x-h)/u),l.y-=x*((i.y-m)/E)):(l.x-=L/2,l.y-=x/2);l.left=l.x,l.top=l.y,l.width=A,l.height=S,l.oldRatio=R,l.ratio=t,this.renderImage(()=>{this.zooming=!1,p(a.zoomed)&&d(o,Ut,a.zoomed,{once:!0}),T(o,Ut,{ratio:t,oldRatio:R,originalEvent:s},{cancelable:!1})}),e&&this.tooltip()}return this},play(t=!1){if(!this.isShown||this.played)return this;const{element:e,options:i}=this;if(p(i.play)&&d(e,Zt,i.play,{once:!0}),T(e,Zt)===!1)return this;const{player:s}=this,n=this.loadImage.bind(this),o=[];let a=0,r=0;if(this.played=!0,this.onLoadWhenPlay=n,t&&this.requestFullscreen(t),c(s,H),w(this.items,(l,h)=>{const m=l.querySelector("img"),u=document.createElement("img");u.src=B(m,"originalUrl"),u.alt=m.getAttribute("alt"),u.referrerPolicy=m.referrerPolicy,a+=1,c(u,at),tt(u,v,i.transition),P(l,et)&&(c(u,D),r=h),o.push(u),d(u,k,n,{once:!0}),s.appendChild(u)}),y(i.interval)&&i.interval>0){const l=()=>{clearTimeout(this.playing.timeout),g(o[r],D),r-=1,r=r>=0?r:a-1,c(o[r],D),this.playing.timeout=setTimeout(l,i.interval)},h=()=>{clearTimeout(this.playing.timeout),g(o[r],D),r+=1,r=r1&&(this.playing={prev:l,next:h,timeout:setTimeout(h,i.interval)})}return this},stop(){if(!this.played)return this;const{element:t,options:e}=this;if(p(e.stop)&&d(t,jt,e.stop,{once:!0}),T(t,jt)===!1)return this;const{player:i}=this;return clearTimeout(this.playing.timeout),this.playing=!1,this.played=!1,w(i.getElementsByTagName("img"),s=>{b(s,k,this.onLoadWhenPlay)}),g(i,H),i.innerHTML="",this.exitFullscreen(),this},full(){const{options:t,viewer:e,image:i,list:s}=this;return!this.isShown||this.played||this.fulled||!t.inline?this:(this.fulled=!0,this.open(),c(this.button,It),t.transition&&(g(s,v),this.viewed&&g(i,v)),c(e,mt),e.setAttribute("role","dialog"),e.setAttribute("aria-labelledby",this.title.id),e.setAttribute("aria-modal",!0),e.removeAttribute("style"),O(e,{zIndex:t.zIndex}),t.focus&&this.enforceFocus(),this.initContainer(),this.viewerData=C({},this.containerData),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage(()=>{t.transition&&setTimeout(()=>{c(i,v),c(s,v)},0)})}),this)},exit(){const{options:t,viewer:e,image:i,list:s}=this;return!this.isShown||this.played||!this.fulled||!t.inline?this:(this.fulled=!1,this.close(),g(this.button,It),t.transition&&(g(s,v),this.viewed&&g(i,v)),t.focus&&this.clearEnforceFocus(),e.removeAttribute("role"),e.removeAttribute("aria-labelledby"),e.removeAttribute("aria-modal"),g(e,mt),O(e,{zIndex:t.zIndexInline}),this.viewerData=C({},this.parentData),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage(()=>{t.transition&&setTimeout(()=>{c(i,v),c(s,v)},0)})}),this)},tooltip(){const{options:t,tooltipBox:e,imageData:i}=this;return!this.viewed||this.played||!t.tooltip?this:(e.textContent=`${Math.round(i.ratio*100)}%`,this.tooltipping?clearTimeout(this.tooltipping):t.transition?(this.fading&&T(e,z),c(e,H),c(e,at),c(e,v),e.removeAttribute("aria-hidden"),e.initialOffsetWidth=e.offsetWidth,c(e,D)):(c(e,H),e.removeAttribute("aria-hidden")),this.tooltipping=setTimeout(()=>{t.transition?(d(e,z,()=>{g(e,H),g(e,at),g(e,v),e.setAttribute("aria-hidden",!0),this.fading=!1},{once:!0}),g(e,D),this.fading=!0):(g(e,H),e.setAttribute("aria-hidden",!0)),this.tooltipping=!1},1e3),this)},toggle(t=null){return this.imageData.ratio===1?this.zoomTo(this.imageData.oldRatio,!0,null,t):this.zoomTo(1,!0,null,t),this},reset(){return this.viewed&&!this.played&&(this.imageData=C({},this.initialImageData),this.renderImage()),this},update(){const{element:t,options:e,isImg:i}=this;if(i&&!t.parentNode)return this.destroy();const s=[];if(w(i?[t]:t.querySelectorAll("img"),n=>{p(e.filter)?e.filter.call(this,n)&&s.push(n):this.getImageURL(n)&&s.push(n)}),!s.length)return this;if(this.images=s,this.length=s.length,this.ready){const n=[];if(w(this.items,(o,a)=>{const r=o.querySelector("img"),l=s[a];l&&r?(l.src!==r.src||l.alt!==r.alt)&&n.push(a):n.push(a)}),O(this.list,{width:"auto"}),this.initList(),this.isShown)if(this.length){if(this.viewed){const o=n.indexOf(this.index);if(o>=0)this.viewed=!1,this.view(Math.max(Math.min(this.index-o,this.length-1),0));else{const a=this.items[this.index];c(a,et),a.setAttribute("aria-selected",!0)}}}else this.image=null,this.viewed=!1,this.index=0,this.imageData={},this.canvas.innerHTML="",this.title.innerHTML=""}else this.build();return this},destroy(){const{element:t,options:e}=this;return t[f]?(this.destroyed=!0,this.ready?(this.played&&this.stop(),e.inline?(this.fulled&&this.exit(),this.unbind()):this.isShown?(this.viewing&&(this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort()),this.hiding&&this.transitioning.abort(),this.hidden()):this.showing&&(this.transitioning.abort(),this.hidden()),this.ready=!1,this.viewer.parentNode.removeChild(this.viewer)):e.inline&&(this.delaying?this.delaying.abort():this.initializing&&this.initializing.abort()),e.inline||b(t,Z,this.onStart),t[f]=void 0,this):this}},Se={getImageURL(t){let{url:e}=this.options;return Q(e)?e=t.getAttribute(e):p(e)?e=e.call(this,t):e="",e},enforceFocus(){this.clearEnforceFocus(),d(document,Ct,this.onFocusin=t=>{const{viewer:e}=this;let{target:i}=t;if(!(i===document||i===e||e.contains(i))){for(;i;){if(i.getAttribute("tabindex")!==null||i.getAttribute("aria-modal")==="true")return;i=i.parentElement}e.focus()}})},clearEnforceFocus(){this.onFocusin&&(b(document,Ct,this.onFocusin),this.onFocusin=null)},open(){const{body:t}=this;c(t,Nt),this.scrollbarWidth>0&&(t.style.paddingRight=`${this.scrollbarWidth+(parseFloat(this.initialBodyComputedPaddingRight)||0)}px`)},close(){const{body:t}=this;g(t,Nt),this.scrollbarWidth>0&&(t.style.paddingRight=this.initialBodyPaddingRight)},shown(){const{element:t,options:e,viewer:i}=this;this.fulled=!0,this.isShown=!0,this.render(),this.bind(),this.showing=!1,e.focus&&(i.focus(),this.enforceFocus()),p(e.shown)&&d(t,Mt,e.shown,{once:!0}),T(t,Mt)!==!1&&this.ready&&this.isShown&&!this.hiding&&this.view(this.index)},hidden(){const{element:t,options:e,viewer:i}=this;e.fucus&&this.clearEnforceFocus(),this.fulled=!1,this.viewed=!1,this.isShown=!1,this.close(),this.unbind(),c(i,F),i.removeAttribute("role"),i.removeAttribute("aria-labelledby"),i.removeAttribute("aria-modal"),i.setAttribute("aria-hidden",!0),this.resetList(),this.resetImage(),this.hiding=!1,this.destroyed||(p(e.hidden)&&d(t,$t,e.hidden,{once:!0}),T(t,$t,null,{cancelable:!1}))},requestFullscreen(t){const e=this.element.ownerDocument;if(this.fulled&&!(e.fullscreenElement||e.webkitFullscreenElement||e.mozFullScreenElement||e.msFullscreenElement)){const{documentElement:i}=e;i.requestFullscreen?X(t)?i.requestFullscreen(t):i.requestFullscreen():i.webkitRequestFullscreen?i.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT):i.mozRequestFullScreen?i.mozRequestFullScreen():i.msRequestFullscreen&&i.msRequestFullscreen()}},exitFullscreen(){const t=this.element.ownerDocument;this.fulled&&(t.fullscreenElement||t.webkitFullscreenElement||t.mozFullScreenElement||t.msFullscreenElement)&&(t.exitFullscreen?t.exitFullscreen():t.webkitExitFullscreen?t.webkitExitFullscreen():t.mozCancelFullScreen?t.mozCancelFullScreen():t.msExitFullscreen&&t.msExitFullscreen())},change(t){const{options:e,pointers:i}=this,s=i[Object.keys(i)[0]];if(!s)return;const n=s.endX-s.startX,o=s.endY-s.startY;switch(this.action){case ot:(n!==0||o!==0)&&(this.pointerMoved=!0,this.move(n,o,t));break;case K:this.zoom(be(i),!1,null,t);break;case Kt:{this.action="switched";const a=Math.abs(n);a>1&&a>Math.abs(o)&&(this.pointers={},n>1?this.prev(e.loop):n<-1&&this.next(e.loop));break}}w(i,a=>{a.startX=a.endX,a.startY=a.endY})},isSwitchable(){const{imageData:t,viewerData:e}=this;return this.length>1&&t.x>=0&&t.y>=0&&t.width<=e.width&&t.height<=e.height}},Ie=M.Viewer,Ne=(t=>()=>(t+=1,t))(-1);class ct{constructor(e,i={}){if(!e||e.nodeType!==1)throw new Error("The first argument is required and must be an element.");this.element=e,this.options=C({},St,X(i)&&i),this.action=!1,this.fading=!1,this.fulled=!1,this.hiding=!1,this.imageClicked=!1,this.imageData={},this.index=this.options.initialViewIndex,this.isImg=!1,this.isShown=!1,this.length=0,this.moving=!1,this.played=!1,this.playing=!1,this.pointers={},this.ready=!1,this.rotating=!1,this.scaling=!1,this.showing=!1,this.timeout=!1,this.tooltipping=!1,this.viewed=!1,this.viewing=!1,this.wheeling=!1,this.zooming=!1,this.pointerMoved=!1,this.id=Ne(),this.init()}init(){const{element:e,options:i}=this;if(e[f])return;e[f]=this,i.focus&&!i.keyboard&&(i.focus=!1);const s=e.localName==="img",n=[];if(w(s?[e]:e.querySelectorAll("img"),o=>{p(i.filter)?i.filter.call(this,o)&&n.push(o):this.getImageURL(o)&&n.push(o)}),this.isImg=s,this.length=n.length,this.images=n,this.initBody(),q(document.createElement(f).style.transition)&&(i.transition=!1),i.inline){let o=0;const a=()=>{if(o+=1,o===this.length){let r;this.initializing=!1,this.delaying={abort:()=>{clearTimeout(r)}},r=setTimeout(()=>{this.delaying=!1,this.build()},0)}};this.initializing={abort:()=>{w(n,r=>{r.complete||(b(r,k,a),b(r,W,a))})}},w(n,r=>{if(r.complete)a();else{let l,h;d(r,k,l=()=>{b(r,W,h),a()},{once:!0}),d(r,W,h=()=>{b(r,k,l),a()},{once:!0})}})}else d(e,Z,this.onStart=({target:o})=>{o.localName==="img"&&(!p(i.filter)||i.filter.call(this,o))&&this.view(this.images.indexOf(o))})}build(){if(this.ready)return;const{element:e,options:i}=this,s=e.parentNode,n=document.createElement("div");n.innerHTML=te;const o=n.querySelector(`.${f}-container`),a=o.querySelector(`.${f}-title`),r=o.querySelector(`.${f}-toolbar`),l=o.querySelector(`.${f}-navbar`),h=o.querySelector(`.${f}-button`),m=o.querySelector(`.${f}-canvas`);if(this.parent=s,this.viewer=o,this.title=a,this.toolbar=r,this.navbar=l,this.button=h,this.canvas=m,this.footer=o.querySelector(`.${f}-footer`),this.tooltipBox=o.querySelector(`.${f}-tooltip`),this.player=o.querySelector(`.${f}-player`),this.list=o.querySelector(`.${f}-list`),o.id=`${f}${this.id}`,a.id=`${f}Title${this.id}`,c(a,i.title?st(Array.isArray(i.title)?i.title[0]:i.title):F),c(l,i.navbar?st(i.navbar):F),tt(h,F,!i.button),i.keyboard&&h.setAttribute("tabindex",0),i.backdrop&&(c(o,`${f}-backdrop`),!i.inline&&i.backdrop!=="static"&&pt(m,lt,"hide")),Q(i.className)&&i.className&&i.className.split(wt).forEach(u=>{c(o,u)}),i.toolbar){const u=document.createElement("ul"),E=X(i.toolbar),N=it.slice(0,3),I=it.slice(7,9),A=it.slice(9);E||c(r,st(i.toolbar)),w(E?i.toolbar:it,(S,L)=>{const x=E&&X(S),R=E?Et(L):S,V=x&&!q(S.show)?S.show:S;if(!V||!i.zoomable&&N.indexOf(R)!==-1||!i.rotatable&&I.indexOf(R)!==-1||!i.scalable&&A.indexOf(R)!==-1)return;const $=x&&!q(S.size)?S.size:S,ut=x&&!q(S.click)?S.click:S,_=document.createElement("li");i.keyboard&&_.setAttribute("tabindex",0),_.setAttribute("role","button"),c(_,`${f}-${R}`),p(ut)||pt(_,lt,R),y(V)&&c(_,st(V)),["small","large"].indexOf($)!==-1?c(_,`${f}-${$}`):R==="play"&&c(_,`${f}-large`),p(ut)&&d(_,Z,ut),u.appendChild(_)}),r.appendChild(u)}else c(r,F);if(!i.rotatable){const u=r.querySelectorAll('li[class*="rotate"]');c(u,G),w(u,E=>{r.appendChild(E)})}if(i.inline)c(h,ie),O(o,{zIndex:i.zIndexInline}),window.getComputedStyle(s).position==="static"&&O(s,{position:"relative"}),s.insertBefore(o,e.nextSibling);else{c(h,ee),c(o,mt),c(o,at),c(o,F),O(o,{zIndex:i.zIndex});let{container:u}=i;Q(u)&&(u=e.ownerDocument.querySelector(u)),u||(u=this.body),u.appendChild(o)}if(i.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,p(i.ready)&&d(e,Rt,i.ready,{once:!0}),T(e,Rt)===!1){this.ready=!1;return}this.ready&&i.inline&&this.view(this.index)}static noConflict(){return window.Viewer=Ie,ct}static setDefaults(e){C(St,X(e)&&e)}}C(ct.prototype,Ee,ye,ve,Te,Se);function Ae(){document.querySelectorAll(".screen").forEach(e=>{const i=document.createElement("code");for(i.className="language-typescript";e.firstChild;)i.appendChild(e.firstChild);if(e.appendChild(i),i.offsetHeight>window.innerHeight*32/100){e.classList.add("fold");const s=document.createElement("div"),n=document.createElement("div");s.className="foldButton",n.className="divider",s.innerText="查看更多",e.appendChild(s),e.appendChild(n),s.addEventListener("click",()=>{e.classList.replace("fold","expand"),e.removeChild(s),e.removeChild(n)})}})}Ae();Qt.highlightAll();window.addEventListener("DOMContentLoaded",function(){Array.from(document.getElementsByTagName("img")).forEach((s,n)=>{s.dataset.original=s.src});const e=document.getElementsByClassName("nested0")[0],i=new ct(e,{filter(s){return s.id.length>0},fullscreen:!1,movable:!1,zoomable:!0,toggleOnDblclick:!0,navbar:!1,toolbar:!1,button:!1,title:function(s){return`${this.index+1}/${this.length}`},keyboard:!1,rotatable:!1,scalable:!1,initialCoverage:.75,minZoomRatio:.15,maxZoomRatio:1.2});window.checkPreview=()=>document.body.className==="viewer-open",window.closePreview=()=>{i.hide()}});function Ce(){const t=document.querySelectorAll(".figcap");t.forEach((e,i)=>{var n;const s=(n=e.nextElementSibling)==null?void 0:n.nextElementSibling;s&&s.insertAdjacentElement("afterend",e)}),t.forEach(e=>{e.classList.add("figcap-show")}),t.forEach(e=>{e.style.display="block"})}Ce();const xe=document.getElementsByTagName("object"),De=Array.from(xe);De.forEach(t=>{const e=document.createElement("video");e.controls=!0;const i=t.getAttribute("data");i&&(e.src=i);const s=t.getElementsByTagName("param");for(let o=0;o{dt.src=t.matches?"../../common/image/f_icon_dark.png":"../../common/image/f_icon.png"};Tt(vt);vt.addEventListener("change",Tt);window.addEventListener("beforeunload",()=>{vt.removeEventListener("change",Tt)}); +import{H as Qt}from"../../../dist/common.js";import"../../../dist/common2.js";const St={backdrop:!0,button:!0,navbar:!0,title:!0,toolbar:!0,className:"",container:"body",filter:null,fullscreen:!0,inheritedAttributes:["crossOrigin","decoding","isMap","loading","referrerPolicy","sizes","srcset","useMap"],initialCoverage:.9,initialViewIndex:0,inline:!1,interval:5e3,keyboard:!0,focus:!0,loading:!0,loop:!0,minWidth:200,minHeight:100,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,slideOnTouch:!0,toggleOnDblclick:!0,tooltip:!0,transition:!0,zIndex:2015,zIndexInline:0,zoomRatio:.1,minZoomRatio:.01,maxZoomRatio:100,url:"src",ready:null,show:null,shown:null,hide:null,hidden:null,view:null,viewed:null,move:null,moved:null,rotate:null,rotated:null,scale:null,scaled:null,zoom:null,zoomed:null,play:null,stop:null},te='
',ht=typeof window<"u"&&typeof window.document<"u",V=ht?window:{},Y=ht&&V.document.documentElement?"ontouchstart"in V.document.documentElement:!1,bt=ht?"PointerEvent"in V:!1,f="viewer",ot="move",Kt="switch",K="zoom",et=`${f}-active`,ee=`${f}-close`,rt=`${f}-fade`,mt=`${f}-fixed`,ie=`${f}-fullscreen`,It=`${f}-fullscreen-exit`,F=`${f}-hide`,se=`${f}-hide-md-down`,ne=`${f}-hide-sm-down`,oe=`${f}-hide-xs-down`,D=`${f}-in`,G=`${f}-invisible`,U=`${f}-loading`,re=`${f}-move`,Nt=`${f}-open`,H=`${f}-show`,v=`${f}-transition`,Z="click",gt="dblclick",At="dragstart",Ct="focusin",xt="keydown",k="load",W="error",ae=Y?"touchend touchcancel":"mouseup",le=Y?"touchmove":"mousemove",he=Y?"touchstart":"mousedown",Dt=bt?"pointerdown":he,kt=bt?"pointermove":le,Lt=bt?"pointerup pointercancel":ae,zt="resize",z="transitionend",Ot="wheel",Rt="ready",_t="show",Vt="shown",Mt="hide",$t="hidden",Ft="view",J="viewed",Wt="move",Ht="moved",Pt="rotate",qt="rotated",Xt="scale",Bt="scaled",Yt="zoom",Ut="zoomed",Zt="play",jt="stop",lt=`${f}Action`,wt=/\s\s*/,it=["zoom-in","zoom-out","one-to-one","reset","prev","play","next","rotate-left","rotate-right","flip-horizontal","flip-vertical"];function Q(t){return typeof t=="string"}const ce=Number.isNaN||V.isNaN;function y(t){return typeof t=="number"&&!ce(t)}function q(t){return typeof t>"u"}function j(t){return typeof t=="object"&&t!==null}const{hasOwnProperty:de}=Object.prototype;function X(t){if(!j(t))return!1;try{const{constructor:e}=t,{prototype:i}=e;return e&&i&&de.call(i,"isPrototypeOf")}catch{return!1}}function p(t){return typeof t=="function"}function w(t,e){if(t&&p(e))if(Array.isArray(t)||y(t.length)){const{length:i}=t;let s;for(s=0;s{e.call(t,t[i],i,t)});return t}const C=Object.assign||function(e,...i){return j(e)&&i.length>0&&i.forEach(s=>{j(s)&&Object.keys(s).forEach(n=>{e[n]=s[n]})}),e},ue=/^(?:width|height|left|top|marginLeft|marginTop)$/;function O(t,e){const{style:i}=t;w(e,(s,n)=>{ue.test(n)&&y(s)&&(s+="px"),i[n]=s})}function fe(t){return Q(t)?t.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"):t}function P(t,e){return!t||!e?!1:t.classList?t.classList.contains(e):t.className.indexOf(e)>-1}function c(t,e){if(!t||!e)return;if(y(t.length)){w(t,s=>{c(s,e)});return}if(t.classList){t.classList.add(e);return}const i=t.className.trim();i?i.indexOf(e)<0&&(t.className=`${i} ${e}`):t.className=e}function g(t,e){if(!(!t||!e)){if(y(t.length)){w(t,i=>{g(i,e)});return}if(t.classList){t.classList.remove(e);return}t.className.indexOf(e)>=0&&(t.className=t.className.replace(e,""))}}function tt(t,e,i){if(e){if(y(t.length)){w(t,s=>{tt(s,e,i)});return}i?c(t,e):g(t,e)}}const me=/([a-z\d])([A-Z])/g;function Et(t){return t.replace(me,"$1-$2").toLowerCase()}function B(t,e){return j(t[e])?t[e]:t.dataset?t.dataset[e]:t.getAttribute(`data-${Et(e)}`)}function pt(t,e,i){j(i)?t[e]=i:t.dataset?t.dataset[e]=i:t.setAttribute(`data-${Et(e)}`,i)}const Gt=(()=>{let t=!1;if(ht){let e=!1;const i=()=>{},s=Object.defineProperty({},"once",{get(){return t=!0,e},set(n){e=n}});V.addEventListener("test",i,s),V.removeEventListener("test",i,s)}return t})();function b(t,e,i,s={}){let n=i;e.trim().split(wt).forEach(o=>{if(!Gt){const{listeners:r}=t;r&&r[o]&&r[o][i]&&(n=r[o][i],delete r[o][i],Object.keys(r[o]).length===0&&delete r[o],Object.keys(r).length===0&&delete t.listeners)}t.removeEventListener(o,n,s)})}function d(t,e,i,s={}){let n=i;e.trim().split(wt).forEach(o=>{if(s.once&&!Gt){const{listeners:r={}}=t;n=(...a)=>{delete r[o][i],t.removeEventListener(o,n,s),i.apply(t,a)},r[o]||(r[o]={}),r[o][i]&&t.removeEventListener(o,r[o][i],s),r[o][i]=n,t.listeners=r}t.addEventListener(o,n,s)})}function T(t,e,i,s){let n;return p(Event)&&p(CustomEvent)?n=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:i,...s}):(n=document.createEvent("CustomEvent"),n.initCustomEvent(e,!0,!0,i)),t.dispatchEvent(n)}function ge(t){const e=t.getBoundingClientRect();return{left:e.left+(window.pageXOffset-document.documentElement.clientLeft),top:e.top+(window.pageYOffset-document.documentElement.clientTop)}}function at({rotate:t,scaleX:e,scaleY:i,translateX:s,translateY:n}){const o=[];y(s)&&s!==0&&o.push(`translateX(${s}px)`),y(n)&&n!==0&&o.push(`translateY(${n}px)`),y(t)&&t!==0&&o.push(`rotate(${t}deg)`),y(e)&&e!==1&&o.push(`scaleX(${e})`),y(i)&&i!==1&&o.push(`scaleY(${i})`);const r=o.length?o.join(" "):"none";return{WebkitTransform:r,msTransform:r,transform:r}}function pe(t){return Q(t)?decodeURIComponent(t.replace(/^.*\//,"").replace(/[?&#].*$/,"")):""}const ft=V.navigator&&/Version\/\d+(\.\d+)+?\s+Safari/i.test(V.navigator.userAgent);function Jt(t,e,i){const s=document.createElement("img");if(t.naturalWidth&&!ft)return i(t.naturalWidth,t.naturalHeight),s;const n=document.body||document.documentElement;return s.onload=()=>{i(s.width,s.height),ft||n.removeChild(s)},w(e.inheritedAttributes,o=>{const r=t.getAttribute(o);r!==null&&s.setAttribute(o,r)}),s.src=t.src,ft||(s.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",n.appendChild(s)),s}function st(t){switch(t){case 2:return oe;case 3:return ne;case 4:return se;default:return""}}function be(t){const e={...t},i=[];return w(t,(s,n)=>{delete e[n],w(e,o=>{const r=Math.abs(s.startX-o.startX),a=Math.abs(s.startY-o.startY),l=Math.abs(s.endX-o.endX),h=Math.abs(s.endY-o.endY),m=Math.sqrt(r*r+a*a),E=(Math.sqrt(l*l+h*h)-m)/m;i.push(E)})}),i.sort((s,n)=>Math.abs(s){e+=n,i+=o,s+=1}),e/=s,i/=s,{pageX:e,pageY:i}}const Ee={render(){this.initContainer(),this.initViewer(),this.initList(),this.renderViewer()},initBody(){const{ownerDocument:t}=this.element,e=t.body||t.documentElement;this.body=e,this.scrollbarWidth=window.innerWidth-t.documentElement.clientWidth,this.initialBodyPaddingRight=e.style.paddingRight,this.initialBodyComputedPaddingRight=window.getComputedStyle(e).paddingRight},initContainer(){this.containerData={width:window.innerWidth,height:window.innerHeight}},initViewer(){const{options:t,parent:e}=this;let i;t.inline&&(i={width:Math.max(e.offsetWidth,t.minWidth),height:Math.max(e.offsetHeight,t.minHeight)},this.parentData=i),(this.fulled||!i)&&(i=this.containerData),this.viewerData=C({},i)},renderViewer(){this.options.inline&&!this.fulled&&O(this.viewer,this.viewerData)},initList(){const{element:t,options:e,list:i}=this,s=[];i.innerHTML="",w(this.images,(n,o)=>{const{src:r}=n,a=n.alt||pe(r),l=this.getImageURL(n);if(r||l){const h=document.createElement("li"),m=document.createElement("img");w(e.inheritedAttributes,u=>{const E=n.getAttribute(u);E!==null&&m.setAttribute(u,E)}),e.navbar&&(m.src=r||l),m.alt=a,m.setAttribute("data-original-url",l||r),h.setAttribute("data-index",o),h.setAttribute("data-viewer-action","view"),h.setAttribute("role","button"),e.keyboard&&h.setAttribute("tabindex",0),h.appendChild(m),i.appendChild(h),s.push(h)}}),this.items=s,w(s,n=>{const o=n.firstElementChild;let r,a;pt(o,"filled",!0),e.loading&&c(n,U),d(o,k,r=l=>{b(o,W,a),e.loading&&g(n,U),this.loadImage(l)},{once:!0}),d(o,W,a=()=>{b(o,k,r),e.loading&&g(n,U)},{once:!0})}),e.transition&&d(t,J,()=>{c(i,v)},{once:!0})},renderList(){const{index:t}=this,e=this.items[t];if(!e)return;const i=e.nextElementSibling,s=parseInt(window.getComputedStyle(i||e).marginLeft,10),{offsetWidth:n}=e,o=n+s;O(this.list,C({width:o*this.length-s},at({translateX:(this.viewerData.width-n)/2-o*t})))},resetList(){const{list:t}=this;t.innerHTML="",g(t,v),O(t,at({translateX:0}))},initImage(t){const{options:e,image:i,viewerData:s}=this,n=this.footer.offsetHeight,o=s.width,r=Math.max(s.height-n,n),a=this.imageData||{};let l;this.imageInitializing={abort:()=>{l.onload=null}},l=Jt(i,e,(h,m)=>{const u=h/m;let E=Math.max(0,Math.min(1,e.initialCoverage)),N=o,I=r;this.imageInitializing=!1,r*u>o?I=o/u:N=r*u,E=y(E)?E:.9,N=Math.min(N*E,h),I=Math.min(I*E,m);const A=(o-N)/2,S=(r-I)/2,L={left:A,top:S,x:A,y:S,width:N,height:I,oldRatio:1,ratio:N/h,aspectRatio:u,naturalWidth:h,naturalHeight:m},x=C({},L);e.rotatable&&(L.rotate=a.rotate||0,x.rotate=0),e.scalable&&(L.scaleX=a.scaleX||1,L.scaleY=a.scaleY||1,x.scaleX=1,x.scaleY=1),this.imageData=L,this.initialImageData=x,t&&t()})},renderImage(t){const{image:e,imageData:i}=this;if(O(e,C({width:i.width,height:i.height,marginLeft:i.x,marginTop:i.y},at(i))),t)if((this.viewing||this.moving||this.rotating||this.scaling||this.zooming)&&this.options.transition&&P(e,v)){const s=()=>{this.imageRendering=!1,t()};this.imageRendering={abort:()=>{b(e,z,s)}},d(e,z,s,{once:!0})}else t()},resetImage(){const{image:t}=this;t&&(this.viewing&&this.viewing.abort(),t.parentNode.removeChild(t),this.image=null,this.title.innerHTML="")}},ye={bind(){const{options:t,viewer:e,canvas:i}=this,s=this.element.ownerDocument;d(e,Z,this.onClick=this.click.bind(this)),d(e,At,this.onDragStart=this.dragstart.bind(this)),d(i,Dt,this.onPointerDown=this.pointerdown.bind(this)),d(s,kt,this.onPointerMove=this.pointermove.bind(this)),d(s,Lt,this.onPointerUp=this.pointerup.bind(this)),d(s,xt,this.onKeyDown=this.keydown.bind(this)),d(window,zt,this.onResize=this.resize.bind(this)),t.zoomable&&t.zoomOnWheel&&d(e,Ot,this.onWheel=this.wheel.bind(this),{passive:!1,capture:!0}),t.toggleOnDblclick&&d(i,gt,this.onDblclick=this.dblclick.bind(this))},unbind(){const{options:t,viewer:e,canvas:i}=this,s=this.element.ownerDocument;b(e,Z,this.onClick),b(e,At,this.onDragStart),b(i,Dt,this.onPointerDown),b(s,kt,this.onPointerMove),b(s,Lt,this.onPointerUp),b(s,xt,this.onKeyDown),b(window,zt,this.onResize),t.zoomable&&t.zoomOnWheel&&b(e,Ot,this.onWheel,{passive:!1,capture:!0}),t.toggleOnDblclick&&b(i,gt,this.onDblclick)}},ve={click(t){const{options:e,imageData:i}=this;let{target:s}=t,n=B(s,lt);switch(!n&&s.localName==="img"&&s.parentElement.localName==="li"&&(s=s.parentElement,n=B(s,lt)),Y&&t.isTrusted&&s===this.canvas&&clearTimeout(this.clickCanvasTimeout),n){case"mix":this.played?this.stop():e.inline?this.fulled?this.exit():this.full():this.hide();break;case"hide":this.pointerMoved||this.hide();break;case"view":this.view(B(s,"index"));break;case"zoom-in":this.zoom(.1,!0);break;case"zoom-out":this.zoom(-.1,!0);break;case"one-to-one":this.toggle();break;case"reset":this.reset();break;case"prev":this.prev(e.loop);break;case"play":this.play(e.fullscreen);break;case"next":this.next(e.loop);break;case"rotate-left":this.rotate(-90);break;case"rotate-right":this.rotate(90);break;case"flip-horizontal":this.scaleX(-i.scaleX||-1);break;case"flip-vertical":this.scaleY(-i.scaleY||-1);break;default:this.played&&this.stop()}},dblclick(t){t.preventDefault(),this.viewed&&t.target===this.image&&(Y&&t.isTrusted&&clearTimeout(this.doubleClickImageTimeout),this.toggle(t.isTrusted?t:t.detail&&t.detail.originalEvent))},load(){this.timeout&&(clearTimeout(this.timeout),this.timeout=!1);const{element:t,options:e,image:i,index:s,viewerData:n}=this;g(i,G),e.loading&&g(this.canvas,U),i.style.cssText=`height:0;margin-left:${n.width/2}px;margin-top:${n.height/2}px;max-width:none!important;position:relative;width:0;`,this.initImage(()=>{tt(i,re,e.movable),tt(i,v,e.transition),this.renderImage(()=>{this.viewed=!0,this.viewing=!1,p(e.viewed)&&d(t,J,e.viewed,{once:!0}),T(t,J,{originalImage:this.images[s],index:s,image:i},{cancelable:!1})})})},loadImage(t){const e=t.target,i=e.parentNode,s=i.offsetWidth||30,n=i.offsetHeight||50,o=!!B(e,"filled");Jt(e,this.options,(r,a)=>{const l=r/a;let h=s,m=n;n*l>s?o?h=n*l:m=s/l:o?m=s/l:h=n*l,O(e,C({width:h,height:m},at({translateX:(s-h)/2,translateY:(n-m)/2})))})},keydown(t){const{options:e}=this;if(!e.keyboard)return;const i=t.keyCode||t.which||t.charCode;switch(i){case 13:this.viewer.contains(t.target)&&this.click(t);break}if(this.fulled)switch(i){case 27:this.played?this.stop():e.inline?this.fulled&&this.exit():this.hide();break;case 32:this.played&&this.stop();break;case 37:this.played&&this.playing?this.playing.prev():this.prev(e.loop);break;case 38:t.preventDefault(),this.zoom(e.zoomRatio,!0);break;case 39:this.played&&this.playing?this.playing.next():this.next(e.loop);break;case 40:t.preventDefault(),this.zoom(-e.zoomRatio,!0);break;case 48:case 49:t.ctrlKey&&(t.preventDefault(),this.toggle());break}},dragstart(t){t.target.localName==="img"&&t.preventDefault()},pointerdown(t){const{options:e,pointers:i}=this,{buttons:s,button:n}=t;if(this.pointerMoved=!1,!this.viewed||this.showing||this.viewing||this.hiding||(t.type==="mousedown"||t.type==="pointerdown"&&t.pointerType==="mouse")&&(y(s)&&s!==1||y(n)&&n!==0||t.ctrlKey))return;t.preventDefault(),t.changedTouches?w(t.changedTouches,r=>{i[r.identifier]=nt(r)}):i[t.pointerId||0]=nt(t);let o=e.movable?ot:!1;e.zoomOnTouch&&e.zoomable&&Object.keys(i).length>1?o=K:e.slideOnTouch&&(t.pointerType==="touch"||t.type==="touchstart")&&this.isSwitchable()&&(o=Kt),e.transition&&(o===ot||o===K)&&g(this.image,v),this.action=o},pointermove(t){const{pointers:e,action:i}=this;!this.viewed||!i||(t.preventDefault(),t.changedTouches?w(t.changedTouches,s=>{C(e[s.identifier]||{},nt(s,!0))}):C(e[t.pointerId||0]||{},nt(t,!0)),this.change(t))},pointerup(t){const{options:e,action:i,pointers:s}=this;let n;t.changedTouches?w(t.changedTouches,o=>{n=s[o.identifier],delete s[o.identifier]}):(n=s[t.pointerId||0],delete s[t.pointerId||0]),i&&(t.preventDefault(),e.transition&&(i===ot||i===K)&&c(this.image,v),this.action=!1,Y&&i!==K&&n&&Date.now()-n.timeStamp<500&&(clearTimeout(this.clickCanvasTimeout),clearTimeout(this.doubleClickImageTimeout),e.toggleOnDblclick&&this.viewed&&t.target===this.image?this.imageClicked?(this.imageClicked=!1,this.doubleClickImageTimeout=setTimeout(()=>{T(this.image,gt,{originalEvent:t})},50)):(this.imageClicked=!0,this.doubleClickImageTimeout=setTimeout(()=>{this.imageClicked=!1},500)):(this.imageClicked=!1,e.backdrop&&e.backdrop!=="static"&&t.target===this.canvas&&(this.clickCanvasTimeout=setTimeout(()=>{T(this.canvas,Z,{originalEvent:t})},50)))))},resize(){if(!(!this.isShown||this.hiding)&&(this.fulled&&(this.close(),this.initBody(),this.open()),this.initContainer(),this.initViewer(),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage()}),this.played)){if(this.options.fullscreen&&this.fulled&&!(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)){this.stop();return}w(this.player.getElementsByTagName("img"),t=>{d(t,k,this.loadImage.bind(this),{once:!0}),T(t,k)})}},wheel(t){if(!this.viewed||(t.preventDefault(),this.wheeling))return;this.wheeling=!0,setTimeout(()=>{this.wheeling=!1},50);const e=Number(this.options.zoomRatio)||.1;let i=1;t.deltaY?i=t.deltaY>0?1:-1:t.wheelDelta?i=-t.wheelDelta/120:t.detail&&(i=t.detail>0?1:-1),this.zoom(-i*e,!0,null,t)}},Te={show(t=!1){const{element:e,options:i}=this;if(i.inline||this.showing||this.isShown||this.showing)return this;if(!this.ready)return this.build(),this.ready&&this.show(t),this;if(p(i.show)&&d(e,_t,i.show,{once:!0}),T(e,_t)===!1||!this.ready)return this;this.hiding&&this.transitioning.abort(),this.showing=!0,this.open();const{viewer:s}=this;if(g(s,F),s.setAttribute("role","dialog"),s.setAttribute("aria-labelledby",this.title.id),s.setAttribute("aria-modal",!0),s.removeAttribute("aria-hidden"),i.transition&&!t){const n=this.shown.bind(this);this.transitioning={abort:()=>{b(s,z,n),g(s,D)}},c(s,v),s.initialOffsetWidth=s.offsetWidth,d(s,z,n,{once:!0}),c(s,D)}else c(s,D),this.shown();return this},hide(t=!1){const{element:e,options:i}=this;if(i.inline||this.hiding||!(this.isShown||this.showing))return this;if(p(i.hide)&&d(e,Mt,i.hide,{once:!0}),T(e,Mt)===!1)return this;this.showing&&this.transitioning.abort(),this.hiding=!0,this.played?this.stop():this.viewing&&this.viewing.abort();const{viewer:s,image:n}=this,o=()=>{g(s,D),this.hidden()};if(i.transition&&!t){const r=l=>{l&&l.target===s&&(b(s,z,r),this.hidden())},a=()=>{P(s,v)?(d(s,z,r),g(s,D)):o()};this.transitioning={abort:()=>{this.viewed&&P(n,v)?b(n,z,a):P(s,v)&&b(s,z,r)}},this.viewed&&P(n,v)?(d(n,z,a,{once:!0}),this.zoomTo(0,!1,null,null,!0)):a()}else o();return this},view(t=this.options.initialViewIndex){if(t=Number(t)||0,this.hiding||this.played||t<0||t>=this.length||this.viewed&&t===this.index)return this;if(!this.isShown)return this.index=t,this.show();this.viewing&&this.viewing.abort();const{element:e,options:i,title:s,canvas:n}=this,o=this.items[t],r=o.querySelector("img"),a=B(r,"originalUrl"),l=r.getAttribute("alt"),h=document.createElement("img");if(w(i.inheritedAttributes,I=>{const A=r.getAttribute(I);A!==null&&h.setAttribute(I,A)}),h.src=a,h.alt=l,p(i.view)&&d(e,Ft,i.view,{once:!0}),T(e,Ft,{originalImage:this.images[t],index:t,image:h})===!1||!this.isShown||this.hiding||this.played)return this;const m=this.items[this.index];m&&(g(m,et),m.removeAttribute("aria-selected")),c(o,et),o.setAttribute("aria-selected",!0),i.focus&&o.focus(),this.image=h,this.viewed=!1,this.index=t,this.imageData={},c(h,G),i.loading&&c(n,U),n.innerHTML="",n.appendChild(h),this.renderList(),s.innerHTML="";const u=()=>{const{imageData:I}=this,A=Array.isArray(i.title)?i.title[1]:i.title;s.innerHTML=fe(p(A)?A.call(this,h,I):`${l} (${I.naturalWidth} × ${I.naturalHeight})`)};let E,N;return d(e,J,u,{once:!0}),this.viewing={abort:()=>{b(e,J,u),h.complete?this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort():(h.src="",b(h,k,E),this.timeout&&clearTimeout(this.timeout))}},h.complete?this.load():(d(h,k,E=()=>{b(h,W,N),this.load()},{once:!0}),d(h,W,N=()=>{b(h,k,E),this.timeout&&(clearTimeout(this.timeout),this.timeout=!1),g(h,G),i.loading&&g(this.canvas,U)},{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>{g(h,G),this.timeout=!1},1e3)),this},prev(t=!1){let e=this.index-1;return e<0&&(e=t?this.length-1:0),this.view(e),this},next(t=!1){const e=this.length-1;let i=this.index+1;return i>e&&(i=t?0:e),this.view(i),this},move(t,e=t){const{imageData:i}=this;return this.moveTo(q(t)?t:i.x+Number(t),q(e)?e:i.y+Number(e)),this},moveTo(t,e=t,i=null){const{element:s,options:n,imageData:o}=this;if(t=Number(t),e=Number(e),this.viewed&&!this.played&&n.movable){const r=o.x,a=o.y;let l=!1;if(y(t)?l=!0:t=r,y(e)?l=!0:e=a,l){if(p(n.move)&&d(s,Wt,n.move,{once:!0}),T(s,Wt,{x:t,y:e,oldX:r,oldY:a,originalEvent:i})===!1)return this;o.x=t,o.y=e,o.left=t,o.top=e,this.moving=!0,this.renderImage(()=>{this.moving=!1,p(n.moved)&&d(s,Ht,n.moved,{once:!0}),T(s,Ht,{x:t,y:e,oldX:r,oldY:a,originalEvent:i},{cancelable:!1})})}}return this},rotate(t){return this.rotateTo((this.imageData.rotate||0)+Number(t)),this},rotateTo(t){const{element:e,options:i,imageData:s}=this;if(t=Number(t),y(t)&&this.viewed&&!this.played&&i.rotatable){const n=s.rotate;if(p(i.rotate)&&d(e,Pt,i.rotate,{once:!0}),T(e,Pt,{degree:t,oldDegree:n})===!1)return this;s.rotate=t,this.rotating=!0,this.renderImage(()=>{this.rotating=!1,p(i.rotated)&&d(e,qt,i.rotated,{once:!0}),T(e,qt,{degree:t,oldDegree:n},{cancelable:!1})})}return this},scaleX(t){return this.scale(t,this.imageData.scaleY),this},scaleY(t){return this.scale(this.imageData.scaleX,t),this},scale(t,e=t){const{element:i,options:s,imageData:n}=this;if(t=Number(t),e=Number(e),this.viewed&&!this.played&&s.scalable){const o=n.scaleX,r=n.scaleY;let a=!1;if(y(t)?a=!0:t=o,y(e)?a=!0:e=r,a){if(p(s.scale)&&d(i,Xt,s.scale,{once:!0}),T(i,Xt,{scaleX:t,scaleY:e,oldScaleX:o,oldScaleY:r})===!1)return this;n.scaleX=t,n.scaleY=e,this.scaling=!0,this.renderImage(()=>{this.scaling=!1,p(s.scaled)&&d(i,Bt,s.scaled,{once:!0}),T(i,Bt,{scaleX:t,scaleY:e,oldScaleX:o,oldScaleY:r},{cancelable:!1})})}}return this},zoom(t,e=!1,i=null,s=null){const{imageData:n}=this;return t=Number(t),t<0?t=1/(1-t):t=1+t,this.zoomTo(n.width*t/n.naturalWidth,e,i,s),this},zoomTo(t,e=!1,i=null,s=null,n=!1){const{element:o,options:r,pointers:a,imageData:l}=this,{x:h,y:m,width:u,height:E,naturalWidth:N,naturalHeight:I}=l;if(t=Math.max(0,t),y(t)&&this.viewed&&!this.played&&(n||r.zoomable)){if(!n){const M=Math.max(.01,r.minZoomRatio),$=Math.min(100,r.maxZoomRatio);t=Math.min(Math.max(t,M),$)}if(s)switch(s.type){case"wheel":r.zoomRatio>=.055&&t>.95&&t<1.05&&(t=1);break;case"pointermove":case"touchmove":case"mousemove":t>.99&&t<1.01&&(t=1);break}const A=N*t,S=I*t,L=A-u,x=S-E,R=l.ratio;if(p(r.zoom)&&d(o,Yt,r.zoom,{once:!0}),T(o,Yt,{ratio:t,oldRatio:R,originalEvent:s})===!1)return this;if(this.zooming=!0,s){const M=ge(this.viewer),$=a&&Object.keys(a).length>0?we(a):{pageX:s.pageX,pageY:s.pageY};l.x-=L*(($.pageX-M.left-h)/u),l.y-=x*(($.pageY-M.top-m)/E)}else X(i)&&y(i.x)&&y(i.y)?(l.x-=L*((i.x-h)/u),l.y-=x*((i.y-m)/E)):(l.x-=L/2,l.y-=x/2);l.left=l.x,l.top=l.y,l.width=A,l.height=S,l.oldRatio=R,l.ratio=t,this.renderImage(()=>{this.zooming=!1,p(r.zoomed)&&d(o,Ut,r.zoomed,{once:!0}),T(o,Ut,{ratio:t,oldRatio:R,originalEvent:s},{cancelable:!1})}),e&&this.tooltip()}return this},play(t=!1){if(!this.isShown||this.played)return this;const{element:e,options:i}=this;if(p(i.play)&&d(e,Zt,i.play,{once:!0}),T(e,Zt)===!1)return this;const{player:s}=this,n=this.loadImage.bind(this),o=[];let r=0,a=0;if(this.played=!0,this.onLoadWhenPlay=n,t&&this.requestFullscreen(t),c(s,H),w(this.items,(l,h)=>{const m=l.querySelector("img"),u=document.createElement("img");u.src=B(m,"originalUrl"),u.alt=m.getAttribute("alt"),u.referrerPolicy=m.referrerPolicy,r+=1,c(u,rt),tt(u,v,i.transition),P(l,et)&&(c(u,D),a=h),o.push(u),d(u,k,n,{once:!0}),s.appendChild(u)}),y(i.interval)&&i.interval>0){const l=()=>{clearTimeout(this.playing.timeout),g(o[a],D),a-=1,a=a>=0?a:r-1,c(o[a],D),this.playing.timeout=setTimeout(l,i.interval)},h=()=>{clearTimeout(this.playing.timeout),g(o[a],D),a+=1,a=a1&&(this.playing={prev:l,next:h,timeout:setTimeout(h,i.interval)})}return this},stop(){if(!this.played)return this;const{element:t,options:e}=this;if(p(e.stop)&&d(t,jt,e.stop,{once:!0}),T(t,jt)===!1)return this;const{player:i}=this;return clearTimeout(this.playing.timeout),this.playing=!1,this.played=!1,w(i.getElementsByTagName("img"),s=>{b(s,k,this.onLoadWhenPlay)}),g(i,H),i.innerHTML="",this.exitFullscreen(),this},full(){const{options:t,viewer:e,image:i,list:s}=this;return!this.isShown||this.played||this.fulled||!t.inline?this:(this.fulled=!0,this.open(),c(this.button,It),t.transition&&(g(s,v),this.viewed&&g(i,v)),c(e,mt),e.setAttribute("role","dialog"),e.setAttribute("aria-labelledby",this.title.id),e.setAttribute("aria-modal",!0),e.removeAttribute("style"),O(e,{zIndex:t.zIndex}),t.focus&&this.enforceFocus(),this.initContainer(),this.viewerData=C({},this.containerData),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage(()=>{t.transition&&setTimeout(()=>{c(i,v),c(s,v)},0)})}),this)},exit(){const{options:t,viewer:e,image:i,list:s}=this;return!this.isShown||this.played||!this.fulled||!t.inline?this:(this.fulled=!1,this.close(),g(this.button,It),t.transition&&(g(s,v),this.viewed&&g(i,v)),t.focus&&this.clearEnforceFocus(),e.removeAttribute("role"),e.removeAttribute("aria-labelledby"),e.removeAttribute("aria-modal"),g(e,mt),O(e,{zIndex:t.zIndexInline}),this.viewerData=C({},this.parentData),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(()=>{this.renderImage(()=>{t.transition&&setTimeout(()=>{c(i,v),c(s,v)},0)})}),this)},tooltip(){const{options:t,tooltipBox:e,imageData:i}=this;return!this.viewed||this.played||!t.tooltip?this:(e.textContent=`${Math.round(i.ratio*100)}%`,this.tooltipping?clearTimeout(this.tooltipping):t.transition?(this.fading&&T(e,z),c(e,H),c(e,rt),c(e,v),e.removeAttribute("aria-hidden"),e.initialOffsetWidth=e.offsetWidth,c(e,D)):(c(e,H),e.removeAttribute("aria-hidden")),this.tooltipping=setTimeout(()=>{t.transition?(d(e,z,()=>{g(e,H),g(e,rt),g(e,v),e.setAttribute("aria-hidden",!0),this.fading=!1},{once:!0}),g(e,D),this.fading=!0):(g(e,H),e.setAttribute("aria-hidden",!0)),this.tooltipping=!1},1e3),this)},toggle(t=null){return this.imageData.ratio===1?this.zoomTo(this.imageData.oldRatio,!0,null,t):this.zoomTo(1,!0,null,t),this},reset(){return this.viewed&&!this.played&&(this.imageData=C({},this.initialImageData),this.renderImage()),this},update(){const{element:t,options:e,isImg:i}=this;if(i&&!t.parentNode)return this.destroy();const s=[];if(w(i?[t]:t.querySelectorAll("img"),n=>{p(e.filter)?e.filter.call(this,n)&&s.push(n):this.getImageURL(n)&&s.push(n)}),!s.length)return this;if(this.images=s,this.length=s.length,this.ready){const n=[];if(w(this.items,(o,r)=>{const a=o.querySelector("img"),l=s[r];l&&a?(l.src!==a.src||l.alt!==a.alt)&&n.push(r):n.push(r)}),O(this.list,{width:"auto"}),this.initList(),this.isShown)if(this.length){if(this.viewed){const o=n.indexOf(this.index);if(o>=0)this.viewed=!1,this.view(Math.max(Math.min(this.index-o,this.length-1),0));else{const r=this.items[this.index];c(r,et),r.setAttribute("aria-selected",!0)}}}else this.image=null,this.viewed=!1,this.index=0,this.imageData={},this.canvas.innerHTML="",this.title.innerHTML=""}else this.build();return this},destroy(){const{element:t,options:e}=this;return t[f]?(this.destroyed=!0,this.ready?(this.played&&this.stop(),e.inline?(this.fulled&&this.exit(),this.unbind()):this.isShown?(this.viewing&&(this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort()),this.hiding&&this.transitioning.abort(),this.hidden()):this.showing&&(this.transitioning.abort(),this.hidden()),this.ready=!1,this.viewer.parentNode.removeChild(this.viewer)):e.inline&&(this.delaying?this.delaying.abort():this.initializing&&this.initializing.abort()),e.inline||b(t,Z,this.onStart),t[f]=void 0,this):this}},Se={getImageURL(t){let{url:e}=this.options;return Q(e)?e=t.getAttribute(e):p(e)?e=e.call(this,t):e="",e},enforceFocus(){this.clearEnforceFocus(),d(document,Ct,this.onFocusin=t=>{const{viewer:e}=this;let{target:i}=t;if(!(i===document||i===e||e.contains(i))){for(;i;){if(i.getAttribute("tabindex")!==null||i.getAttribute("aria-modal")==="true")return;i=i.parentElement}e.focus()}})},clearEnforceFocus(){this.onFocusin&&(b(document,Ct,this.onFocusin),this.onFocusin=null)},open(){const{body:t}=this;c(t,Nt),this.scrollbarWidth>0&&(t.style.paddingRight=`${this.scrollbarWidth+(parseFloat(this.initialBodyComputedPaddingRight)||0)}px`)},close(){const{body:t}=this;g(t,Nt),this.scrollbarWidth>0&&(t.style.paddingRight=this.initialBodyPaddingRight)},shown(){const{element:t,options:e,viewer:i}=this;this.fulled=!0,this.isShown=!0,this.render(),this.bind(),this.showing=!1,e.focus&&(i.focus(),this.enforceFocus()),p(e.shown)&&d(t,Vt,e.shown,{once:!0}),T(t,Vt)!==!1&&this.ready&&this.isShown&&!this.hiding&&this.view(this.index)},hidden(){const{element:t,options:e,viewer:i}=this;e.fucus&&this.clearEnforceFocus(),this.close(),this.unbind(),c(i,F),i.removeAttribute("role"),i.removeAttribute("aria-labelledby"),i.removeAttribute("aria-modal"),i.setAttribute("aria-hidden",!0),this.resetList(),this.resetImage(),this.fulled=!1,this.viewed=!1,this.isShown=!1,this.hiding=!1,this.destroyed||(p(e.hidden)&&d(t,$t,e.hidden,{once:!0}),T(t,$t,null,{cancelable:!1}))},requestFullscreen(t){const e=this.element.ownerDocument;if(this.fulled&&!(e.fullscreenElement||e.webkitFullscreenElement||e.mozFullScreenElement||e.msFullscreenElement)){const{documentElement:i}=e;i.requestFullscreen?X(t)?i.requestFullscreen(t):i.requestFullscreen():i.webkitRequestFullscreen?i.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT):i.mozRequestFullScreen?i.mozRequestFullScreen():i.msRequestFullscreen&&i.msRequestFullscreen()}},exitFullscreen(){const t=this.element.ownerDocument;this.fulled&&(t.fullscreenElement||t.webkitFullscreenElement||t.mozFullScreenElement||t.msFullscreenElement)&&(t.exitFullscreen?t.exitFullscreen():t.webkitExitFullscreen?t.webkitExitFullscreen():t.mozCancelFullScreen?t.mozCancelFullScreen():t.msExitFullscreen&&t.msExitFullscreen())},change(t){const{options:e,pointers:i}=this,s=i[Object.keys(i)[0]];if(!s)return;const n=s.endX-s.startX,o=s.endY-s.startY;switch(this.action){case ot:(n!==0||o!==0)&&(this.pointerMoved=!0,this.move(n,o,t));break;case K:this.zoom(be(i),!1,null,t);break;case Kt:{this.action="switched";const r=Math.abs(n);r>1&&r>Math.abs(o)&&(this.pointers={},n>1?this.prev(e.loop):n<-1&&this.next(e.loop));break}}w(i,r=>{r.startX=r.endX,r.startY=r.endY})},isSwitchable(){const{imageData:t,viewerData:e}=this;return this.length>1&&t.x>=0&&t.y>=0&&t.width<=e.width&&t.height<=e.height}},Ie=V.Viewer,Ne=(t=>()=>(t+=1,t))(-1);class ct{constructor(e,i={}){if(!e||e.nodeType!==1)throw new Error("The first argument is required and must be an element.");this.element=e,this.options=C({},St,X(i)&&i),this.action=!1,this.fading=!1,this.fulled=!1,this.hiding=!1,this.imageClicked=!1,this.imageData={},this.index=this.options.initialViewIndex,this.isImg=!1,this.isShown=!1,this.length=0,this.moving=!1,this.played=!1,this.playing=!1,this.pointers={},this.ready=!1,this.rotating=!1,this.scaling=!1,this.showing=!1,this.timeout=!1,this.tooltipping=!1,this.viewed=!1,this.viewing=!1,this.wheeling=!1,this.zooming=!1,this.pointerMoved=!1,this.id=Ne(),this.init()}init(){const{element:e,options:i}=this;if(e[f])return;e[f]=this,i.focus&&!i.keyboard&&(i.focus=!1);const s=e.localName==="img",n=[];if(w(s?[e]:e.querySelectorAll("img"),o=>{p(i.filter)?i.filter.call(this,o)&&n.push(o):this.getImageURL(o)&&n.push(o)}),this.isImg=s,this.length=n.length,this.images=n,this.initBody(),q(document.createElement(f).style.transition)&&(i.transition=!1),i.inline){let o=0;const r=()=>{if(o+=1,o===this.length){let a;this.initializing=!1,this.delaying={abort:()=>{clearTimeout(a)}},a=setTimeout(()=>{this.delaying=!1,this.build()},0)}};this.initializing={abort:()=>{w(n,a=>{a.complete||(b(a,k,r),b(a,W,r))})}},w(n,a=>{if(a.complete)r();else{let l,h;d(a,k,l=()=>{b(a,W,h),r()},{once:!0}),d(a,W,h=()=>{b(a,k,l),r()},{once:!0})}})}else d(e,Z,this.onStart=({target:o})=>{o.localName==="img"&&(!p(i.filter)||i.filter.call(this,o))&&this.view(this.images.indexOf(o))})}build(){if(this.ready)return;const{element:e,options:i}=this,s=e.parentNode,n=document.createElement("div");n.innerHTML=te;const o=n.querySelector(`.${f}-container`),r=o.querySelector(`.${f}-title`),a=o.querySelector(`.${f}-toolbar`),l=o.querySelector(`.${f}-navbar`),h=o.querySelector(`.${f}-button`),m=o.querySelector(`.${f}-canvas`);if(this.parent=s,this.viewer=o,this.title=r,this.toolbar=a,this.navbar=l,this.button=h,this.canvas=m,this.footer=o.querySelector(`.${f}-footer`),this.tooltipBox=o.querySelector(`.${f}-tooltip`),this.player=o.querySelector(`.${f}-player`),this.list=o.querySelector(`.${f}-list`),o.id=`${f}${this.id}`,r.id=`${f}Title${this.id}`,c(r,i.title?st(Array.isArray(i.title)?i.title[0]:i.title):F),c(l,i.navbar?st(i.navbar):F),tt(h,F,!i.button),i.keyboard&&h.setAttribute("tabindex",0),i.backdrop&&(c(o,`${f}-backdrop`),!i.inline&&i.backdrop!=="static"&&pt(m,lt,"hide")),Q(i.className)&&i.className&&i.className.split(wt).forEach(u=>{c(o,u)}),i.toolbar){const u=document.createElement("ul"),E=X(i.toolbar),N=it.slice(0,3),I=it.slice(7,9),A=it.slice(9);E||c(a,st(i.toolbar)),w(E?i.toolbar:it,(S,L)=>{const x=E&&X(S),R=E?Et(L):S,M=x&&!q(S.show)?S.show:S;if(!M||!i.zoomable&&N.indexOf(R)!==-1||!i.rotatable&&I.indexOf(R)!==-1||!i.scalable&&A.indexOf(R)!==-1)return;const $=x&&!q(S.size)?S.size:S,ut=x&&!q(S.click)?S.click:S,_=document.createElement("li");i.keyboard&&_.setAttribute("tabindex",0),_.setAttribute("role","button"),c(_,`${f}-${R}`),p(ut)||pt(_,lt,R),y(M)&&c(_,st(M)),["small","large"].indexOf($)!==-1?c(_,`${f}-${$}`):R==="play"&&c(_,`${f}-large`),p(ut)&&d(_,Z,ut),u.appendChild(_)}),a.appendChild(u)}else c(a,F);if(!i.rotatable){const u=a.querySelectorAll('li[class*="rotate"]');c(u,G),w(u,E=>{a.appendChild(E)})}if(i.inline)c(h,ie),O(o,{zIndex:i.zIndexInline}),window.getComputedStyle(s).position==="static"&&O(s,{position:"relative"}),s.insertBefore(o,e.nextSibling);else{c(h,ee),c(o,mt),c(o,rt),c(o,F),O(o,{zIndex:i.zIndex});let{container:u}=i;Q(u)&&(u=e.ownerDocument.querySelector(u)),u||(u=this.body),u.appendChild(o)}if(i.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,p(i.ready)&&d(e,Rt,i.ready,{once:!0}),T(e,Rt)===!1){this.ready=!1;return}this.ready&&i.inline&&this.view(this.index)}static noConflict(){return window.Viewer=Ie,ct}static setDefaults(e){C(St,X(e)&&e)}}C(ct.prototype,Ee,ye,ve,Te,Se);function Ae(){document.querySelectorAll(".screen").forEach(e=>{const i=document.createElement("code");for(i.className="language-typescript";e.firstChild;)i.appendChild(e.firstChild);if(e.appendChild(i),i.offsetHeight>window.innerHeight*32/100){e.classList.add("fold");const s=document.createElement("div"),n=document.createElement("div");s.className="foldButton",n.className="divider",s.innerText="查看更多",e.appendChild(s),e.appendChild(n),s.addEventListener("click",()=>{e.classList.replace("fold","expand"),e.removeChild(s),e.removeChild(n)})}})}Ae();Qt.highlightAll();window.addEventListener("DOMContentLoaded",function(){Array.from(document.getElementsByTagName("img")).forEach((s,n)=>{s.dataset.original=s.src});const e=document.getElementsByClassName("nested0")[0],i=new ct(e,{filter(s){return s.id.length>0},fullscreen:!1,movable:!1,zoomable:!0,toggleOnDblclick:!0,navbar:!1,toolbar:!1,button:!1,title:function(s){return`${this.index+1}/${this.length}`},keyboard:!1,rotatable:!1,scalable:!1,initialCoverage:.75,minZoomRatio:.15,maxZoomRatio:1.2});window.checkPreview=()=>document.body.className==="viewer-open",window.closePreview=()=>{i.hide()}});function Ce(){const t=document.querySelectorAll(".figcap");t.forEach((e,i)=>{var n;const s=(n=e.nextElementSibling)==null?void 0:n.nextElementSibling;s&&s.insertAdjacentElement("afterend",e)}),t.forEach(e=>{e.classList.add("figcap-show")}),t.forEach(e=>{e.style.display="block"})}Ce();const xe=document.getElementsByTagName("object"),De=Array.from(xe);De.forEach(t=>{const e=document.createElement("video");e.controls=!0;const i=t.getAttribute("data");i&&(e.src=i);const s=t.getElementsByTagName("param");for(let o=0;o{dt.src=t.matches?"../../common/image/f_icon_dark.png":"../../common/image/f_icon.png"};Tt(vt);vt.addEventListener("change",Tt);window.addEventListener("beforeunload",()=>{vt.removeEventListener("change",Tt)}); diff --git a/products/phone/src/main/resources/resfile/bannercols/hmos-world/image/video_devp.jpeg b/products/phone/src/main/resources/resfile/bannercols/hmos-world/image/video_devp.jpeg index aa4efce9dfd4eb85075359240766c87eac0ed66d..6f2ba43bd61445819c12da734e7168e7fbf2585e 100644 Binary files a/products/phone/src/main/resources/resfile/bannercols/hmos-world/image/video_devp.jpeg and b/products/phone/src/main/resources/resfile/bannercols/hmos-world/image/video_devp.jpeg differ diff --git a/products/phone/src/main/resources/zh_CN/element/string.json b/products/phone/src/main/resources/zh_CN/element/string.json index cff753a8ade6411a19cbdf8a3e84c64fc78fba2b..57039aba1e49790c8e28f1950b5bf080b61422f0 100644 --- a/products/phone/src/main/resources/zh_CN/element/string.json +++ b/products/phone/src/main/resources/zh_CN/element/string.json @@ -9,7 +9,7 @@ "value": "description" }, { - "name": "EntryAbility_label", + "name": "HMOSAbility_label", "value": "HMOS代码工坊" }, { diff --git a/products/wearable/src/main/ets/model/WearableSampleModel.ets b/products/wearable/src/main/ets/model/WearableSampleModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..05030b6a6863d844d40e1d54bac9417911413d0e --- /dev/null +++ b/products/wearable/src/main/ets/model/WearableSampleModel.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { WearableSampleService } from '../service/WearableSampleService'; +import { WearableSampleData } from './WearableSampleData'; + +const TAG = '[WearableSampleModel]'; + +export class WearableSampleModel { + private static instance: WearableSampleModel; + private service: WearableSampleService = new WearableSampleService(); + + private constructor() { + } + + public static getInstance(): WearableSampleModel { + if (!WearableSampleModel.instance) { + WearableSampleModel.instance = new WearableSampleModel(); + } + return WearableSampleModel.instance; + } + + public getWearableSampleList(): Promise { + return this.service.getWearableSampleListByMock() + .then((data: WearableSampleData[]) => { + return data; + }) + } +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/pages/MainPage.ets b/products/wearable/src/main/ets/pages/MainPage.ets index a345fe548fc25e68de08e49b484ec6dc3d6d25aa..5ef999dc62b5ff628ce9faf4c1543f9754d8ce4c 100644 --- a/products/wearable/src/main/ets/pages/MainPage.ets +++ b/products/wearable/src/main/ets/pages/MainPage.ets @@ -14,37 +14,36 @@ */ import { ArcSwiper, ArcSwiperAttribute, ArcSwiperController } from '@kit.ArkUI'; -import { MockRequest } from '@ohos/common'; import { HomePageComponent } from '../component/HomepageComponent'; -import { SampleListComponent } from '../component/SampleListComponent'; -import { WearableSampleData } from '../model/WearableSampleData'; +import { SampleListView } from '../view/SampleListView'; -const WEARABLE_SAMPLE_TRIGGER: string = 'wearable-sample-list'; - -@Entry @Component struct MainPage { private wearableSwiperController: ArcSwiperController = new ArcSwiperController(); - private wearableSampleList: WearableSampleData[] = []; - - aboutToAppear(): void { - MockRequest.call(WEARABLE_SAMPLE_TRIGGER) - .then((result: WearableSampleData[]) => { - this.wearableSampleList = result; - }) - } build() { - ArcSwiper(this.wearableSwiperController) { - HomePageComponent() - .onClick(() => { - this.wearableSwiperController.showNext(); - }) - SampleListComponent({ wearableSampleList: this.wearableSampleList }) + NavDestination() { + ArcSwiper(this.wearableSwiperController) { + HomePageComponent() + .onClick(() => { + this.wearableSwiperController.showNext(); + }) + SampleListView() + } + .indicator(false) + .onDigitalCrown((event: CrownEvent) => { + event.stopPropagation(); + }) } - .indicator(false) - .onDigitalCrown((event: CrownEvent) => { - event.stopPropagation(); - }) + .backgroundColor(Color.Black) + .transition(TransitionEffect.OPACITY) + .hideTitleBar(true) + .height('100%') + .width('100%') } +} + +@Builder +export function MainPageBuilder() { + MainPage() } \ No newline at end of file diff --git a/products/wearable/src/main/ets/pages/SplashPage.ets b/products/wearable/src/main/ets/pages/SplashPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..787327328e4f8ba148815f020b957047e92afc8e --- /dev/null +++ b/products/wearable/src/main/ets/pages/SplashPage.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonConstants, PageContext } from '@ohos/common'; +import { SplashEventTypeEnum, SplashViewModel } from '../viewmodel/SplashViewModel'; + +const TAG: string = '[SplashPage]'; + +@Entry +@Component +struct SplashPage { + private pageContext: PageContext = AppStorage.get('pageContext') as PageContext; + private appPathInfo: NavPathStack = this.pageContext.navPathStack; + private viewModel: SplashViewModel = new SplashViewModel(); + + aboutToAppear(): void { + this.viewModel.sendEvent(SplashEventTypeEnum.CHECK_FIRST_START); + this.getUIContext().animateTo({ + delay: CommonConstants.ANIMATION_DELAY, + duration: CommonConstants.ANIMATION_DURATION, + }, () => { + this.viewModel.sendEvent(SplashEventTypeEnum.JUMP_TO_MAIN); + }) + } + + build() { + Navigation(this.appPathInfo) { + Column() + .width('100%') + .height('100%') + .backgroundColor($r('app.color.start_window_background')) + } + .hideTitleBar(true) + .mode(NavigationMode.Stack) + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/service/WearableSampleService.ets b/products/wearable/src/main/ets/service/WearableSampleService.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba67266ecb9be4a0a2366d7a1f5778b248bc2178 --- /dev/null +++ b/products/wearable/src/main/ets/service/WearableSampleService.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BusinessError } from '@kit.BasicServicesKit'; +import { MockRequest } from '@ohos/common'; +import { WearableSampleData } from '../model/WearableSampleData'; + +const TAG: string = '[WearableSampleService]'; +const WEARABLE_SAMPLE_TRIGGER: string = 'wearable-sample-list'; + +export class WearableSampleService { + public constructor() { + } + + public getWearableSampleListByMock(): Promise { + return new Promise((resolve: (value: WearableSampleData[]) => void, + reject: (reason?: Object) => void) => { + MockRequest.call(WEARABLE_SAMPLE_TRIGGER) + .then((result: WearableSampleData[]) => { + resolve(result); + }) + .catch((error: BusinessError) => { + reject(error); + }) + }) + } +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/view/SampleListView.ets b/products/wearable/src/main/ets/view/SampleListView.ets new file mode 100644 index 0000000000000000000000000000000000000000..72699f6768e612c00f4e8af1dd1acaa0e93acd74 --- /dev/null +++ b/products/wearable/src/main/ets/view/SampleListView.ets @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ArcList, ArcListAttribute, ArcListItem, LengthMetrics, ComponentContent } from '@kit.ArkUI'; +import { MediaTypeEnum } from '@ohos/commonbusiness'; +import { WearableSampleData } from '../model/WearableSampleData'; +import { SampleListState } from '../viewmodel/SampleListState'; +import { + LoadSampleParam, + SampleListEventType, + SampleListViewModel +} from '../viewmodel/SampleListViewModel'; + +const ITEM_SPACE: number = 6; +const ITEM_WIDTH: string = '88%'; +const TAG: string = '[SampleListComponent]'; + +@Builder +function SampleListHeader() { + Column() { + Text($r('app.string.sample_library')) + .fontSize($r('app.float.item_title_size')) + .fontWeight(FontWeight.Bold) + .fontColor($r('sys.color.font_on_primary')) + .padding({ + top: $r('sys.float.padding_level3'), + bottom: $r('sys.float.padding_level2'), + }) + Text($r('app.string.watch_development_sample')) + .fontSize($r('sys.float.Subtitle_M')) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_on_secondary')) + } +} + +@Component +export struct SampleListView { + context: UIContext = this.getUIContext(); + sampleListHeader: ComponentContent<[]> = new ComponentContent(this.context, wrapBuilder(SampleListHeader)); + viewModel: SampleListViewModel = SampleListViewModel.getInstance(); + @State sampleListState: SampleListState = this.viewModel.getState(); + + aboutToAppear(): void { + this.viewModel.sendEvent({ + type: SampleListEventType.LOAD_SAMPLE_LIST, + }); + } + + @Builder + SampleListItem(wearableSampleData: WearableSampleData) { + Row() { + if (wearableSampleData.mediaType === MediaTypeEnum.SYMBOL) { + Button({ type: ButtonType.Circle }) { + SymbolGlyph($r(wearableSampleData.mediaUrl)) + .fontSize($r('app.float.icon_size')) + .fontColor([$r('sys.color.font_on_primary')]) + } + .width($r('app.float.button_size')) + .height($r('app.float.button_size')) + .backgroundColor(wearableSampleData.symbolGlyphColor) + } else if (wearableSampleData.mediaType == MediaTypeEnum.IMAGE) { + Image($r(wearableSampleData.mediaUrl)) + .width($r('app.float.button_size')) + .height($r('app.float.button_size')) + } + + Column() { + Text(wearableSampleData.title) + .fontWeight(FontWeight.Medium) + .fontColor($r('sys.color.font_on_primary')) + .fontSize($r('app.float.item_title_size')) + Text(wearableSampleData.desc) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_on_secondary')) + .fontSize($r('app.float.item_description_size')) + } + + SymbolGlyph($r('sys.symbol.chevron_forward')) + .fontSize($r('app.float.icon_size')) + .fontColor([$r('sys.color.icon_secondary')]) + } + .justifyContent(FlexAlign.SpaceBetween) + .width(ITEM_WIDTH) + .borderRadius($r('app.float.item_border_radius')) + .padding({ + top: $r('sys.float.padding_level6'), + bottom: $r('sys.float.padding_level5'), + left: $r('sys.float.padding_level3'), + right: $r('sys.float.padding_level3'), + }) + .backgroundColor($r('app.color.item_background')) + .onClick(() => { + this.viewModel.sendEvent({ + type: SampleListEventType.LOAD_SAMPLE, + param: { + abilityName: wearableSampleData.abilityName, + } + }); + }) + } + + build() { + ArcList({ header: this.sampleListHeader }) { + ForEach(this.sampleListState.wearableSampleList, (item: WearableSampleData) => { + ArcListItem() { + this.SampleListItem(item) + } + }, (item: WearableSampleData) => item.id.toString()) + } + .space(LengthMetrics.vp(ITEM_SPACE)) + .focusable(true) + .focusOnTouch(true) + .defaultFocus(true) + } +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/viewmodel/SampleListState.ets b/products/wearable/src/main/ets/viewmodel/SampleListState.ets new file mode 100644 index 0000000000000000000000000000000000000000..127c75b95d40db5692ffda1a5208e967d7727747 --- /dev/null +++ b/products/wearable/src/main/ets/viewmodel/SampleListState.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseState } from '@ohos/common'; +import { WearableSampleData } from '../model/WearableSampleData'; + +@Observed +export class SampleListState extends BaseState { + public wearableSampleList: WearableSampleData[] = []; +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/viewmodel/SampleListViewModel.ets b/products/wearable/src/main/ets/viewmodel/SampleListViewModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..470603adb5b8256a9741435f4c40bbc159fdf549 --- /dev/null +++ b/products/wearable/src/main/ets/viewmodel/SampleListViewModel.ets @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { common } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { BaseVM, Logger, ProcessUtil, StorageKey } from '@ohos/common'; +import { WearableSampleData } from '../model/WearableSampleData'; +import { WearableSampleModel } from '../model/WearableSampleModel'; +import { SampleListState } from './SampleListState'; + +const TAG = '[SampleListViewModel]'; + +export class SampleListViewModel extends BaseVM { + private static instance: SampleListViewModel; + private wearableSampleModel: WearableSampleModel = WearableSampleModel.getInstance(); + + private constructor() { + super(new SampleListState()); + } + + public static getInstance(): SampleListViewModel { + if (!SampleListViewModel.instance) { + SampleListViewModel.instance = new SampleListViewModel(); + } + return SampleListViewModel.instance; + } + + public sendEvent(eventParam: SampleListEventParam): void { + const eventType: SampleListEventType = eventParam.type; + if (eventType === SampleListEventType.LOAD_SAMPLE_LIST) { + this.loadWearableSampleList(); + } else if (eventType === SampleListEventType.LOAD_SAMPLE) { + this.loadSample(eventParam.param as LoadSampleParam); + } + } + + private loadWearableSampleList() { + this.wearableSampleModel.getWearableSampleList() + .then((result: WearableSampleData[]) => { + this.state.wearableSampleList = result; + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `load WearableSampleList Failed, ${error.code} ${error.message}`); + }) + } + + private loadSample(param: LoadSampleParam): void { + const uiContext: UIContext = AppStorage.get(StorageKey.UI_CONTEXT) as UIContext; + const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; + ProcessUtil.startAbility(context, { + bundleName: context.abilityInfo.bundleName, + abilityName: param.abilityName, + }); + } +} + +export enum SampleListEventType { + LOAD_SAMPLE_LIST = 'loadSamplePage', + LOAD_SAMPLE = 'loadSample', +} + +export interface SampleListEventParam { + type: SampleListEventType; + param?: T; +} + +export interface LoadSampleParam { + abilityName: string; +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/viewmodel/SplashViewModel.ets b/products/wearable/src/main/ets/viewmodel/SplashViewModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9e2a7ba54ed9b20a434935e826f5087db0ad3e4 --- /dev/null +++ b/products/wearable/src/main/ets/viewmodel/SplashViewModel.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseState, BaseVM, Logger, PageContext, PreferenceManager } from '@ohos/common'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const TAG: string = '[SplashViewModel]'; + +export class SplashViewModel extends BaseVM { + private pageContext: PageContext = AppStorage.get('pageContext') as PageContext; + private preferenceManager: PreferenceManager = PreferenceManager.getInstance(); + + public constructor() { + super(new BaseState()); + } + + public sendEvent(eventType: SplashEventTypeEnum): void { + if (eventType === SplashEventTypeEnum.JUMP_TO_MAIN) { + this.jumpToMainPage(); + } else if (eventType === SplashEventTypeEnum.CHECK_FIRST_START) { + this.checkIsFirstStart(); + } + } + + private jumpToMainPage(): void { + this.pageContext.replacePage({ + routerName: 'MainPage', + }); + } + + private checkIsFirstStart(): void { + this.preferenceManager.hasValue('isFirstStart').then((hasResult: boolean) => { + if (hasResult) { + Logger.info(TAG, 'Not first startup.'); + } else { + Logger.info(TAG, 'First startup.'); + this.preferenceManager.setValue('isFirstStart', false).then(() => { + Logger.info(TAG, 'Put the value of startup Successfully.'); + }).catch((err: BusinessError) => { + Logger.error(TAG, `Put the value of startup Failed, err code: ${err.code}, message: ${err.message}`); + }); + } + }).catch((err: BusinessError) => { + Logger.error(TAG, `check startup Failed, err code: ${err.code}, message: ${err.message}`); + }); + } +} + +export enum SplashEventTypeEnum { + JUMP_TO_MAIN = 'jumpToMainPage', + CHECK_FIRST_START = 'checkIsFirstStart', +} \ No newline at end of file diff --git a/products/wearable/src/main/ets/wearableability/WearableAbility.ets b/products/wearable/src/main/ets/wearableability/WearableAbility.ets index e71f0d9b22348741f108ee4a099810723b31cbfc..9e9fa5746e9f7dafd84f154ec37cdcb58a1e54f4 100644 --- a/products/wearable/src/main/ets/wearableability/WearableAbility.ets +++ b/products/wearable/src/main/ets/wearableability/WearableAbility.ets @@ -16,7 +16,7 @@ import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; -import { Logger } from '@ohos/common'; +import { Logger, PageContext, StorageKey } from '@ohos/common'; const TAG = '[WearableAbility]'; @@ -29,15 +29,37 @@ export default class WearableAbility extends UIAbility { Logger.info(TAG, 'Ability onDestroy'); } + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { + Logger.info(TAG, `onNewWant`); + this.checkAndHandleParams(want); + } + + checkAndHandleParams(want: Want): void { + Logger.info(TAG, `checkAndHandleParams`); + try { + if (want === null || want.parameters === null || want === undefined || want.parameters === undefined) { + return; + } + } catch (err) { + Logger.error(TAG, `checkAndHandleParams failed: ${err}`); + } + } + onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability Logger.info(TAG, 'Ability onWindowStageCreate'); + AppStorage.setOrCreate('pageContext', new PageContext()); - windowStage.loadContent('pages/MainPage', (err: BusinessError) => { + windowStage.loadContent('pages/SplashPage', (err: BusinessError) => { if (err.code) { Logger.error(TAG, `Failed to load the content. Cause: ${err.code} ${err.message}`); return; } + try { + AppStorage.setOrCreate(StorageKey.UI_CONTEXT, windowStage.getMainWindowSync().getUIContext()); + } catch (error) { + Logger.error(TAG, `setHostUIContext failed ${error}`); + } Logger.info(TAG, 'Succeeded in loading the content.'); }); } diff --git a/products/wearable/src/main/module.json5 b/products/wearable/src/main/module.json5 index f9baafa2b386db220f14037c428b24c241753d56..b0720610607a975f06c50ae2f10db18d02d2f3d8 100644 --- a/products/wearable/src/main/module.json5 +++ b/products/wearable/src/main/module.json5 @@ -10,6 +10,7 @@ "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", + "routerMap": "$profile:router_map", "abilities": [ { "name": "WearableAbility", @@ -26,7 +27,7 @@ "entity.system.home" ], "actions": [ - "action.system.home" + "ohos.want.action.home" ] } ] diff --git a/products/wearable/src/main/resources/base/media/ic_background_wearable.png b/products/wearable/src/main/resources/base/media/ic_background_wearable.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4ebb884d18fe3f81e83fbbe850e7ddee4dfee9 Binary files /dev/null and b/products/wearable/src/main/resources/base/media/ic_background_wearable.png differ diff --git a/products/wearable/src/main/resources/base/media/ic_foreground_wearable.png b/products/wearable/src/main/resources/base/media/ic_foreground_wearable.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc9e44f965c521a46fad6660b7fe6d091f45418 Binary files /dev/null and b/products/wearable/src/main/resources/base/media/ic_foreground_wearable.png differ diff --git a/products/wearable/src/main/resources/base/media/layered_image.json b/products/wearable/src/main/resources/base/media/layered_image.json index ab180cdfef55bcd5248e3aef53bad8d621a6443a..cbd3e7dfe456f995941237569b84cde07dc98418 100644 --- a/products/wearable/src/main/resources/base/media/layered_image.json +++ b/products/wearable/src/main/resources/base/media/layered_image.json @@ -1,7 +1,7 @@ { "layered-image": { - "background" : "$media:ic_background", - "foreground" : "$media:ic_foreground" + "background" : "$media:ic_background_wearable", + "foreground" : "$media:ic_foreground_wearable" } } \ No newline at end of file diff --git a/products/wearable/src/main/resources/base/profile/main_pages.json b/products/wearable/src/main/resources/base/profile/main_pages.json index f4241ef2f72e78047b4c449d92bd1a92accc39fb..4eff73327fce0b36ed61fe227e348ce7abb243d7 100644 --- a/products/wearable/src/main/resources/base/profile/main_pages.json +++ b/products/wearable/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,5 @@ { "src": [ - "pages/MainPage" + "pages/SplashPage" ] } diff --git a/products/wearable/src/main/resources/base/profile/router_map.json b/products/wearable/src/main/resources/base/profile/router_map.json new file mode 100644 index 0000000000000000000000000000000000000000..f7557702dbb78abbe9682fabebade00b2c719858 --- /dev/null +++ b/products/wearable/src/main/resources/base/profile/router_map.json @@ -0,0 +1,9 @@ +{ + "routerMap": [ + { + "name": "MainPage", + "pageSourceFile": "src/main/ets/pages/MainPage.ets", + "buildFunction": "MainPageBuilder" + } + ] +} \ No newline at end of file