diff --git a/entry/src/main/ets/generated/Index.ets b/entry/src/main/ets/generated/Index.ets new file mode 100644 index 0000000..c5da597 --- /dev/null +++ b/entry/src/main/ets/generated/Index.ets @@ -0,0 +1,43 @@ +import { EmptyPagePathStack } from './view/EmptyPagePathStack'; +import { SecondPageSearch } from './view/SecondPageSearch'; +import { BMICalculator } from './pages/BMICalculator'; + +@Entry +@Component +struct Index { + private scroller: Scroller = new Scroller(); + @Provide('appPathStack') appPathStack: NavPathStack = new NavPathStack(); + @State title: string = 'page_title'; + + @Builder + PageMap(name: string) { + if (name === 'SearchPage') { + SecondPageSearch() + } else { + EmptyPagePathStack() + } + } + + build() { + Navigation(this.appPathStack) { + Column() { + Scroll(this.scroller) { + Column() { + BMICalculator() + } + .width('100%') + .justifyContent(FlexAlign.Start) + .alignItems(HorizontalAlign.Start) + } + .scrollable(ScrollDirection.Vertical) + .scrollBar(BarState.Off) + .width('100%') + } + .backgroundColor('#F1F3F5') + .height('100%') + } + .navDestination(this.PageMap) + .hideTitleBar(true) + .mode(NavigationMode.Stack) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/common/BreakpointConstants.ets b/entry/src/main/ets/generated/common/BreakpointConstants.ets new file mode 100644 index 0000000..ba7f91c --- /dev/null +++ b/entry/src/main/ets/generated/common/BreakpointConstants.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Constants for breakpoint. + */ +export class BreakpointConstants { + /** + * Breakpoints that represent small device types. + */ + static readonly BREAKPOINT_SM: string = 'sm'; + /** + * Breakpoints that represent middle device types. + */ + static readonly BREAKPOINT_MD: string = 'md'; + /** + * Breakpoints that represent large device types. + */ + static readonly BREAKPOINT_LG: string = 'lg'; + /** + * Grid row column list. + */ + static readonly GRID_ROW_COLUMNS: number[] = [12, 15, 4]; + /** + * Grid column span list. + */ + static readonly GRID_COLUMN_SPANS: number[] = [12, 6, 7, 5, 3, 4, 2]; + /** + * Breakpoint ranges. + */ + static readonly BREAKPOINT_RANGES: number[] = [320, 600, 840]; +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/common/CommonConstants.ets b/entry/src/main/ets/generated/common/CommonConstants.ets new file mode 100644 index 0000000..31afa29 --- /dev/null +++ b/entry/src/main/ets/generated/common/CommonConstants.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Common constants for common component. + */ +export class CommonConstants { + static readonly HARMONY_HEI_TI_FONT_FAMILY = 'HarmonyHeiTi'; + static readonly FULL_PERCENT: string = '100%'; + static readonly WINDOW_UTIL: string = 'windowUtil'; + /** + * Font weight 500. + */ + static readonly FONT_WEIGHT_500: number = 500; + /** + * Device types. + */ + static readonly DEVICE_TYPES: string[] = ['2in1', 'tablet', 'phone']; +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/common/CommonEnums.ets b/entry/src/main/ets/generated/common/CommonEnums.ets new file mode 100644 index 0000000..ce7916b --- /dev/null +++ b/entry/src/main/ets/generated/common/CommonEnums.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 enum LoadingStatus { + OFF = 'off', + LOADING = 'loading', + SUCCESS = 'success', + FAILED = 'failed' +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/common/ModuleTitleComponent.ets b/entry/src/main/ets/generated/common/ModuleTitleComponent.ets new file mode 100644 index 0000000..411aa31 --- /dev/null +++ b/entry/src/main/ets/generated/common/ModuleTitleComponent.ets @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from './BreakpointConstants'; +import { CommonConstants } from './CommonConstants'; + +@Component +export struct ModuleTitleComponent { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_LG; + public title: string = ''; + public moduleRedirectContent: string = ''; + @Consume('appPathStack') appPathStack: NavPathStack; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + if (this.title.length) { + Row() { + Text(this.title) + .fontSize($r('app.integer.subtitle_text_L')) + .fontWeight(FontWeight.Bold) + .fontColor($r('app.color.font_primary')) + + Text(this.moduleRedirectContent) + .fontColor($r('app.color.font_secondary')) + .fontSize($r('app.integer.body_text_S')) + .fontWeight(FontWeight.Medium) + .onClick(() => { + this.jump() + }) + + } + .width(CommonConstants.FULL_PERCENT) + .height("44vp") + .justifyContent(FlexAlign.SpaceBetween) + .borderRadius($r('sys.float.corner_radius_level8')) + } + } +} diff --git a/entry/src/main/ets/generated/common/ModuleTitleComponentWithIcon.ets b/entry/src/main/ets/generated/common/ModuleTitleComponentWithIcon.ets new file mode 100644 index 0000000..7b3bf9f --- /dev/null +++ b/entry/src/main/ets/generated/common/ModuleTitleComponentWithIcon.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from './BreakpointConstants'; +import { CommonConstants } from './CommonConstants'; + +@Component +export struct ModuleTitleComponentWithIcon { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_LG; + public moduleIcon: Resource = $r("app.media.icon"); + public title: string = ''; + public moduleRedirectContent: string = ''; + @Consume('appPathStack') appPathStack: NavPathStack; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + Row() { + Row() { + Image(this.moduleIcon) + .height('20vp') + .width('20vp') + .margin({ + right: "4vp" + }) + Text(this.title) + .fontSize("16fp") + .fontWeight(CommonConstants.FONT_WEIGHT_500) + .fontColor($r('sys.color.font_primary')) + } + + Text(this.moduleRedirectContent) + .fontColor(Color.Gray) + .fontSize('12fp') + .fontWeight(CommonConstants.FONT_WEIGHT_500) + .onClick(() => { + this.jump() + }) + .margin({ + right: "4vp" + }) + } + .width(CommonConstants.FULL_PERCENT) + .padding({ left: 6, right: 6 }) + .height("30vp") + .justifyContent(FlexAlign.SpaceBetween) + .borderRadius($r('sys.float.corner_radius_level6')) + } +} diff --git a/entry/src/main/ets/generated/entryability/EntryAbility.ets b/entry/src/main/ets/generated/entryability/EntryAbility.ets new file mode 100644 index 0000000..ff6eeea --- /dev/null +++ b/entry/src/main/ets/generated/entryability/EntryAbility.ets @@ -0,0 +1,100 @@ +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; +import { WindowUtil } from '../util/WindowUtil'; + +export default class EntryAbility extends UIAbility { + private windowObj?: window.Window; + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.getMainWindow().then((data: window.Window) => { + this.windowObj = data; + this.updateWidthBp(); + this.updateHeightBp(); + this.windowObj.on('windowSizeChange', (windowSize: window.Size) => { + this.updateWidthBp(); + this.updateHeightBp(); + }) + }) + + let windowUtil: WindowUtil | undefined = WindowUtil.getInstance(); + if (windowUtil !== undefined) { + windowUtil.setWindowStage(windowStage); + windowUtil.setMainWindowPortrait(); + } + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + private updateWidthBp(): void { + if (this.windowObj === undefined) { + return; + } + let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties(); + let windowWidth: number = mainWindow.windowRect.width; + let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels; + let widthBp: string = ''; + if (windowWidthVp < 320) { + widthBp = 'xs'; + } else if (windowWidthVp >= 320 && windowWidthVp < 600) { + widthBp = 'sm'; + } else if (windowWidthVp >= 600 && windowWidthVp < 840) { + widthBp = 'md'; + } else if (windowWidthVp >= 840 && windowWidthVp < 1440) { + widthBp = 'lg'; + } else { + widthBp = 'xl'; + } + AppStorage.setOrCreate('currentWidthBreakpoint', widthBp); + } + + private updateHeightBp(): void { + if (this.windowObj === undefined) { + return; + } + let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties(); + let windowHeight: number = mainWindow.windowRect.height; + let windowWidth: number = mainWindow.windowRect.width; + let heightBp: string = ''; + let aspectRatio: number = windowHeight / windowWidth; + if (aspectRatio < 0.8) { + heightBp = 'sm'; + } else if (aspectRatio >= 0.8 && aspectRatio < 1.2) { + heightBp = 'md'; + } else { + heightBp = 'lg'; + } + AppStorage.setOrCreate('currentHeightBreakpoint', heightBp); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/entry/src/main/ets/generated/pages/BMICalculator.ets b/entry/src/main/ets/generated/pages/BMICalculator.ets new file mode 100644 index 0000000..283295a --- /dev/null +++ b/entry/src/main/ets/generated/pages/BMICalculator.ets @@ -0,0 +1,27 @@ +import { PageTitleModule } from '../view/PageTitleModule'; +import { HeightWeightInputModule } from '../view/HeightWeightInputModule'; +import { CalculateBmiButtonModule } from '../view/CalculateBmiButtonModule'; +import { HealthResultModule } from '../view/HealthResultModule'; + +@Component +export struct BMICalculator { + private scroller: Scroller = new Scroller(); + + build() { + Scroll(this.scroller) { + Column() { + PageTitleModule() + HeightWeightInputModule() + CalculateBmiButtonModule() + HealthResultModule() + } + .width('100%') + } + .scrollable(ScrollDirection.Vertical) + .scrollBar(BarState.Off) + .width('100%') + .height('100%') + .align(Alignment.Top) + .backgroundColor($r('app.color.page_bg_color')) + } +} diff --git a/entry/src/main/ets/generated/util/BreakpointType.ets b/entry/src/main/ets/generated/util/BreakpointType.ets new file mode 100644 index 0000000..6f55250 --- /dev/null +++ b/entry/src/main/ets/generated/util/BreakpointType.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from "../common/BreakpointConstants"; + +export class BreakpointType { + sm: T; + md: T; + lg: T; + + constructor(sm: T, md: T, lg: T) { + this.sm = sm; + this.md = md; + this.lg = lg; + } + + getValue(currentWidthBreakpoint: string): T { + if (currentWidthBreakpoint === BreakpointConstants.BREAKPOINT_MD) { + return this.md; + } + if (currentWidthBreakpoint === BreakpointConstants.BREAKPOINT_LG) { + return this.lg; + } else { + return this.sm; + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/util/LazyDataSource.ets b/entry/src/main/ets/generated/util/LazyDataSource.ets new file mode 100644 index 0000000..d8561b3 --- /dev/null +++ b/entry/src/main/ets/generated/util/LazyDataSource.ets @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 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 Logger from './Logger'; +import { ObservedArray } from './ObservedArray'; + +const TAG = '[BasicDataSource]'; + +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): T | undefined { + return undefined; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + Logger.info(TAG, 'add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + Logger.info(TAG, 'remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +@Observed +export default class LazyDataSource extends BasicDataSource { + dataArray: T[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): T { + return this.dataArray[index]; + } + + public addData(index: number, data: T): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: T): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } + + public pushArrayData(newData: ObservedArray): void { + this.clear(); + this.dataArray.push(...newData); + this.notifyDataReload(); + } + + public appendArrayData(addData: ObservedArray): void { + this.dataArray.push(...addData); + this.notifyDataReload(); + } + + public deleteData(index: number): void { + this.dataArray.splice(index, 1); + this.notifyDataDelete(index); + } + + public getDataList(): ObservedArray { + return this.dataArray; + } + + public clear(): void { + this.dataArray.splice(0, this.dataArray?.length); + } + + public isEmpty(): boolean { + return this.dataArray.length === 0; + } +} diff --git a/entry/src/main/ets/generated/util/Logger.ets b/entry/src/main/ets/generated/util/Logger.ets new file mode 100644 index 0000000..75d04e2 --- /dev/null +++ b/entry/src/main/ets/generated/util/Logger.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 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 { hilog } from '@kit.PerformanceAnalysisKit'; + +class Logger { + private domain: number; + private prefix: string; + private format: string = "%{public}s, %{public}s"; + + constructor(prefix: string) { + this.prefix = prefix; + this.domain = 0xFF00; + } + + debug(...args: Object[]): void { + hilog.debug(this.domain, this.prefix, this.format, args); + } + + info(...args: Object[]): void { + hilog.info(this.domain, this.prefix, this.format, args); + } + + warn(...args: Object[]): void { + hilog.warn(this.domain, this.prefix, this.format, args); + } + + error(...args: Object[]): void { + hilog.error(this.domain, this.prefix, this.format, args); + } +} + +export default new Logger('[HMOSWorld]'); diff --git a/entry/src/main/ets/generated/util/ObservedArray.ets b/entry/src/main/ets/generated/util/ObservedArray.ets new file mode 100644 index 0000000..921097b --- /dev/null +++ b/entry/src/main/ets/generated/util/ObservedArray.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Wraps an array as an observed object + */ +@Observed +export class ObservedArray extends Array { + constructor(args?: T[]) { + if (args instanceof Array) { + super(...args); + } else { + super(); + } + } +} diff --git a/entry/src/main/ets/generated/util/WebUtils.ets b/entry/src/main/ets/generated/util/WebUtils.ets new file mode 100644 index 0000000..9fe4a4b --- /dev/null +++ b/entry/src/main/ets/generated/util/WebUtils.ets @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 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 { BuilderNode, FrameNode, NodeController, Size } from '@kit.ArkUI'; +import { webview } from '@kit.ArkWeb'; +import { CommonConstants } from '../common/CommonConstants'; +import Logger from './Logger'; + +let nodeMap: Map = new Map(); +let controllerMap: Map = new Map(); +let onPageEndMap: Map = new Map(); +let onProgressChangeMap: Map = new Map(); +let onResourceLoadMap: Map = new Map(); +let context: UIContext; + +class Data { + public url: string; + public controller: WebviewController; + public onPageEndAction?: Function; + public onProgressChangeAction?: Function; + public onResourceLoadAction?: Function; + + constructor(url: string, controller: WebviewController) { + this.url = url; + this.controller = controller; + } +} + +// Developer-defined template +@Builder +function webBuilder(data: Data) { + Web({ src: data.url.split('~')[0], controller: data.controller }) + .domStorageAccess(true) + .zoomAccess(true) + .fileAccess(true) + .mixedMode(MixedMode.All) + .cacheMode(CacheMode.Default) + .verticalScrollBarAccess(false) + .javaScriptAccess(true) + .pinchSmooth(true) + .onFirstContentfulPaint(() => { + nodeMap.set('hmos_' + data.url, undefined); + }) + .onPageEnd(() => { + onPageEndMap.get(data.url)?.(); + }) + .onProgressChange((event) => { + Logger.info('newProgress:' + event?.newProgress); + if (event?.newProgress === 100) { + onProgressChangeMap.get(data.url)?.(); + } + Logger.info('onProgressChange weburl: ' + data.url); + }) + .onResourceLoad((event) => { + Logger.info('onResourceLoad:' + event?.url); + onResourceLoadMap.get(data.url)?.(event.url); + }) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) +} + +let wrap = wrapBuilder(webBuilder); + +/** + * Controls and feeds back the behavior of the node on the corresponding NodeContainer. + * It must be used together with NodeContainer. + */ +export class MyNodeController extends NodeController { + private rootNode: BuilderNode | null | undefined = null; + private isRemove: boolean = false; + + // Used to construct the number of nodes and return the node mount in the corresponding NodeContainer. + // This API is called when the corresponding NodeContainer is created or by using the rebuild method. + makeNode(uiContext: UIContext): FrameNode | null { + Logger.info('uiContext is undifined : ' + (uiContext === undefined)); + if (this.isRemove) { + return null; + } + if (this.rootNode != undefined) { + return this.rootNode.getFrameNode(); + } + return null; + } + + disposeNode() { + this.rootNode?.dispose(); + } + + aboutToResize(size: Size) { + Logger.info('aboutToResize width : ' + size.width + ' height : ' + size.height); + } + + aboutToAppear() { + if (this.rootNode == undefined) { + return; + } + } + + aboutToDisappear() { + Logger.info('aboutToDisappear'); + } + + + initWeb(url: string, uiContext: UIContext, control: WebviewController, onPageEndAction?: Function) { + if (this.rootNode != null) { + return; + } + this.rootNode = new BuilderNode(uiContext); + this.rootNode.dispose() + this.rootNode.build(wrap, { url: url, controller: control }); + } +} + +export function createNWeb(url: string, uiContext?: UIContext) { + if (nodeMap.has(url)) { + return; + } + if (!context && uiContext) { + context = uiContext; + } + let baseNode = new MyNodeController(); + let controller = new webview.WebviewController(); + baseNode.initWeb(url, context, controller); + controllerMap.set(url, controller) + nodeMap.set(url, baseNode); +} + +export const getNWeb = (url: string): MyNodeController | undefined => { + return nodeMap.get(url); +} + +// Destruct the created node. +export const deleteNode = (url: string) => { + let nodeController = nodeMap.get(url); + nodeController?.disposeNode(); + nodeMap.delete(url); + controllerMap.delete(url); + onPageEndMap.delete(url); +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/util/WindowUtil.ets b/entry/src/main/ets/generated/util/WindowUtil.ets new file mode 100644 index 0000000..f090cdf --- /dev/null +++ b/entry/src/main/ets/generated/util/WindowUtil.ets @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 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 { deviceInfo } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; +import Logger from './Logger'; +import { CommonConstants } from '../common/CommonConstants'; + +@Observed +export class WindowUtil { + private windowStage?: window.WindowStage; + private mainWindowClass?: window.Window; + + static getInstance(): WindowUtil | undefined { + if (!AppStorage.get(CommonConstants.WINDOW_UTIL)) { + AppStorage.setOrCreate(CommonConstants.WINDOW_UTIL, new WindowUtil()); + } else { + Logger.info(`AppStorage does not have windowUtil`); + } + return AppStorage.get(CommonConstants.WINDOW_UTIL); + } + + setWindowStage(windowStage: window.WindowStage): void { + this.windowStage = windowStage; + } + + setMainWindowPortrait(): void { + if (this.windowStage === undefined) { + Logger.error(`WindowStage is undefined`); + return; + } + this.windowStage.getMainWindow((err, windowClass: window.Window) => { + this.mainWindowClass = windowClass; + if (err.code) { + Logger.error(`Failed to obtain the main window. Code:${err.code}, message:${err.message}`); + return; + } + if (deviceInfo.deviceType !== CommonConstants.DEVICE_TYPES[0] && deviceInfo.deviceType !== + CommonConstants.DEVICE_TYPES[1]) { + this.mainWindowClass.setPreferredOrientation(window.Orientation.PORTRAIT); + } + }); + } + + setMainWindowOrientation(orientation: window.Orientation): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setPreferredOrientation(orientation); + } + + disableWindowSystemBar(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowSystemBarEnable([]); + } + + enableWindowSystemBar(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']); + } + + setFullScreen(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowLayoutFullScreen(true); + } + + getMainWindow(): window.Window | undefined { + return this.mainWindowClass; + } + + offWindowSizeChange(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass?.off('windowSizeChange'); + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/view/CalculateBmiButtonModule.ets b/entry/src/main/ets/generated/view/CalculateBmiButtonModule.ets new file mode 100644 index 0000000..effda4c --- /dev/null +++ b/entry/src/main/ets/generated/view/CalculateBmiButtonModule.ets @@ -0,0 +1,157 @@ +/* + * 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 { + DataSource, DataSourceStyleAStyleA +} from '../viewmodel/CalculateBmiButtonModuleData'; + +import { LoadingStatus } from '../common/CommonEnums'; +import { LoadingFailedView } from '../view/LoadingFailedView'; +import { BreakpointConstants } from '../common/BreakpointConstants'; + +import { BreakpointType } from '../util/BreakpointType'; +import LazyDataSource from '../util/LazyDataSource'; +import { CommonConstants } from '../common/CommonConstants'; +import { ModuleTitleComponent } from '../common/ModuleTitleComponent'; + + +@Component +export struct CalculateBmiButtonModule { + @State itemModel: DataSource = + DataSource.getInstance(); + @State lazyDataSource: LazyDataSource = + this.itemModel.lazyDataSource; + @State rowHeight: number = 150; + @State rowGap: number = 6; + @State moduleTitle: string = "健康计算"; + @State moduleRedirectContent: string = "查看更多"; + private columnGapArray: number[] = [6, 10, 12]; + private columnNumberArray: number[] = [2, 4, 4]; + private rowNumberArray: number[] = [1, 1, 1]; + @State loadingStatus: LoadingStatus = LoadingStatus.OFF; + @Consume('appPathStack') appPathStack: NavPathStack; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + + aboutToAppear() { + this.loadResources(); + } + + loadResources(): void { + this.loadingStatus = LoadingStatus.LOADING; + this.itemModel.getResources().then(() => { + this.loadingStatus = LoadingStatus.SUCCESS; + }).catch(() => { + this.loadingStatus = LoadingStatus.FAILED; + }); + } + + build() { + Column() { + Column() { + ModuleTitleComponent({ title: this.moduleTitle, moduleRedirectContent: this.moduleRedirectContent }) + if (this.loadingStatus === LoadingStatus.FAILED) { + LoadingFailedView(() => this.loadResources()) + } + if (this.loadingStatus === LoadingStatus.SUCCESS) { + Column() { + Button('计算BMI') + .fontSize($r('app.integer.subtitle_text_L')) + .fontWeight(FontWeight.Medium) + .fontColor($r('app.color.font_on_primary')) + .backgroundColor($r('sys.color.ohos_id_color_palette_aux1')) + .width('60%') + .height(60) + .borderRadius($r('sys.float.corner_radius_level8')) + } + .width('100%') + .height(this.currentWidthBreakpoint !== BreakpointConstants.BREAKPOINT_LG ? + (this.rowGap + this.rowHeight) * new BreakpointType(this.rowNumberArray[0], this.rowNumberArray[1], + this.rowNumberArray[2]).getValue(this.currentWidthBreakpoint) : + (this.rowGap + this.rowHeight + 30) * new BreakpointType(this.rowNumberArray[0], this.rowNumberArray[1], + this.rowNumberArray[2]).getValue(this.currentWidthBreakpoint)) + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) + } + } + .width('92%') + .align(Alignment.Center) + .borderRadius($r('sys.float.corner_radius_level8')) + .margin({ bottom: "10vp" }) + } + .width('100%') + } +} + +@Component +export struct DoubleStackGraphicTextItem { + @State title: string = '模块名'; + @State content: string = '跳转'; + @State image: Resource = $r("app.media.noImage"); + + build() { + Stack({ alignContent: Alignment.TopStart }) { + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link DataSource#IMAGES} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see DataSource#getResources() + */ + Image(this.image) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + .borderRadius($r('sys.float.corner_radius_level8')) + Column() { + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link DataSource#TITLES} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see DataSource#getResources() + */ + Text(this.title) + .fontWeight(FontWeight.Medium) + .fontSize($r('app.integer.subtitle_text_L')) + .margin({ top: "4vp" }) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .width(CommonConstants.FULL_PERCENT) + .fontColor($r('app.color.font_on_primary')) + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link DataSource#CONTENTS} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see DataSource#getResources() + */ + Text(this.content) + .fontSize($r('app.integer.body_text_M')) + .opacity(0.8) + .fontWeight(FontWeight.Regular) + .maxLines(1) + .margin({ top: "2vp" }) + .width(CommonConstants.FULL_PERCENT) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .fontColor($r('app.color.font_on_secondary')) + } + .padding({ left: '16vp', top: '16vp' }) + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Start) + .width(CommonConstants.FULL_PERCENT) + } + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + } +} diff --git a/entry/src/main/ets/generated/view/EmptyPage.ets b/entry/src/main/ets/generated/view/EmptyPage.ets new file mode 100644 index 0000000..2fcc812 --- /dev/null +++ b/entry/src/main/ets/generated/view/EmptyPage.ets @@ -0,0 +1,27 @@ +import { router } from '@kit.ArkUI'; + +@Entry +@Component +struct EmptyPage { + @State content: string = (router.getParams() as Record)['text']; + + build() { + Column() { + Row() { + Text('empty page for ') + .fontSize('25vp') + .fontColor(Color.Gray) + Text(this.content) + .fontSize('25vp') + .fontColor(Color.Blue) + } + .onClick(() => { + router.back(); + }) + } + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) + .width('100%') + .height('100%') + } +} diff --git a/entry/src/main/ets/generated/view/EmptyPagePathStack.ets b/entry/src/main/ets/generated/view/EmptyPagePathStack.ets new file mode 100644 index 0000000..692fc56 --- /dev/null +++ b/entry/src/main/ets/generated/view/EmptyPagePathStack.ets @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 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 '../common/CommonConstants'; + + +@Component +export struct EmptyPagePathStack { + @Consume('appPathStack') appPathStack: NavPathStack; + + build() { + NavDestination() { + Column() { + TopNavigationView({ + title: "详情页", + onBackClick: () => { + this.appPathStack.pop(); + } + }) + Image($r("app.media.realImageGen_travel_0")) + } + .justifyContent(FlexAlign.SpaceBetween) + .alignItems(HorizontalAlign.Center) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + } + .hideTitleBar(true) + } +} + +@Builder +export function EmptyPagePathStackBuilder() { + EmptyPagePathStack() +} + +@Component +struct TopNavigationView { + title?: ResourceStr; + onBackClick?: Function; + + build() { + Row() { + if (this.onBackClick) { + Image($r('app.media.ic_back')) + .width("40vp") + .height("40vp") + .margin({ right: "16vp" }) + .onClick(() => this.onBackClick?.()) + } + + Text(this.title) + .fontSize("20fp") + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Start) + .layoutWeight(1) + } + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .width(CommonConstants.FULL_PERCENT) + .height("56vp") + .padding({ + left: "24vp", + right: "24vp" + }) + } +} diff --git a/entry/src/main/ets/generated/view/HealthResultModule.ets b/entry/src/main/ets/generated/view/HealthResultModule.ets new file mode 100644 index 0000000..294dd80 --- /dev/null +++ b/entry/src/main/ets/generated/view/HealthResultModule.ets @@ -0,0 +1,215 @@ +/* + * 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 { + DataSource, Data +} from '../viewmodel/HealthResultModuleData'; + +import { LoadingStatus } from '../common/CommonEnums'; +import { LoadingFailedView } from '../view/LoadingFailedView'; + +import { BreakpointConstants } from '../common/BreakpointConstants'; +import { BreakpointType } from '../util/BreakpointType'; +import LazyDataSource from '../util/LazyDataSource'; +import { CommonConstants } from '../common/CommonConstants'; +import { ModuleTitleComponent } from '../common/ModuleTitleComponent'; + + +@Component +export struct HealthResultModule { + @State itemModel: Data = + Data.getInstance(); + @Prop listDirection: Axis = Axis.Vertical + @State moduleTitle: string = "健康计算结果"; + @State moduleRedirectContent: string = "查看更多"; + @State loadingStatus: LoadingStatus = LoadingStatus.OFF; + @State lazyDataSource: LazyDataSource = + this.itemModel.lazyDataSource; + private spaceArray: string[] = ['8vp', '6vp', '10vp']; + private lanesArray: number[] = [1, 2, 3]; + @Consume('appPathStack') appPathStack: NavPathStack; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + + aboutToAppear() { + this.loadResources(); + + } + + loadResources(): void { + this.loadingStatus = LoadingStatus.LOADING; + this.itemModel.getResources().then(() => { + this.loadingStatus = LoadingStatus.SUCCESS; + }).catch(() => { + this.loadingStatus = LoadingStatus.FAILED; + }); + } + + build() { + Column() { + Column() { + ModuleTitleComponent({ title: this.moduleTitle, moduleRedirectContent: this.moduleRedirectContent }) + + if (this.loadingStatus === LoadingStatus.FAILED) { + LoadingFailedView(() => this.loadResources()) + } + if (this.loadingStatus === LoadingStatus.SUCCESS) { + List({ + space: new BreakpointType(this.spaceArray[0], this.spaceArray[1], + this.spaceArray[2]).getValue(this.currentWidthBreakpoint) + }) { + LazyForEach(this.lazyDataSource, (item: DataSource) => { + ListItem() { + HealthResultCard({ + image: item.getImage(), + mainText: item.getMainText(), + subText: item.getSubText(), + descriptionText: item.getDescriptionText(), + tagTextList: item.getTagTextList(), + tagTextColorList: item.getTagTextColorList() + }) + } + .width('100%') + .height("180vp") + .borderRadius($r('sys.float.corner_radius_level8')) + .backgroundColor($r('app.color.module_item_bg_color')) + .onClick(() => { + this.appPathStack.pushPathByName('DetailedPagePathStack', null) + }) + }, (item: DataSource, index: number) => index + JSON.stringify(item)) + } + .width('auto') + .height('auto') + .listDirection(this.listDirection) + // .divider({ "strokeWidth": 1 }) + .lanes(new BreakpointType(this.lanesArray[0], this.lanesArray[1], + this.lanesArray[2]).getValue(this.currentWidthBreakpoint), "12vp") + } + } + .borderRadius($r('sys.float.corner_radius_level8')) + .margin({ bottom: "10vp" }) + .align(Alignment.Center) + .width('92%') + } + .width("100%") + } +} + +@Component +export struct HealthResultCard { + @State image: Resource = $r('app.media.noImage'); + @State mainText: string = '主标题文本'; + @State subText: string = '子标题文本'; + @State descriptionText: string = '这是一个描述文本,用于展示一些详细信息。'; + @State tagTextList: string[] = ['标签1', '标签2', '标签3', "标签4"]; + @State tagTextColorList: Color[] = [Color.Brown, Color.Green, Color.Gray, Color.Blue]; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + + build() { + Column() { + Row() { + // 左侧健康指标区域 + Column() { + // BMI数值显示 + Text(this.mainText) + .fontSize($r('app.integer.title_text_L')) + .fontColor($r('app.color.primary_color')) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .margin({ bottom: 4 }) + .maxLines(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + + // 健康状态标签 + Text(this.subText) + .fontSize($r('app.integer.body_text_M')) + .fontColor($r('app.color.content_font_color')) + .fontWeight(FontWeight.Medium) + .textAlign(TextAlign.Center) + .margin({ bottom: 8 }) + .maxLines(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + + // 健康建议文本 + Text(this.descriptionText) + .fontSize($r('app.integer.caption_text_L')) + .fontColor($r('app.color.content_sub_title_font_color')) + .textAlign(TextAlign.Center) + .maxLines(2) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } + .width('40%') + .height('100%') + .justifyContent(FlexAlign.Center) + .padding({ left: 15, right: 10 }) + + // 分隔线 + Divider() + .vertical(true) + .height('60%') + .strokeWidth(1) + .color($r('app.color.divider_color')) + + // 右侧健康知识科普区域 + Column() { + Text('健康知识') + .fontSize($r('app.integer.subtitle_text_M')) + .fontColor($r('app.color.content_font_color')) + .fontWeight(FontWeight.Bold) + .margin({ bottom: 6 }) + .width('100%') + + Text('保持健康的生活方式,均衡饮食,适量运动,定期体检是维护健康的重要方法。') + .fontSize($r('app.integer.body_text_S')) + .fontColor($r('app.color.content_sub_title_font_color')) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + .margin({ bottom: 8 }) + + // 标签区域 + Row() { + ForEach(this.tagTextList, (item: string, index: number) => { + Text(item) + .width(52) + .height(18) + .textAlign(TextAlign.Center) + .fontSize($r('app.integer.caption_text_M')) + .fontWeight(FontWeight.Medium) + .fontColor(this.tagTextColorList[index]) + .borderColor(this.tagTextColorList[index]) + .borderWidth(1) + .borderRadius($r('sys.float.corner_radius_level2')) + .margin({ right: 4 }) + }) + } + .width('100%') + .justifyContent(FlexAlign.Start) + } + .width('55%') + .height('100%') + .justifyContent(FlexAlign.SpaceBetween) + .padding({ left: 10, right: 15 }) + } + .borderRadius($r('sys.float.corner_radius_level8')) + .backgroundColor($r('app.color.comp_background_primary_trans')) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + } + .margin({ bottom: "8px" }) + } +} diff --git a/entry/src/main/ets/generated/view/HeightWeightInputModule.ets b/entry/src/main/ets/generated/view/HeightWeightInputModule.ets new file mode 100644 index 0000000..8f45807 --- /dev/null +++ b/entry/src/main/ets/generated/view/HeightWeightInputModule.ets @@ -0,0 +1,260 @@ +/* + * 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 { + DataSource, Data +} from '../viewmodel/HeightWeightInputModuleData'; +import { LoadingStatus } from '../common/CommonEnums'; +import { LoadingFailedView } from '../view/LoadingFailedView'; + +import { BreakpointConstants } from '../common/BreakpointConstants'; +import { BreakpointType } from '../util/BreakpointType'; +import LazyDataSource from '../util/LazyDataSource'; +import { CommonConstants } from '../common/CommonConstants'; +import { ModuleTitleComponent } from '../common/ModuleTitleComponent' + + +@Component +export struct HeightWeightInputModule { + @State itemModel: Data = + Data.getInstance(); + @Prop listDirection: Axis = Axis.Horizontal + @State moduleTitle: string = "身高体重计算"; + @State moduleRedirectContent: string = "查看更多"; + @State loadingStatus: LoadingStatus = LoadingStatus.OFF; + @State lazyDataSource: LazyDataSource = + this.itemModel.lazyDataSource; + private spaceArray: string[] = ['8vp', '16vp', '20vp']; + @Consume('appPathStack') appPathStack: NavPathStack; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + aboutToAppear() { + this.loadResources(); + + } + + loadResources(): void { + this.loadingStatus = LoadingStatus.LOADING; + this.itemModel.getResources().then(() => { + this.loadingStatus = LoadingStatus.SUCCESS; + }).catch(() => { + this.loadingStatus = LoadingStatus.FAILED; + }); + } + + build() { + Column() { + ModuleTitleComponent({ title: this.moduleTitle, moduleRedirectContent: this.moduleRedirectContent }) + + if (this.loadingStatus === LoadingStatus.FAILED) { + LoadingFailedView(() => this.loadResources()) + } + if (this.loadingStatus === LoadingStatus.SUCCESS) { + List({ + space: new BreakpointType(this.spaceArray[0], this.spaceArray[1], + this.spaceArray[2]).getValue(this.currentWidthBreakpoint) + }) { + LazyForEach(this.lazyDataSource, (item: DataSource) => { + ListItem() { + HorizontalGraphicTextFunctionItem2({ + icon: item.getIcon(), + title: item.getTitle(), + description: item.getDescription() + }) + } + .width('150vp') + .height('60vp') + .onClick(() => { + this.jump() + }) + .borderRadius($r('sys.float.corner_radius_level4')) + .backgroundColor($r('app.color.comp_background_primary_trans')) + }, (item: DataSource, index: number) => index + JSON.stringify(item)) + } + .width('auto') + .height('auto') + .listDirection(this.listDirection) + .scrollBar(BarState.Off) + } + } + .width('92%') + .margin({ bottom: "10vp" }) + } +} + + +@Component +export struct HorizontalGraphicTextFunctionItem2 { + @State title: string = '模块名'; + @State description: string = '跳转'; + @State icon: Resource = $r("app.media.ic_public_app"); + @State heightValue: number = 170; + @State weightValue: number = 65; + @State heightUnit: string = 'cm'; + @State weightUnit: string = 'kg'; + + build() { + Row() { + Column() { + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#TITLES} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#getResources() + */ + Text(this.title) + .margin({ bottom: '3vp' }) + .fontColor($r('app.color.font_primary')) + .maxFontSize($r('app.integer.subtitle_text_M')) + .minFontSize($r('app.integer.caption_text_L')) + .fontWeight(FontWeight.Medium) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + + // 身高输入区域 + Row() { + Text('身高:') + .fontColor($r('app.color.font_primary')) + .fontSize($r('app.integer.body_text_S')) + .fontWeight(FontWeight.Medium) + .width('20%') + + Column() { + // 文本框显示当前值 + Text(this.heightValue.toString()) + .fontColor($r('app.color.font_primary')) + .fontSize($r('app.integer.body_text_M')) + .textAlign(TextAlign.Center) + .width('100%') + .margin({ bottom: '4vp' }) + + // 滑动拉杆 + Slider({ + value: this.heightValue, + min: 100, + max: 250, + step: 1, + style: SliderStyle.OutSet + }) + .width('100%') + .height('20vp') + .onChange((value: number) => { + this.heightValue = Math.round(value); + }) + } + .width('60%') + + // 单位选择器 + Picker({ range: ['cm', 'm'] }) + .width('20%') + .selected(this.heightUnit === 'cm' ? 0 : 1) + .onChange((index: number) => { + this.heightUnit = index === 0 ? 'cm' : 'm'; + }) + } + .width('100%') + .margin({ bottom: '8vp' }) + + // 体重输入区域 + Row() { + Text('体重:') + .fontColor($r('app.color.font_primary')) + .fontSize($r('app.integer.body_text_S')) + .fontWeight(FontWeight.Medium) + .width('20%') + + Column() { + // 文本框显示当前值 + Text(this.weightValue.toString()) + .fontColor($r('app.color.font_primary')) + .fontSize($r('app.integer.body_text_M')) + .textAlign(TextAlign.Center) + .width('100%') + .margin({ bottom: '4vp' }) + + // 滑动拉杆 + Slider({ + value: this.weightValue, + min: 30, + max: 200, + step: 0.5, + style: SliderStyle.OutSet + }) + .width('100%') + .height('20vp') + .onChange((value: number) => { + this.weightValue = Math.round(value * 2) / 2; + }) + } + .width('60%') + + // 单位选择器 + Picker({ range: ['kg', 'lb'] }) + .width('20%') + .selected(this.weightUnit === 'kg' ? 0 : 1) + .onChange((index: number) => { + this.weightUnit = index === 0 ? 'kg' : 'lb'; + }) + } + .width('100%') + + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#DESCRIPTIONS} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#getResources() + */ + Text(this.description) + .fontColor($r('app.color.font_secondary')) + .maxFontSize($r('app.integer.body_text_S')) + .minFontSize($r('app.integer.caption_text_M')) + .fontWeight(FontWeight.Regular) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .width('50%') + .layoutWeight(1) + .alignItems(HorizontalAlign.Start) + .padding({ left: 6, right: 2 }) + + /** + * TODO: + * please modify it according to the actual situation. + * directly modify {@link SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#ICONS} + * or refactor method {@code getResources()} to implement your custom code logic. + * @see SwiperFlatten_HorizontalGraphicTextFunctionItem2Model#getResources() + */ + Column() { + Image(this.icon) + .height('60%') + .constraintSize({ maxWidth: '100%' }) + .objectFit(ImageFit.Contain) + } + .width('30%') + .margin({ right: 2 }) + .alignItems(HorizontalAlign.End) + } + .justifyContent(FlexAlign.SpaceBetween) + .borderRadius($r('sys.float.corner_radius_level8')) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + } +} diff --git a/entry/src/main/ets/generated/view/LoadingFailedView.ets b/entry/src/main/ets/generated/view/LoadingFailedView.ets new file mode 100644 index 0000000..ba7ff16 --- /dev/null +++ b/entry/src/main/ets/generated/view/LoadingFailedView.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 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 '../common/CommonConstants' + +@Builder +export function LoadingFailedView(handleReload?: () => void) { + Row() { + Column() { + Image($r('app.media.ic_failure')) + .width("120vp") + .height("120vp") + Text("Failed to load the network") + .fontColor($r('sys.color.mask_secondary')) + .fontFamily(CommonConstants.HARMONY_HEI_TI_FONT_FAMILY) + .fontSize("14fp") + .margin({ top: "8vp" }) + Row() { + Text("Reload") + .fontColor("#FF3E50") + .fontFamily(CommonConstants.HARMONY_HEI_TI_FONT_FAMILY) + .fontSize("12fp") + .width(CommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Center) + } + .height("32vp") + .width("80vp") + .margin({ top: "8vp" }) + .borderRadius($r('sys.float.corner_radius_level6')) + .onClick(() => handleReload?.()) + } + } + .justifyContent(FlexAlign.Center) + .layoutWeight(1) +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/view/LoadingView.ets b/entry/src/main/ets/generated/view/LoadingView.ets new file mode 100644 index 0000000..4716d7c --- /dev/null +++ b/entry/src/main/ets/generated/view/LoadingView.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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 '../common/CommonConstants' + +@Component +export struct LoadingView { + build() { + Column() { + Row() { + LoadingProgress() + } + .margin({ top: "260vp" }) + .width("72vp") + .height("72vp") + } + .height(CommonConstants.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/view/PageTitleModule.ets b/entry/src/main/ets/generated/view/PageTitleModule.ets new file mode 100644 index 0000000..7e84e00 --- /dev/null +++ b/entry/src/main/ets/generated/view/PageTitleModule.ets @@ -0,0 +1,133 @@ +import { + DataSource, DataSourceStyleAStyleA +} from '../viewmodel/PageTitleModuleData'; +import { LoadingStatus } from '../common/CommonEnums'; +import { BreakpointConstants } from '../common/BreakpointConstants'; +import { BreakpointType } from '../util/BreakpointType'; +import { CommonConstants } from '../common/CommonConstants'; + +@Component +struct IconTextItem { + @Consume('appPathStack') appPathStack: NavPathStack; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + private icon: Resource = $r('app.media.noImage'); + private title: string = "BMI计算器"; + private iconColor?: string = '#2D70F1'; + private iconSize: number = 32; + + build() { + Column() { + Image(this.icon) + .width(this.iconSize) + .height(this.iconSize) + .fillColor(this.iconColor) + .onClick(() => { + this.jump() + }) + + Text(this.title) + .fontColor('#333333') + .fontSize($r('app.integer.body_text_S')) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .margin({ top: '5px' }) + .onClick(() => { + this.jump() + }) + } + .alignItems(HorizontalAlign.Center) + .width('100%') + } +} + +@Component +export struct PageTitleModule { + @Consume('appPathStack') appPathStack: NavPathStack; + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; + @State functionModel: DataSource = DataSource.getInstance(); + @State items: Array = []; + @State loadingStatus: LoadingStatus = LoadingStatus.LOADING; + @State rowHeight: number = 80; + @State rowGap: number = 6; + private columnGapArray: number[] = [6, 10, 12]; + private columnNumberArray: number[] = [1, 8, 8]; + private rowNumberArray: number[] = [1, 1, 1]; + + aboutToAppear() { + this.loadData(); + } + + async loadData() { + try { + this.loadingStatus = LoadingStatus.LOADING; + await this.functionModel.getResources(); + this.loadingStatus = LoadingStatus.SUCCESS; + + this.items = this.functionModel.getAllItems(); + } catch (error) { + this.loadingStatus = LoadingStatus.FAILED; + console.error('Failed to load data:', error); + } + } + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + Column() { + Column() { + Image(this.functionModel.getBannerImage()) + .objectFit(ImageFit.Fill) + } + .height(100) + + if (this.loadingStatus === LoadingStatus.SUCCESS) { + Grid() { + ForEach(this.items, (item: DataSourceStyleAStyleA) => { + GridItem() { + IconTextItem({ + icon: item.getIcon(), + title: item.getTitle(), + iconColor: '#2196F3' + }) + } + }) + } + .columnsTemplate(("1fr ").repeat(new BreakpointType(this.columnNumberArray[0], this.columnNumberArray[1], + this.columnNumberArray[2]).getValue(this.currentWidthBreakpoint)).trim()) + .rowsTemplate(("1fr ").repeat(new BreakpointType(this.rowNumberArray[0], this.rowNumberArray[1], + this.rowNumberArray[2]).getValue(this.currentWidthBreakpoint)).trim()) + .height(this.currentWidthBreakpoint !== BreakpointConstants.BREAKPOINT_LG ? + (this.rowGap + this.rowHeight) * new BreakpointType(this.rowNumberArray[0], this.rowNumberArray[1], + this.rowNumberArray[2]).getValue(this.currentWidthBreakpoint) : + (this.rowGap + this.rowHeight + 30) * new BreakpointType(this.rowNumberArray[0], this.rowNumberArray[1], + this.rowNumberArray[2]).getValue(this.currentWidthBreakpoint)) + .columnsGap(new BreakpointType(this.columnGapArray[0], this.columnGapArray[1], + this.columnGapArray[2]).getValue(this.currentWidthBreakpoint)) + .rowsGap(this.rowGap) + } else if (this.loadingStatus === LoadingStatus.FAILED) { + Text('加载中...') + .fontSize(14) + .fontColor('#999999') + .margin(16) + } else { + Text('加载失败,点击重试') + .fontSize(14) + .fontColor('#999999') + .margin(16) + .onClick(() => { + this.loadData(); + }) + } + } + .width(CommonConstants.FULL_PERCENT) + .height(180) + .backgroundColor($r('app.color.comp_background_primary_trans')) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/view/SearchModuleWithButtonPage.ets b/entry/src/main/ets/generated/view/SearchModuleWithButtonPage.ets new file mode 100644 index 0000000..66dc090 --- /dev/null +++ b/entry/src/main/ets/generated/view/SearchModuleWithButtonPage.ets @@ -0,0 +1,98 @@ +/* + * 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. + */ + +/* + * 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 { curves } from '@kit.ArkUI'; +import { CommonConstants } from '../common/CommonConstants'; + +@Builder +export function SearchModuleWithButtonPageBuilder() { + SearchModuleWithButtonPage() +} + +@Component +export default struct SearchModuleWithButtonPage { + private pageInfos: NavPathStack = new NavPathStack(); + + private onArrowClicked(): void { + this.pageInfos.pop(false); + } + + build() { + NavDestination() { + Row() { + Image($r('app.media.icon')) + .width(40) + .height(40) + .onClick(() => { + this.onArrowClicked(); + }) + Search({ placeholder: '搜索交通/酒店/景点等' }) + .searchButton('搜索') + .enableKeyboardOnFocus(false) + .placeholderColor(Color.Black) + .placeholderFont({ + family: "HarmonyHeiTi", + size: 16, + weight: 400 + }) + .borderColor($r('sys.color.font_primary')) + .searchIcon({ color: Color.Black }) + .backgroundColor(Color.White) + .defaultFocus(true) + .focusOnTouch(true) + .fontColor(Color.Black) + .width('85%') + .padding({ + left: "24vp", + right: "24vp" + }) + } + .width(CommonConstants.FULL_PERCENT) + .height(50) + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .margin({ bottom: '10vp' }) + } + .transition(TransitionEffect.OPACITY) + .hideTitleBar(true) + .backgroundColor('#F1F3F5') + .onReady((context: NavDestinationContext) => { + this.pageInfos = context.pathStack; + }) + .onBackPressed(() => { + animateTo({ + curve: curves.interpolatingSpring(0, 1, 342, 38), + }, () => { + this.pageInfos.pop(false); + }) + return true; + }) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/view/SecondPageSearch.ets b/entry/src/main/ets/generated/view/SecondPageSearch.ets new file mode 100644 index 0000000..860a0fe --- /dev/null +++ b/entry/src/main/ets/generated/view/SecondPageSearch.ets @@ -0,0 +1,107 @@ +/* + * 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 '../common/CommonConstants'; + + +@Component +export struct SecondPageSearch { + @Consume('appPathStack') appPathStack: NavPathStack; + @State searchValue: string = ''; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + NavDestination() { + Column() { + SearchBar({ + searchValue: this.searchValue, + onBack: () => { + this.appPathStack.clear(); + return false; + } + }) + } + .backgroundColor($r('sys.color.ohos_id_color_sub_background')) + .height(CommonConstants.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) + } + .hideTitleBar(true) + .onBackPressed(() => { + this.appPathStack.clear(); + return true; + }) + } +} + +@Builder +export function SearchPageBuilder() { + SecondPageSearch() +} + +@Component +struct SearchBar { + @Consume('appPathStack') appPathStack: NavPathStack; + @Link searchValue: string; + onBack: () => void = () => { + }; + + build() { + Row() { + Image($r('app.media.ic_back')) + .size({ width: "24vp", height: "24vp" }) + .width("40vp") + .height("40vp") + .margin({ right: "8vp" }) + .onClick(() => this.onBack()) + + SearchInput({ + searchValue: this.searchValue + }) + } + .width(CommonConstants.FULL_PERCENT) + .padding({ + top: "8vp", + bottom: "8vp", + left: "24vp", + right: "24vp" + }) + } +} + +@Component +struct SearchInput { + @Link searchValue: string; + + aboutToAppear(): void { + } + + aboutToDisappear(): void { + } + + build() { + Search({ + placeholder: "Search", + value: this.searchValue + }) + .enableKeyboardOnFocus(true) + .textFont({ size: "16fp" }) + .placeholderFont({ size: "16fp" }) + .height("40vp") + .layoutWeight(1) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/viewmodel/CalculateBmiButtonModuleData.ets b/entry/src/main/ets/generated/viewmodel/CalculateBmiButtonModuleData.ets new file mode 100644 index 0000000..3240605 --- /dev/null +++ b/entry/src/main/ets/generated/viewmodel/CalculateBmiButtonModuleData.ets @@ -0,0 +1,93 @@ +/* + * 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 LazyDataSource from '../util/LazyDataSource'; + +export class DataSource { + private static instance: DataSource; + lazyDataSource: LazyDataSource = new LazyDataSource(); + static readonly IMAGES: Resource[] = + [$r('app.media.background'), $r('app.media.background')]; + static readonly TITLES: string[] = + ['权益中心', '捞币兑换']; + static readonly CONTENTS: string[] = + ['会员福利月月领', '可在商城兑换福利']; + static readonly PAGES: string[] = + ['EmptyPagePathStack', 'EmptyPagePathStack']; + + constructor() { + } + + public static getInstance(): DataSource { + if (!DataSource.instance) { + DataSource.instance = + new DataSource(); + } + return DataSource.instance; + } + + /** + * Data loaded on current view converts network data into rendering data + */ + getResources(): Promise { + + /** + * use your web request here + */ + return new Promise((resolve: Function) => { + const modelList: Array = []; + for (let index = 0; index < DataSource.IMAGES.length; + index++) { + modelList.push(new DataSourceStyleAStyleA( + DataSource.IMAGES[index], + DataSource.TITLES[index], + DataSource.CONTENTS[index], + DataSource.PAGES[index]) + ); + } + this.lazyDataSource.pushArrayData(modelList); + resolve(); + }); + } +} + +export class DataSourceStyleAStyleA { + private image: Resource; + private title: string; + private content: string; + private page: string; + + constructor(image: Resource, title: string, content: string, page: string) { + this.image = image; + this.title = title; + this.content = content; + this.page = page; + } + + getImage(): Resource { + return this.image; + } + + getTitle(): string { + return this.title; + } + + getContent(): string { + return this.content; + } + + getPage(): string { + return this.page; + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/viewmodel/HealthResultModuleData.ets b/entry/src/main/ets/generated/viewmodel/HealthResultModuleData.ets new file mode 100644 index 0000000..091880c --- /dev/null +++ b/entry/src/main/ets/generated/viewmodel/HealthResultModuleData.ets @@ -0,0 +1,109 @@ +/* + * 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 LazyDataSource from '../util/LazyDataSource'; + +export class Data { + private static instance: Data; + lazyDataSource: LazyDataSource = new LazyDataSource(); + static readonly IMAGES: Resource[] = + [$r(('app.media.realImageGen_common_3')), $r(('app.media.realImageGen_common_0'))]; + static readonly MAIN_TEXT: string[] = ['BMI 数值', '健康建议']; + static readonly SUB_TEXT: string[] = ['您的 BMI 值为', '根据您的 BMI 值,我们为您提供以下建议']; + static readonly DESCRIPTION_TEXT: string[] = ['保持健康体重,享受美好生活', '均衡饮食,适量运动,定期体检']; + static readonly TAG_TEXTS_LIST: string[][] = [['健康', '体重'], ['饮食', '运动']]; + static readonly TAG_TEXT_COLORS_LIST: Color[][] = + [[Color.Brown, Color.Green, Color.Gray], [Color.Brown, Color.Green, Color.Gray], + [Color.Brown, Color.Green, Color.Gray], [Color.Brown, Color.Green, Color.Gray], + [Color.Brown, Color.Green, Color.Gray], [Color.Brown, Color.Green, Color.Gray]]; + + constructor() { + } + + public static getInstance(): Data { + if (!Data.instance) { + Data.instance = + new Data(); + } + return Data.instance; + } + + /** + * Data loaded on current view converts network data into rendering data + */ + getResources(): Promise { + + /** + * use your web request here + */ + return new Promise((resolve: Function) => { + const modelList: Array = []; + for (let index = 0; index < Data.IMAGES.length; + index++) { + modelList.push(new DataSource( + Data.IMAGES[index], + Data.MAIN_TEXT[index], + Data.SUB_TEXT[index], + Data.DESCRIPTION_TEXT[index], + Data.TAG_TEXTS_LIST[index], + Data.TAG_TEXT_COLORS_LIST[index])); + } + this.lazyDataSource.pushArrayData(modelList); + resolve(); + }); + } +} + +export class DataSource { + private image: Resource; + private mainText: string; + private subText: string; + private descriptionText: string; + private tagTextList: string[]; + private tagTextColorList: Color[]; + + constructor(image: Resource, mainText: string, subText: string, + descriptionText: string, tagTextList: string[], tagTextColorList: Color[]) { + this.image = image; + this.mainText = mainText; + this.subText = subText; + this.descriptionText = descriptionText; + this.tagTextList = tagTextList; + this.tagTextColorList = tagTextColorList; + } + + getImage(): Resource { + return this.image; + } + + getMainText(): string { + return this.mainText; + } + + getSubText(): string { + return this.subText; + } + + getDescriptionText(): string { + return this.descriptionText; + } + + getTagTextList(): string[] { + return this.tagTextList; + } + + getTagTextColorList(): Color[] { + return this.tagTextColorList; + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/viewmodel/HeightWeightInputModuleData.ets b/entry/src/main/ets/generated/viewmodel/HeightWeightInputModuleData.ets new file mode 100644 index 0000000..0654b4d --- /dev/null +++ b/entry/src/main/ets/generated/viewmodel/HeightWeightInputModuleData.ets @@ -0,0 +1,80 @@ +/* + * 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 LazyDataSource from '../util/LazyDataSource'; + +export class Data { + private static instance: Data; + lazyDataSource: LazyDataSource = new LazyDataSource(); + static readonly ICONS: Resource[] = [$r('app.media.lib_icon_19'), $r('app.media.lib_icon_19')]; + static readonly TITLES: string[] = ['身高', '体重']; + static readonly DESCRIPTIONS: string[] = ['', '']; + + constructor() { + } + + public static getInstance(): Data { + if (!Data.instance) { + Data.instance = + new Data(); + } + return Data.instance; + } + + /** + * Data loaded on current view converts network data into rendering data + */ + getResources(): Promise { + + /** + * use your web request here + */ + return new Promise((resolve: Function) => { + const modelList: Array = []; + for (let index = 0; index < Data.ICONS.length; + index++) { + modelList.push(new DataSource( + Data.ICONS[index], + Data.TITLES[index], + Data.DESCRIPTIONS[index])); + } + this.lazyDataSource.pushArrayData(modelList); + resolve(); + }); + } +} + +export class DataSource { + private icon: Resource; + private title: string; + private description: string; + + constructor(icon: Resource, title: string, description: string) { + this.icon = icon; + this.title = title; + this.description = description; + } + + getIcon(): Resource { + return this.icon; + } + + getTitle(): string { + return this.title; + } + + getDescription(): string { + return this.description; + } +} \ No newline at end of file diff --git a/entry/src/main/ets/generated/viewmodel/PageTitleModuleData.ets b/entry/src/main/ets/generated/viewmodel/PageTitleModuleData.ets new file mode 100644 index 0000000..6466bde --- /dev/null +++ b/entry/src/main/ets/generated/viewmodel/PageTitleModuleData.ets @@ -0,0 +1,67 @@ +import LazyDataSource from '../util/LazyDataSource'; + +export class DataSourceStyleAStyleA { + private icon: Resource; + private title: string; + + constructor(icon: Resource, title: string) { + this.icon = icon; + this.title = title; + } + + getIcon(): Resource { + return this.icon; + } + + getTitle(): string { + return this.title; + } +} + +export class DataSource { + private static instance: DataSource; + lazyDataSource: LazyDataSource = new LazyDataSource(); + private allItems: Array = []; + static readonly ICONS: Resource[] = [$r('app.media.lib_icon_171')]; + static readonly TITLES: string[] = ['BMI计算器']; + static readonly BANNER_IMAGE: Resource = $r(('app.media.realImageGen_common_0')); + + constructor() { + } + + public static getInstance(): DataSource { + if (!DataSource.instance) { + DataSource.instance = new DataSource(); + } + return DataSource.instance; + } + + /** + * Data loaded on current view converts network data into rendering data + */ + getResources(): Promise { + /** + * use your web request here + */ + return new Promise((resolve: Function) => { + const modelList: Array = []; + for (let index = 0; index < DataSource.ICONS.length; index++) { + modelList.push(new DataSourceStyleAStyleA( + DataSource.ICONS[index], + DataSource.TITLES[index] + )); + } + this.allItems = modelList; + this.lazyDataSource.pushArrayData(modelList); + resolve(); + }); + } + + getAllItems(): Array { + return this.allItems; + } + + getBannerImage(): Resource { + return DataSource.BANNER_IMAGE; + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json index 54bb950..116f185 100644 --- a/entry/src/main/resources/base/element/color.json +++ b/entry/src/main/resources/base/element/color.json @@ -1,8 +1,48 @@ { - "color": [ - { - "name": "start_window_background", - "value": "#FFFFFFFF" - } - ] + "color" : [ { + "name" : "start_window_background", + "value" : "#FFFFFFFF" + }, { + "name" : "app_icon_color", + "value" : "#BDBDBD" + }, { + "name" : "app_icon_pressed_color", + "value" : "#9E9E9E" + }, { + "name" : "page_bg_color", + "value" : "#F5F5F5" + }, { + "name" : "page_title_font_color", + "value" : "#616161" + }, { + "name" : "module_bg_color", + "value" : "#EEEEEE" + }, { + "name" : "module_title_font_color", + "value" : "#757575" + }, { + "name" : "module_icon_color", + "value" : "#9E9E9E" + }, { + "name" : "module_item_bg_color", + "value" : "#F2F2F2" + }, { + "name" : "content_main_title_font_color", + "value" : "#616161" + }, { + "name" : "content_sub_title_font_color", + "value" : "#757575" + }, { + "name" : "content_label_font_color", + "value" : "#9E9E9E" + }, { + "name" : "content_font_color", + "value" : "#000000" + }, { + "name" : "button_bg_color", + "value" : "#757575" + }, { + "name" : "button_font_color", + "value" : "#FFFFFF" + } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color_dark.json b/entry/src/main/resources/base/element/color_dark.json new file mode 100644 index 0000000..9b689d0 --- /dev/null +++ b/entry/src/main/resources/base/element/color_dark.json @@ -0,0 +1,156 @@ +{ + "color" : [ { + "name" : "brand_dark", + "value" : "#ff317af7" + }, { + "name" : "warning_dark", + "value" : "#ffd94838" + }, { + "name" : "alert_dark", + "value" : "#ffdb6b42" + }, { + "name" : "confirm_dark", + "value" : "#ff5ba854" + }, { + "name" : "font_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "font_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "font_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "font_fourth_dark", + "value" : "#33ffffff" + }, { + "name" : "font_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "font_on_primary_dark", + "value" : "#ff000000" + }, { + "name" : "font_on_secondary_dark", + "value" : "#99000000" + }, { + "name" : "font_on_tertiary_dark", + "value" : "#66000000" + }, { + "name" : "font_on_fourth_dark", + "value" : "#33000000" + }, { + "name" : "icon_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "icon_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "icon_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "icon_fourth_dark", + "value" : "#33ffffff" + }, { + "name" : "icon_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "icon_sub_emphasize_dark", + "value" : "#66317af7" + }, { + "name" : "icon_on_primary_dark", + "value" : "#ff000000" + }, { + "name" : "icon_on_secondary_dark", + "value" : "#99000000" + }, { + "name" : "icon_on_tertiary_dark", + "value" : "#66000000" + }, { + "name" : "icon_on_fourth_dark", + "value" : "#33000000" + }, { + "name" : "background_primary_dark", + "value" : "#ff000000" + }, { + "name" : "background_secondary_dark", + "value" : "#ff000000" + }, { + "name" : "background_tertiary_dark", + "value" : "#ff202224" + }, { + "name" : "background_fourth_dark", + "value" : "#ff2e3033" + }, { + "name" : "background_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "comp_foreground_primary_dark", + "value" : "#ffe5e5e5" + }, { + "name" : "comp_background_primary_dark", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_trans_dark", + "value" : "#33ffffff" + }, { + "name" : "comp_background_primary_contrary_dark", + "value" : "#ffe5e5e5" + }, { + "name" : "comp_background_gray_dark", + "value" : "#ffe5e5ea" + }, { + "name" : "comp_background_secondary_dark", + "value" : "#19ffffff" + }, { + "name" : "comp_background_tertiary_dark", + "value" : "#0cffffff" + }, { + "name" : "comp_background_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "comp_background_neutral_dark", + "value" : "#ffffffff" + }, { + "name" : "comp_emphasize_secondary_dark", + "value" : "#33317af7" + }, { + "name" : "comp_emphasize_tertiary_dark", + "value" : "#19317af7" + }, { + "name" : "comp_divider_dark", + "value" : "#33ffffff" + }, { + "name" : "comp_common_contrary_dark", + "value" : "#ff000000" + }, { + "name" : "comp_background_focus_dark", + "value" : "#ff000000" + }, { + "name" : "comp_focused_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "comp_focused_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "comp_focused_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "interactive_hover_dark", + "value" : "#0cffffff" + }, { + "name" : "interactive_pressed_dark", + "value" : "#19ffffff" + }, { + "name" : "interactive_focus_dark", + "value" : "#ff317af7" + }, { + "name" : "interactive_active_dark", + "value" : "#ff317af7" + }, { + "name" : "interactive_select_dark", + "value" : "#33ffffff" + }, { + "name" : "interactive_click_dark", + "value" : "#19ffffff" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color_light.json b/entry/src/main/resources/base/element/color_light.json new file mode 100644 index 0000000..33b544e --- /dev/null +++ b/entry/src/main/resources/base/element/color_light.json @@ -0,0 +1,156 @@ +{ + "color" : [ { + "name" : "brand", + "value" : "#ff0a59f7" + }, { + "name" : "warning", + "value" : "#ffe84026" + }, { + "name" : "alert", + "value" : "#ffed6f21" + }, { + "name" : "confirm", + "value" : "#ff64bb5c" + }, { + "name" : "font_primary", + "value" : "#e5000000" + }, { + "name" : "font_secondary", + "value" : "#99000000" + }, { + "name" : "font_tertiary", + "value" : "#66000000" + }, { + "name" : "font_fourth", + "value" : "#33000000" + }, { + "name" : "font_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "font_on_primary", + "value" : "#ffffffff" + }, { + "name" : "font_on_secondary", + "value" : "#99ffffff" + }, { + "name" : "font_on_tertiary", + "value" : "#66ffffff" + }, { + "name" : "font_on_fourth", + "value" : "#33ffffff" + }, { + "name" : "icon_primary", + "value" : "#e5000000" + }, { + "name" : "icon_secondary", + "value" : "#99000000" + }, { + "name" : "icon_tertiary", + "value" : "#66000000" + }, { + "name" : "icon_fourth", + "value" : "#33000000" + }, { + "name" : "icon_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "icon_sub_emphasize", + "value" : "#660a59f7" + }, { + "name" : "icon_on_primary", + "value" : "#ffffffff" + }, { + "name" : "icon_on_secondary", + "value" : "#99ffffff" + }, { + "name" : "icon_on_tertiary", + "value" : "#66ffffff" + }, { + "name" : "icon_on_fourth", + "value" : "#33ffffff" + }, { + "name" : "background_primary", + "value" : "#ffffffff" + }, { + "name" : "background_secondary", + "value" : "#fff1f3f5" + }, { + "name" : "background_tertiary", + "value" : "#ffe5e5ea" + }, { + "name" : "background_fourth", + "value" : "#ffd1d1d6" + }, { + "name" : "background_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "comp_foreground_primary", + "value" : "#ff000000" + }, { + "name" : "comp_background_primary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_trans", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_contrary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_gray", + "value" : "#fff1f3f5" + }, { + "name" : "comp_background_secondary", + "value" : "#19000000" + }, { + "name" : "comp_background_tertiary", + "value" : "#0c000000" + }, { + "name" : "comp_background_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "comp_background_neutral", + "value" : "#ff000000" + }, { + "name" : "comp_emphasize_secondary", + "value" : "#330a59f7" + }, { + "name" : "comp_emphasize_tertiary", + "value" : "#190a59f7" + }, { + "name" : "comp_divider", + "value" : "#33000000" + }, { + "name" : "comp_common_contrary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_focus", + "value" : "#fff1f3f5" + }, { + "name" : "comp_focused_primary", + "value" : "#e5000000" + }, { + "name" : "comp_focused_secondary", + "value" : "#99000000" + }, { + "name" : "comp_focused_tertiary", + "value" : "#66000000" + }, { + "name" : "interactive_hover", + "value" : "#0c000000" + }, { + "name" : "interactive_pressed", + "value" : "#19000000" + }, { + "name" : "interactive_focus", + "value" : "#ff0a59f7" + }, { + "name" : "interactive_active", + "value" : "#ff0a59f7" + }, { + "name" : "interactive_select", + "value" : "#33000000" + }, { + "name" : "interactive_click", + "value" : "#19000000" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/float.json b/entry/src/main/resources/base/element/float.json index 33ea223..658ac5a 100644 --- a/entry/src/main/resources/base/element/float.json +++ b/entry/src/main/resources/base/element/float.json @@ -1,8 +1,9 @@ { - "float": [ - { - "name": "page_text_font_size", - "value": "50fp" - } - ] -} + "float" : [ { + "name" : "font_size", + "value" : "14fp" + }, { + "name" : "page_text_font_size", + "value" : "50fp" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/font_size.json b/entry/src/main/resources/base/element/font_size.json new file mode 100644 index 0000000..bf3fa77 --- /dev/null +++ b/entry/src/main/resources/base/element/font_size.json @@ -0,0 +1,63 @@ +{ + "integer" : [ { + "name" : "display_text_L", + "value" : 56, + "comment" : "Light" + }, { + "name" : "display_text_M", + "value" : 48, + "comment" : "Light" + }, { + "name" : "display_text_S", + "value" : 38, + "comment" : "Light" + }, { + "name" : "title_text_L", + "value" : 30, + "comment" : "Bold" + }, { + "name" : "title_text_M", + "value" : 24, + "comment" : "Bold" + }, { + "name" : "title_text_S", + "value" : 20, + "comment" : "Bold" + }, { + "name" : "subtitle_text_L", + "value" : 18, + "comment" : "Medium" + }, { + "name" : "subtitle_text_M", + "value" : 16, + "comment" : "Medium" + }, { + "name" : "subtitle_text_S", + "value" : 14, + "comment" : "Medium" + }, { + "name" : "body_text_L", + "value" : 16, + "comment" : "Regular" + }, { + "name" : "body_text_M", + "value" : 14, + "comment" : "Regular" + }, { + "name" : "body_text_S", + "value" : 12, + "comment" : "Regular" + }, { + "name" : "caption_text_L", + "value" : 12, + "comment" : "Medium" + }, { + "name" : "caption_text_M", + "value" : 10, + "comment" : "Medium" + }, { + "name" : "caption_text_S", + "value" : 8, + "comment" : "Medium" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index f945955..18d85ed 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -1,16 +1,36 @@ { - "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "label" - } - ] + "string" : [ { + "name" : "module_desc", + "value" : "module description" + }, { + "name" : "EntryAbility_desc", + "value" : "description" + }, { + "name" : "EntryAbility_label", + "value" : "label" + }, { + "name" : "defaultForm_label", + "value" : "form_label" + }, { + "name" : "defaultForm_desc", + "value" : "form_description" + }, { + "name" : "EntryFormAbility_desc", + "value" : "form_description" + }, { + "name" : "EntryFormAbility_label", + "value" : "form_label" + }, { + "name" : "widget_desc", + "value" : "This is a service widget." + }, { + "name" : "widget_display_name", + "value" : "widget" + }, { + "name" : "widget1_desc", + "value" : "This is a service widget." + }, { + "name" : "widget1_display_name", + "value" : "widget1" + } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/media/background.png b/entry/src/main/resources/base/media/background.png index 923f2b3..f939c9f 100644 Binary files a/entry/src/main/resources/base/media/background.png and b/entry/src/main/resources/base/media/background.png differ diff --git a/entry/src/main/resources/base/media/ic_back.svg b/entry/src/main/resources/base/media/ic_back.svg new file mode 100644 index 0000000..a67bad0 --- /dev/null +++ b/entry/src/main/resources/base/media/ic_back.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/entry/src/main/resources/base/media/ic_failure.svg b/entry/src/main/resources/base/media/ic_failure.svg new file mode 100644 index 0000000..6d1e0c0 --- /dev/null +++ b/entry/src/main/resources/base/media/ic_failure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/ic_public_app.svg b/entry/src/main/resources/base/media/ic_public_app.svg new file mode 100644 index 0000000..70dc9dc --- /dev/null +++ b/entry/src/main/resources/base/media/ic_public_app.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_app + + + + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000..514fd95 Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ diff --git a/entry/src/main/resources/base/media/lib_icon_171.svg b/entry/src/main/resources/base/media/lib_icon_171.svg new file mode 100644 index 0000000..f6ff7bd --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_171.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/entry/src/main/resources/base/media/lib_icon_19.svg b/entry/src/main/resources/base/media/lib_icon_19.svg new file mode 100644 index 0000000..4087ead --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_19.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/entry/src/main/resources/base/media/noImage.png b/entry/src/main/resources/base/media/noImage.png new file mode 100644 index 0000000..7155c22 Binary files /dev/null and b/entry/src/main/resources/base/media/noImage.png differ diff --git a/entry/src/main/resources/base/media/realImageGen_common_0.png b/entry/src/main/resources/base/media/realImageGen_common_0.png new file mode 100644 index 0000000..c6cacb6 Binary files /dev/null and b/entry/src/main/resources/base/media/realImageGen_common_0.png differ diff --git a/entry/src/main/resources/base/media/realImageGen_common_3.png b/entry/src/main/resources/base/media/realImageGen_common_3.png new file mode 100644 index 0000000..7dc82b9 Binary files /dev/null and b/entry/src/main/resources/base/media/realImageGen_common_3.png differ diff --git a/entry/src/main/resources/base/media/realImageGen_travel_0.png b/entry/src/main/resources/base/media/realImageGen_travel_0.png new file mode 100644 index 0000000..62aae9e Binary files /dev/null and b/entry/src/main/resources/base/media/realImageGen_travel_0.png differ diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index f6191bd..3e889f6 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -1,6 +1,3 @@ { - "src": [ - "pages/Index", - "pages/Second" - ] -} + "src" : [ "generated/Index", "pages/Index", "pages/Second" ] +} \ No newline at end of file