diff --git a/arkoala-arkts/arkui/src/Application.ts b/arkoala-arkts/arkui/src/Application.ts index e3fee2aa0d705586b67c6ecdae29c0869deee004..4c611d4956935d8797bf9fc22b146065410b6a98 100644 --- a/arkoala-arkts/arkui/src/Application.ts +++ b/arkoala-arkts/arkui/src/Application.ts @@ -25,6 +25,7 @@ import { checkEvents, setCustomEventsChecker } from "./generated/Events" import { checkArkoalaCallbacks } from "./generated/peers/CallbacksChecker" import { setUIDetachedRootCreator } from "./generated/peers/CallbackTransformer" import { enterForeignContext, leaveForeignContext } from "./handwritten" +import { Routed } from "./handwritten" setCustomEventsChecker(checkArkoalaCallbacks) @@ -80,7 +81,10 @@ export function createUiDetachedRoot( const node = manager.updatableNode(peerFactory(), (context: StateContext) => { const frozen = manager.frozen manager.frozen = true - memoEntry(context, 0, builder) + memoEntry(context, 0, + /** @memo */ + () => WithAppRouter(builder) + ) manager.frozen = frozen }) detachedRoots.set(node.value.peer.ptr, node) @@ -96,6 +100,20 @@ export function destroyUiDetachedRoot(node: PeerNode): void { root.dispose() } +/** @memo */ +function WithAppRouter( + /** @memo */ + content?: () => void, + url?: string, +) : void { + Routed( + () => { + content?.() + }, + url + ) +} + function dumpTree(node: IncrementalNode, indent: int32 = 0) { const indentToString = (indent: number) => { let str = "" @@ -155,7 +173,9 @@ export class Application { return manager.updatableNode(peer, (context: StateContext) => { const frozen = manager.frozen manager.frozen = true - memoEntry(context, 0, builder) + memoEntry(context, 0, /** @memo */ + () => { WithAppRouter(builder) } + ) manager.frozen = frozen }) } @@ -228,8 +248,9 @@ export class Application { manager.syncChanges() manager.updateSnapshot() this.computeRoot() - for (const detachedRoot of detachedRoots.values()) + for (const detachedRoot of detachedRoots.values()) { detachedRoot.value + } if (partialUpdates.length > 0) { // If there are pending partial updates - we apply them one by one and provide update context. for (let update of partialUpdates) { @@ -245,8 +266,9 @@ export class Application { // Compute new tree state try { root.value - for (const detachedRoot of detachedRoots.values()) + for (const detachedRoot of detachedRoots.values()) { detachedRoot.value + } } catch (error) { InteropNativeModule._NativeLog('has error in partialUpdates') } @@ -279,9 +301,10 @@ export class Application { } catch (error) { InteropNativeModule._NativeLog(`Application.enter() error: ${error}`) if (error instanceof Error) { - if (error.stack) { + const stack = error.stack + if (stack) { leaveForeignContext() - InteropNativeModule._NativeLog(error.stack!.toString()) + InteropNativeModule._NativeLog("Application.enter: " + stack) return true } } diff --git a/arkoala-arkts/arkui/src/ArkComponentRoot.ts b/arkoala-arkts/arkui/src/ArkComponentRoot.ts index 3472d5f1fe7f9033d456f9a5b72147cc0fe61e85..f87858db488a89db3bac10b5d3b344ffe9575f0a 100644 --- a/arkoala-arkts/arkui/src/ArkComponentRoot.ts +++ b/arkoala-arkts/arkui/src/ArkComponentRoot.ts @@ -18,7 +18,7 @@ import { PeerNode } from "./PeerNode"; import { ArkComponentRootPeer } from "./generated/peers/ArkStaticComponentsPeer"; import { ArkCustomComponent } from "./ArkCustomComponent" import { int32 } from "@koalaui/common" -import { CurrentRouterTransitionState } from "./handwritten"; +import { CurrentRouterTransitionState, VisibilityHiding, VisibilityShowing, WithRouterTransitionState } from "./handwritten/Router"; /** @memo */ export function ArkComponentRoot( @@ -30,32 +30,42 @@ export function ArkComponentRoot( () => ArkComponentRootPeer.create(), (node: PeerNode) => { let state = CurrentRouterTransitionState() - RunEffect(state != undefined ? (state!.visibility as int32) : -1, (visibility: int32) => { - //console.log(`Router transition changed: ${visibility}`) - // Write properly when enum import will be fixed. - if (visibility == 2 /* RouterTransitionVisibility.Showing */) { - component.onPageShow() - } - if (visibility == 3 /* RouterTransitionVisibility.Hiding */) { - component.onPageHide() - } - }) - let shown = rememberDisposable(() => { - let state = mutableState(false) - scheduleCallback(() => { - component.aboutToAppear() - // TODO: page visibility doesn't belong here, remove when router transition state propely maintained. - component.onPageShow() - state.value = true + if (state) { + let shown = rememberDisposable(() => { + let state = mutableState(false) + scheduleCallback(() => { + component.aboutToAppear() + // TODO: page visibility doesn't belong here, remove when router transition state properly maintained. + component.onPageShow() + state.value = true + }) + return state + }, (_: MutableState | undefined) => + scheduleCallback(() => { + component.aboutToDisappear() + // TODO: page visibility doesn't belong here, remove when router transition state properly maintained. + component.onPageHide() + }) + ) + + RunEffect(state.visibility, (visibility:int32) => { + switch (visibility) { + case VisibilityShowing: + component.onPageShow() + break + + case VisibilityHiding: + component.onPageHide() + break + + default: break + } }) - return state - }, (inited: MutableState | undefined) => - scheduleCallback(() => { - component.aboutToDisappear() - // TODO: page visibility doesn't belong here, remove when router transition state propely maintained. - component.onPageHide() - })) - if (!shown.value) return - content() - }) + + component.pageTransition() + + if (shown.value) WithRouterTransitionState(undefined, content) // skip first frame and hide router state + } + } + ) } \ No newline at end of file diff --git a/arkoala-arkts/arkui/src/ArkStructBase.ts b/arkoala-arkts/arkui/src/ArkStructBase.ts index 16365245a20e3e8421d44a213dd5c74e8cf2345e..fc2ea77e984093402ec6135c595d9640bafa1d30 100644 --- a/arkoala-arkts/arkui/src/ArkStructBase.ts +++ b/arkoala-arkts/arkui/src/ArkStructBase.ts @@ -1,8 +1,23 @@ -import { MutableState, mutableState, remember, rememberDisposable, rememberMutableState, RunEffect, scheduleCallback } from "@koalaui/runtime" +/* + * 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 { remember } from "@koalaui/runtime" import { ArkCustomComponentImpl } from "./ArkCustomComponent" import { ArkCommonMethodComponent } from "./generated" -import { CurrentRouterTransitionState, RouterTransitionState, RouterTransitionVisibility, WithRouterTransitionState } from "./handwritten" -import { int32 } from "@koalaui/common" +import { ArkPageTransitionEnter, ArkPageTransitionExit } from "./handwritten/ArkPageTransition"; +import { PageTransitionOptions } from "./generated/ArkPageTransitionInterfaces"; import { ArkComponentRoot } from "./ArkComponentRoot" /** base class for user's structs */ @@ -58,4 +73,10 @@ export abstract class ArkStructBase extends ArkCustomComponentImpl content?: () => void, initializers?: T_Options ): void + + /** @memo */ + pageTransition(): void { + ArkPageTransitionEnter(undefined, undefined, { duration: 100 } as PageTransitionOptions ) + ArkPageTransitionExit(undefined, undefined, { duration: 100 } as PageTransitionOptions ) + } } diff --git a/arkoala-arkts/arkui/src/UserView.ts b/arkoala-arkts/arkui/src/UserView.ts index 90c686df611fbee77af31327c5e7d7e8a0b9dcc7..0806d9c1342f81e179153ba76b4d662ee069f300 100644 --- a/arkoala-arkts/arkui/src/UserView.ts +++ b/arkoala-arkts/arkui/src/UserView.ts @@ -17,7 +17,7 @@ import { int32, int8Array } from "@koalaui/common" export type UserViewBuilder = /** @memo */ -(/*root: PeerNode*/) => void +() => void export class UserView { constructor() {} diff --git a/arkoala-arkts/arkui/src/handwritten/ArkPageTransitionData.ts b/arkoala-arkts/arkui/src/handwritten/ArkPageTransitionData.ts index 0a5c9a88d9b48e1abc4c8c570c6d49ea6487a8fc..0c3c89acca13eab8a8a06ffc624a31a1176060ae 100644 --- a/arkoala-arkts/arkui/src/handwritten/ArkPageTransitionData.ts +++ b/arkoala-arkts/arkui/src/handwritten/ArkPageTransitionData.ts @@ -13,21 +13,7 @@ * limitations under the License. */ -import { RouteType, SlideEffect, PageTransitionOptions } from "../generated" - -interface TranslateOptions { - x?: string | number | undefined; - y?: string | number | undefined; - z?: string | number | undefined; -} - -interface ScaleOptions { - x?: number | undefined; - y?: number | undefined; - z?: number | undefined; - centerX?: string | number | undefined; - centerY?: string | number | undefined; -} +import { RouteType, SlideEffect, PageTransitionOptions, TranslateOptions, ScaleOptions } from "../generated" export class ArkPageTransitionData { params: PageTransitionOptions diff --git a/arkoala-arkts/arkui/src/handwritten/Router.ts b/arkoala-arkts/arkui/src/handwritten/Router.ts index 52642a7b70124acfb3fde50893a50121f518b922..1e42f9ab01e3474644afe5c2f8903a97fabd202e 100644 --- a/arkoala-arkts/arkui/src/handwritten/Router.ts +++ b/arkoala-arkts/arkui/src/handwritten/Router.ts @@ -14,20 +14,39 @@ */ -import { int32, observableProxyArray } from "@koalaui/common" +import { int32 } from "@koalaui/common" import { MutableState, contextLocal, contextLocalScope, - mutableState + mutableState, + remember, + RepeatByArray, + arrayState, + RunEffect, } from "@koalaui/runtime" -import { RouteType} from "../generated" +//import { RouteType} from "../generated/ArkPageTransitionInterfaces" + +// ---------------------------------------------------------- +// TODO: Remove these constants when enums are fixed in Panda +export const VisibilityHidden = 0 +export const VisibilityVisible = 1 +export const VisibilityShowing = 2 +export const VisibilityHiding = 3 + +const RouteType_NONE = 0 +const RouteType_None = 0 +const RouteType_PUSH = 1 +const RouteType_Push = 1 +const RouteType_POP = 2 +const RouteType_Pop = 2 +// ---------------------------------------------------------- export enum RouterTransitionVisibility { - Hidden, - Visible, - Showing, - Hiding, + Hidden = VisibilityHidden, + Visible = VisibilityVisible, + Showing = VisibilityShowing, + Hiding = VisibilityHiding } export type MemoFunction = @@ -36,8 +55,8 @@ export type MemoFunction = export interface RouterTransitionState { pageId: int32 - visibility: RouterTransitionVisibility - route?: RouteType + visibility: int32 // TODO: Use RouterTransitionVisibility enum when enums are fixed in Panda + route?: int32 // TODO: Use RouteType enum when enums are fixed in Panda } class VisiblePage { @@ -49,16 +68,16 @@ class VisiblePage { constructor( page: MemoFunction, version: int32, - visibility: RouterTransitionVisibility, - route?: RouteType + visibility: int32, // TODO: Use RouterTransitionVisibility enum when enums are fixed in Panda + route?: int32 // TODO: Use RouteType enum when enums are fixed in Panda ) { this.page = page this.version = version this.transitionState = mutableState({ pageId: version, visibility, route } as RouterTransitionState) } - setTransitionState(visibility: RouterTransitionVisibility, route?: RouteType) { - this.transitionState.value = { pageId: this.version, visibility, route } + setTransitionState(visibility: int32, route?: int32) { + this.transitionState.value = { pageId: this.version, visibility, route } as RouterTransitionState } get transition(): RouterTransitionState { @@ -67,7 +86,7 @@ class VisiblePage { } class RouterState { - readonly visiblePages = observableProxyArray() + readonly visiblePages = arrayState() currentActivePage = mutableState(0) constructor( page: MemoFunction, @@ -79,7 +98,7 @@ class RouterState { this.url = url this.params = params this.resolve = resolve - this.visiblePages.push(new VisiblePage(page, this.version.value, RouterTransitionVisibility.Visible)) + this.visiblePages.push(new VisiblePage(page, this.version.value, VisibilityVisible)) } /** @memo */ page: MemoFunction @@ -205,7 +224,8 @@ class RouterImpl implements Router { if (push) { this.stack.push(new RouterStackEntry(this.state.url, this.state.page, this.state.params)) } - this.activate(entry, push ? RouteType.Push : RouteType.None, params, resolve) + // TODO: Use RouteType enum values when enums are fixed in Panda + this.activate(entry, push ? RouteType_Push : RouteType_None, params, resolve) } else { const resolver = this.resolver if (resolver !== undefined) { @@ -214,7 +234,7 @@ class RouterImpl implements Router { if (push) { this.stack.push(new RouterStackEntry(this.state.url, this.state.page, this.state.params)) } - this.activate(new RouterRegistryEntry(url, page), push ? RouteType.Push : RouteType.None, params, resolve) + this.activate(new RouterRegistryEntry(url, page), push ? RouteType_Push : RouteType_None, params, resolve) }) .catch((error: string | undefined): void => reject(error)) } @@ -228,58 +248,56 @@ class RouterImpl implements Router { showingPage: number = -1 hidingPage: number = -1 - private activate(entry: RouterRegistryEntry, route: RouteType, params: Map | undefined, resolve: () => void) { + // TODO: Use RouteType enum as route parameter when enums are fixed in Panda + private activate(entry: RouterRegistryEntry, route: int32, params: Map | undefined, resolve: () => void) { const state = this.state state.version.value++ // console.log("activating", RouteType[route], entry.url, "version", state.version.value) let previousVisiblePageIndex = this.findIndexByVersion(state.currentActivePage.value) - let previousVisiblePage = state.visiblePages[previousVisiblePageIndex] - if (previousVisiblePage) previousVisiblePage.setTransitionState(RouterTransitionVisibility.Hiding, route) + let previousVisiblePage = state.visiblePages.value[previousVisiblePageIndex] + if (previousVisiblePage) previousVisiblePage.setTransitionState(VisibilityHiding, route) state.page = entry.page state.url = entry.url state.params = params state.resolve = resolve let newVisiblePage: VisiblePage - /* - TODO SHOPPING: transform switch to ifs - */ - console.log(`TODO SHOPPING: activate`) - // switch (route) { - // case RouteType.Push: { - // newVisiblePage = new VisiblePage(entry.page, state.version.value, RouterTransitionVisibility.Showing, route) - // state.visiblePages.splice(previousVisiblePageIndex + 1, 0, newVisiblePage) - // break - // } - // case RouteType.Pop: { - // const index = this.stack.length // TODO: store uid in registry to find a page - // newVisiblePage = state.visiblePages[index] - // newVisiblePage.setTransitionState(RouterTransitionVisibility.Showing, route) - // // remove all hidden pages removed from the stack - // for (let i = state.visiblePages.length - 1; i > index; i--) { - // const visibility = state.visiblePages[i].transition.visibility - // if (visibility == RouterTransitionVisibility.Hidden) state.visiblePages.splice(i) - // } - // break - // } - // case RouteType.None: { - // // TODO: can/shall we animate replace? - // newVisiblePage = new VisiblePage(entry.page, state.version.value, RouterTransitionVisibility.Showing, route) - // state.visiblePages[previousVisiblePageIndex] = newVisiblePage - // break - // } - // default: - // throw new Error("Illegal RouteType: " + route) - // } - // this.hidingPage = previousVisiblePage?.version ?? -1 - // this.showingPage = newVisiblePage.version - // state.currentActivePage.value = newVisiblePage.version + + switch (route) { + case RouteType_Push: { + newVisiblePage = new VisiblePage(entry.page, state.version.value, VisibilityShowing, route) + state.visiblePages.splice(previousVisiblePageIndex + 1, 0, newVisiblePage) + break + } + case RouteType_Pop: { + const index = this.stack.length // TODO: store uid in registry to find a page + newVisiblePage = state.visiblePages.value[index] + newVisiblePage.setTransitionState(VisibilityShowing, route) + // remove all hidden pages removed from the stack + for (let i = state.visiblePages.length - 1; i > index; i--) { + const visibility = state.visiblePages.value[i].transition.visibility + if (visibility == VisibilityHidden) state.visiblePages.splice(i, undefined) + } + break + } + case RouteType_None: { + // TODO: can/shall we animate replace? + newVisiblePage = new VisiblePage(entry.page, state.version.value, VisibilityShowing, route) + state.visiblePages.set(previousVisiblePageIndex, newVisiblePage) + break + } + default: + throw new Error("Illegal RouteType: " + route) + } + this.hidingPage = previousVisiblePage?.version ?? -1 + this.showingPage = newVisiblePage.version + state.currentActivePage.value = newVisiblePage.version } findIndexByVersion(version: int32): int32 { const array = this.state.visiblePages const length = array.length for (let i = 0; i < length; i++) { - if (array[i].version == version) return i + if (array.value[i].version == version) return i } return -1 } @@ -287,26 +305,26 @@ class RouterImpl implements Router { onPageTransitionEnd(pageId: int32): void { const index = this.findIndexByVersion(pageId) if (index < 0) return - const page = this.state.visiblePages[index] - if (page.transition.visibility == RouterTransitionVisibility.Showing) { + const page = this.state.visiblePages.value[index] + if (page.transition.visibility == VisibilityShowing) { if (pageId == this.state.currentActivePage.value) { console.log("PAGE VISIBLE:", page.transition.pageId) - page.setTransitionState(RouterTransitionVisibility.Visible) + page.setTransitionState(VisibilityVisible) } else { - // console.log("ERROR: showing page cannot be shown:", page.transition.route ? RouteType[page.transition.route] : "unknown") - page.setTransitionState(RouterTransitionVisibility.Hidden) + page.setTransitionState(VisibilityHidden) } - } else if (page.transition.visibility == RouterTransitionVisibility.Hiding) { + } else if (page.transition.visibility == VisibilityHiding) { if (index < this.stack.length) { console.log("PAGE HIDDEN:", page.transition.pageId) - page.setTransitionState(RouterTransitionVisibility.Hidden) + page.setTransitionState(VisibilityHidden) } else { console.log("PAGE REMOVED:", page.transition.pageId) this.state.visiblePages.splice(index, 1) } - } else { - // console.log("ERROR: no page transition:", RouterTransitionVisibility[page.transition.visibility], page.transition.route ? RouteType[page.transition.route] : "unknown") } + // else { + // // console.log("ERROR: no page transition:", RouterTransitionVisibility[page.transition.visibility], page.transition.route ? RouteType[page.transition.route] : "unknown") + // } } push(url: string, params?: Map): Promise { @@ -338,7 +356,7 @@ class RouterImpl implements Router { if (entry) { this.activate( new RouterRegistryEntry(entry.url, entry.page), - RouteType.Pop, + RouteType_Pop, params ?? entry.params, resolve ) @@ -358,36 +376,26 @@ class RouterImpl implements Router { } /** @memo */ -// export function Routed( -// /** @memo */ -// initial: () => void, -// /** @memo */ -// contentOwner: ( -// /** @memo */ -// content: () => void -// ) => void, -// initialUrl?: string, -// ) { -// const routerState = remember(() => new RouterState(initial, initialUrl ?? "_initial_")) -// const router = remember(() => new RouterImpl(routerState)) -// RunEffect<() => void>(routerState.resolve!, (resolve?: () => void): void => { resolve?.() }) -// contextLocalScope(CURRENT_ROUTER, router, (): void => { -// contentOwner( -// /** @memo */ -// (): void => { -// RepeatByArray( -// routerState.visiblePages, -// (page: VisiblePage): int32 => { return page.version }, -// (page: VisiblePage): void => { -// WithRouterTransitionState(page.transition, () => { -// page.page() -// }) -// } -// ) -// } -// ) -// }) -// } +export function Routed( + /** @memo */ + initial: () => void, + initialUrl?: string, +) { + const routerState = remember(() => new RouterState(initial, initialUrl ?? "_initial_")) + const router = remember(() => new RouterImpl(routerState)) + RunEffect<(() => void) | undefined>(routerState.resolve, (resolve?: () => void): void => { resolve?.() }) + contextLocalScope(CURRENT_ROUTER, router, () => { + RepeatByArray( + routerState.visiblePages.value, + (page: VisiblePage, index: int32): int32 => { return page.version }, + (page: VisiblePage, index: int32): void => { + WithRouterTransitionState(page.transition, () => { + page.page() + }) + } + ) + }) +} /** @memo */ export function CurrentRouter(): Router | undefined { @@ -396,7 +404,7 @@ export function CurrentRouter(): Router | undefined { /** @memo */ export function CurrentRouterTransitionState(): RouterTransitionState | undefined { - return contextLocal(CURRENT_ROUTER_TRANSITION)?.value + return contextLocal(CURRENT_ROUTER_TRANSITION)?.value } /** @memo */ diff --git a/arkoala-arkts/arkui/src/handwritten/index.ts b/arkoala-arkts/arkui/src/handwritten/index.ts index eeb6fe2981f5a793b234b5ed48ee269e25f71cea..d2bde379dd3be8325b6d3f42f85c1c5759c9acc6 100644 --- a/arkoala-arkts/arkui/src/handwritten/index.ts +++ b/arkoala-arkts/arkui/src/handwritten/index.ts @@ -18,6 +18,3 @@ export interface ISinglePropertyChangeSubscriber {} export interface NavigationAttribute {} export interface PageTransitionEnterInterface {} export interface PageTransitionExitInterface {} - -export { ArkPageTransitionEnter as PageTransitionEnter } from "./ArkPageTransition" -export { ArkPageTransitionExit as PageTransitionExit } from "./ArkPageTransition" diff --git a/arkoala-arkts/cats/.gitignore b/arkoala-arkts/cats/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9085d4a755e0fea4b249cd725a4be76cef157e9a --- /dev/null +++ b/arkoala-arkts/cats/.gitignore @@ -0,0 +1,2 @@ +oh_modules +generated \ No newline at end of file diff --git a/arkoala-arkts/cats/application/AppScope/app.json5 b/arkoala-arkts/cats/application/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2b158f05afee4931a92bfa3b584a0ce713466338 --- /dev/null +++ b/arkoala-arkts/cats/application/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.cats", + "vendor": "cats", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/arkoala-arkts/cats/application/AppScope/resources/base/element/string.json b/arkoala-arkts/cats/application/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..5b9c990b7be02b272426b5597a27e811b1cf9551 --- /dev/null +++ b/arkoala-arkts/cats/application/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "Cats" + } + ] +} diff --git a/arkoala-arkts/cats/application/AppScope/resources/base/media/app_icon.png b/arkoala-arkts/cats/application/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/arkoala-arkts/cats/application/AppScope/resources/base/media/app_icon.png differ diff --git a/arkoala-arkts/cats/application/build-profile.json5 b/arkoala-arkts/cats/application/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3ead1e058d9d9f02f77efdd11d0ff722c97cc8d4 --- /dev/null +++ b/arkoala-arkts/cats/application/build-profile.json5 @@ -0,0 +1,34 @@ +{ + "app": { + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS" + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/code-linter.json5 b/arkoala-arkts/cats/application/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..77b31b517a3e5c2f34c3ae1bf44083c0c06cbd6d --- /dev/null +++ b/arkoala-arkts/cats/application/code-linter.json5 @@ -0,0 +1,20 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/.gitignore b/arkoala-arkts/cats/application/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/build-profile.json5 b/arkoala-arkts/cats/application/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/hvigorfile.ts b/arkoala-arkts/cats/application/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/arkoala-arkts/cats/application/entry/obfuscation-rules.txt b/arkoala-arkts/cats/application/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/arkoala-arkts/cats/application/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/oh-package.json5 b/arkoala-arkts/cats/application/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/arkoala-arkts/cats/application/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/arkoala-arkts/cats/application/entry/src/main/ets/entryability/EntryAbility.ets b/arkoala-arkts/cats/application/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..47e7c29daad4648a5bab6b1b71675c855c0a4bc6 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,42 @@ +import { AbilityConstant, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class EntryAbility extends UIAbility { + 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.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.'); + }); + } + + 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/arkoala-arkts/cats/application/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/arkoala-arkts/cats/application/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc55c03d3eea7ce53d5346c732a39ce9bf5267e1 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,12 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(0x0000, 'testTag', 'onBackup ok'); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/ets/pages/Index.ets b/arkoala-arkts/cats/application/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..9393e00f3990f2da833746e03f7fc066e15766bc --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,20 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/ets/resources/koala.png b/arkoala-arkts/cats/application/entry/src/main/ets/resources/koala.png new file mode 100644 index 0000000000000000000000000000000000000000..c2053602ac7ec945e4099ceee995831e0a3a08b9 Binary files /dev/null and b/arkoala-arkts/cats/application/entry/src/main/ets/resources/koala.png differ diff --git a/arkoala-arkts/cats/application/entry/src/main/module.json5 b/arkoala-arkts/cats/application/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4b8c6e3e9d96866b58c1e31ee1f73d7735152f0b --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/module.json5 @@ -0,0 +1,58 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "metadata": [ + { + "name": "ArkoalaPlugin", + "value": "true" + } + ], + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/element/color.json b/arkoala-arkts/cats/application/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/element/string.json b/arkoala-arkts/cats/application/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/media/background.png b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d Binary files /dev/null and b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/background.png differ diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/media/foreground.png b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902 Binary files /dev/null and b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/foreground.png differ diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/media/layered_image.json b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/media/startIcon.png b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/arkoala-arkts/cats/application/entry/src/main/resources/base/media/startIcon.png differ diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/backup_config.json b/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/main_pages.json b/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/en_US/element/string.json b/arkoala-arkts/cats/application/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/main/resources/zh_CN/element/string.json b/arkoala-arkts/cats/application/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/mock/mock-config.json5 b/arkoala-arkts/cats/application/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/Ability.test.ets b/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/List.test.ets b/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/ohosTest/module.json5 b/arkoala-arkts/cats/application/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/arkoala-arkts/cats/application/entry/src/test/List.test.ets b/arkoala-arkts/cats/application/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/entry/src/test/LocalUnit.test.ets b/arkoala-arkts/cats/application/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/arkoala-arkts/cats/application/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/hvigor/hvigor-config.json5 b/arkoala-arkts/cats/application/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..06b2783670a348f95533b352c1ceda909a842bbc --- /dev/null +++ b/arkoala-arkts/cats/application/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.0", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/arkoala-arkts/cats/application/hvigorfile.ts b/arkoala-arkts/cats/application/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/arkoala-arkts/cats/application/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/arkoala-arkts/cats/application/local.properties b/arkoala-arkts/cats/application/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..20f608699522ce5b5f170457336fbfbf96165c62 --- /dev/null +++ b/arkoala-arkts/cats/application/local.properties @@ -0,0 +1,9 @@ +# This file is automatically generated by DevEco Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file should *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# For customization when using a Version Control System, please read the header note. + + diff --git a/arkoala-arkts/cats/application/oh-package-lock.json5 b/arkoala-arkts/cats/application/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c515a170a788b4e15a0f13cd39e020a0ec945ede --- /dev/null +++ b/arkoala-arkts/cats/application/oh-package-lock.json5 @@ -0,0 +1,25 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har": "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har", + "@koalaui/user@../user/app/user/build/default/outputs/default/user.har": "@koalaui/user@../user/app/user/build/default/outputs/default/user.har" + }, + "packages": { + "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har": { + "name": "@koalaui/arkoala-arkui", + "version": "1.0.0", + "resolved": "../../har/app/arkoala/build/default/outputs/default/arkoala.har", + "registryType": "local" + }, + "@koalaui/user@../user/app/user/build/default/outputs/default/user.har": { + "name": "@koalaui/user", + "version": "1.0.0", + "resolved": "../user/app/user/build/default/outputs/default/user.har", + "registryType": "local" + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/application/oh-package.json5 b/arkoala-arkts/cats/application/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3eb509e8fb7bbd3ca58b429959c67ea1019c9473 --- /dev/null +++ b/arkoala-arkts/cats/application/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.0", + "description": "Please describe the basic information.", + "dependencies": { + "@koalaui/arkoala-arkui": "file:../../har/app/arkoala/build/default/outputs/default/arkoala.har", + "@koalaui/user": "file:../user/app/user/build/default/outputs/default/user.har" + }, + "devDependencies": { + } +} diff --git a/arkoala-arkts/cats/package.json b/arkoala-arkts/cats/package.json new file mode 100644 index 0000000000000000000000000000000000000000..4d1f23bf0ca79056d2a1a9cc547e4dce09467ecf --- /dev/null +++ b/arkoala-arkts/cats/package.json @@ -0,0 +1,29 @@ +{ + "name": "@koalaui/application", + "version": "1.4.1", + "description": "", + "scripts": { + "clean": "rimraf application/entry/build application/generated application/oh_modules application/.hvigor && npm run clean --prefix user", + + "ets-plugin": "npm run arkoala:plugin --prefix ../..", + + "arkoala:har:arm32": "npm run arkoala:har-arm32 --prefix ../../arkoala-arkts", + "arkoala:har:arm64": "npm run arkoala:har-arm64 --prefix ../../arkoala-arkts", + "arkoala:har:universal": "npm run arkoala:har-universal --prefix ../../arkoala-arkts", + + "user:har:arm32": "npm run har-arm32 --prefix ./user", + "user:har:arm64": "npm run har-arm64 --prefix ./user", + "user:har:universal": "npm run har-universal --prefix ./user", + + "install": "cd application && DEVECO_TOOLS_HOME=../../har/command-line-tools node ../../../arkoala/ohos-sdk/scripts/cli.mjs oh-build --install-ohpm-deps-only", + "build": "cd application && DEVECO_TOOLS_HOME=../../har/command-line-tools node ../../../arkoala/ohos-sdk/scripts/cli.mjs oh-build", + "rebuild": "npm run clean && npm run build", + "sign": "cd application && DEVECO_TOOLS_HOME=../../har/command-line-tools node ../../../arkoala/ohos-sdk/scripts/cli.mjs oh-sign", + "exec": "cd application && DEVECO_TOOLS_HOME=../../har/command-line-tools node ../../../arkoala/ohos-sdk/scripts/cli.mjs oh-exec -i -r", + "launch": "npm run install && npm run build && npm run sign && npm run exec", + "relaunch": "npm run clean && npm run launch", + + "all:arm32": "npm run clean && npm run ets-plugin && npm run arkoala:har:arm32 && npm run user:har:arm32 && npm run launch", + "all:arm64": "npm run clean && npm run ets-plugin && npm run arkoala:har:arm64 && npm run user:har:arm64 && npm run launch" + } +} diff --git a/arkoala-arkts/cats/user/app/AppScope/app.json5 b/arkoala-arkts/cats/user/app/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2b158f05afee4931a92bfa3b584a0ce713466338 --- /dev/null +++ b/arkoala-arkts/cats/user/app/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.cats", + "vendor": "cats", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/arkoala-arkts/cats/user/app/build-profile.json5 b/arkoala-arkts/cats/user/app/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2ee625f46f9040da1757d80ebc950a886012849b --- /dev/null +++ b/arkoala-arkts/cats/user/app/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "user", + "srcPath": "./user" + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/cats/user/app/hvigor/hvigor-config.json5 b/arkoala-arkts/cats/user/app/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..792dd237449ebb23683ff3c9021626ddaa9d0a23 --- /dev/null +++ b/arkoala-arkts/cats/user/app/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.0", + "dependencies": { + }, + "execution": { + // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */ + } +} + diff --git a/arkoala-arkts/cats/user/app/hvigorfile.ts b/arkoala-arkts/cats/user/app/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/arkoala-arkts/cats/user/app/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/arkoala-arkts/cats/user/app/oh-package.json5 b/arkoala-arkts/cats/user/app/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..332c838bbbbb8c7f14b9487b1744f6f0aebbd16a --- /dev/null +++ b/arkoala-arkts/cats/user/app/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "modelVersion": "5.0.0", + "name": "@koalaui/user", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/arkoala-arkts/cats/user/app/user/BuildProfile.ets b/arkoala-arkts/cats/user/app/user/BuildProfile.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4 --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/BuildProfile.ets @@ -0,0 +1,17 @@ +/** + * Use these variables when you tailor your ArkTS code. They must be of the const type. + */ +export const HAR_VERSION = '1.0.0'; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; +export const TARGET_NAME = 'default'; + +/** + * BuildProfile Class is used only for compatibility purposes. + */ +export default class BuildProfile { + static readonly HAR_VERSION = HAR_VERSION; + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; + static readonly DEBUG = DEBUG; + static readonly TARGET_NAME = TARGET_NAME; +} \ No newline at end of file diff --git a/arkoala-arkts/cats/user/app/user/build-profile.json5 b/arkoala-arkts/cats/user/app/user/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d1f2f2cedd68e5a7acff8872198118eaf4d82b36 --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/build-profile.json5 @@ -0,0 +1,33 @@ +{ + "apiType": "stageMode", + "buildOption": { + "nativeLib": { + "debugSymbol": { + "strip": false + } + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + }, + "consumerFiles": [ + "./consumer-rules.txt" + ] + } + }, + }, + ], + "targets": [ + { + "name": "default" + } + ] +} diff --git a/arkoala-arkts/cats/user/app/user/hvigorfile.ts b/arkoala-arkts/cats/user/app/user/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..42187071482d292588ad40babeda74f7b8d97a23 --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/arkoala-arkts/cats/user/app/user/obfuscation-rules.txt b/arkoala-arkts/cats/user/app/user/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..985b2aeb7658286b17bd26eab8f217c3fe75ea8b --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/arkoala-arkts/cats/user/app/user/oh-package.json5 b/arkoala-arkts/cats/user/app/user/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..cda726c0e210dd98ae8eb3c653689807e6bd59e3 --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/oh-package.json5 @@ -0,0 +1,9 @@ +{ + "name": "@koalaui/user", + "version": "1.0.0", + "description": "Please describe the basic information.", + "types": "", + "author": "", + "license": "Apache-2.0", + "dependencies": {} +} diff --git a/arkoala-arkts/cats/user/app/user/src/main/module.json5 b/arkoala-arkts/cats/user/app/user/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6b0ad6685ad208707f810b65f66cbd88ff98e833 --- /dev/null +++ b/arkoala-arkts/cats/user/app/user/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "user", + "type": "har", + "deviceTypes": [ + "default", + "tablet", + "2in1" + ] + } +} diff --git a/arkoala-arkts/cats/user/arktsconfig-run-unmemoized.json b/arkoala-arkts/cats/user/arktsconfig-run-unmemoized.json new file mode 100644 index 0000000000000000000000000000000000000000..9d80f9bd0d593170a22e48518c93050ed2a37137 --- /dev/null +++ b/arkoala-arkts/cats/user/arktsconfig-run-unmemoized.json @@ -0,0 +1,46 @@ +{ + "compilerOptions": { + "package": "@koalaui/user", + "outDir": "build/abc", + "baseUrl": ".", + "paths": { + "app": [ + "./build/unmemoized/build/generated" + ], + "@koalaui/compat": [ + "../../../incremental/compat/src/arkts" + ], + "@koalaui/common": [ + "../../../incremental/common/src" + ], + "@koalaui/runtime": [ + "../../../incremental/runtime/build/unmemoized/src" + ], + "@koalaui/arkts-arkui": [ + "../../arkui/build/unmemoized/src" + ], + "@koalaui/interop": [ + "../../../interop/src/arkts" + ], + "#components": [ + "../../arkui/build/unmemoized/src/generated/arkts" + ], + "@koalaui/arkui-common": [ + "../../../arkoala/arkui-common/build/unmemoized/src", + "../../../arkoala/arkui-common/build/unmemoized/src/arkts" + ], + "#arkcompat": [ + "../../../arkoala/arkui-common/build/unmemoized/src/arkts" + ], + "#arkstate": [ + "../../../arkoala/arkui-common/build/unmemoized/src" + ], + "@koalaui/arkts-arkui/ohos.router": [ + "../../arkui/build/unmemoized/src/ohos.router.ts" + ] + } + }, + "include": [ + "./build/unmemoized/**/*.ts" + ] +} diff --git a/arkoala-arkts/cats/user/package.json b/arkoala-arkts/cats/user/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c861714d6070a92e6caed833fceec651480249a2 --- /dev/null +++ b/arkoala-arkts/cats/user/package.json @@ -0,0 +1,29 @@ +{ + "name": "@koalaui/arkts-framework", + "version": "1.4.1", + "description": "", + "scripts": { + "clean": "rimraf build generated unmemoized js_output abc lib app/user/build app/user/libs app/.hvigor .ninja_log", + "distclean": "rimraf command-line-tools", + "compile:plugin": "cd ../../../arkoala/ets-plugin && npm run compile", + "compile:ets": "npm run compile:plugin && cd src/ets && ets-tsc -p ./etsconfig.json", + "unmemoize": "npm run compile:ets && ets-tsc -p tsconfig-unmemoize.json", + "unmemoize:runtime": "npm run unmemoize --prefix ../../../incremental/runtime", + "unmemoize:arkui-no-common": "npm run unmemoize --prefix ../../arkui", + "unmemoize:arkui-common": "npm run unmemoize --prefix ../../../arkoala/arkui-common", + "unmemoize:all": "npm run unmemoize:runtime && npm run unmemoize:arkui-no-common && npm run unmemoize:arkui-common && npm run unmemoize", + "build:user": "npm run unmemoize:all && npm run build:user:inc", + "build:user:inc": "fast-arktsc --input-files ./arktsconfig-run-unmemoized.json --output-dir ./build --compiler ../../../incremental/tools/panda/arkts/arktsc --link-name user && ninja -f build/build.ninja", + + "pack": "npm run cli-tools:check && cd app && DEVECO_SDK_HOME=../../../../arkoala/ohos-sdk/ohos-sdk ../../../command-line-tools/hvigor/bin/hvigorw --no-daemon --mode module -p product=default -p module=user@default assembleHar", + "har-arm32": "npm run build:user && npm run --prefix ../../../arkoala/ohos-sdk download && node scripts/build-har.mjs --name user --arch arm32 && npm run pack", + "har-arm64": "npm run build:user && npm run --prefix ../../../arkoala/ohos-sdk download && node scripts/build-har.mjs --name user --arch arm64 && npm run pack", + + "cli-tools:chmod:bz": "node ../../../arkoala/ohos-sdk/scripts/openlab-cli.mjs chmod -p ../../command-line-tools/ohpm/bin -b 755 && node ../../../arkoala/ohos-sdk/scripts/openlab-cli.mjs chmod -p ../../command-line-tools/hvigor/bin -b 755", + "cli-tools:chmod:yz": "node ../../../arkoala/ohos-sdk/scripts/gitlab-cli.mjs chmod -p ../../command-line-tools/ohpm/bin -b 755 && node ../../../arkoala/ohos-sdk/scripts/gitlab-cli.mjs chmod -p ../../command-line-tools/hvigor/bin -b 755", + "cli-tools:download:bz": "node ../../../arkoala/ohos-sdk/scripts/openlab-cli.mjs download -p command-line-tools -v 5.0.3502 -f command-line-tools.5.0.3502.zip -d ../../command-line-tools && npm run cli-tools:chmod:bz", + "cli-tools:download:yz": "node ../../../arkoala/ohos-sdk/scripts/gitlab-cli.mjs download -p deveco-tools -v 5.0.1300 -f deveco-tools.5.0.1300.zip -d ../../command-line-tools && npm run cli-tools:chmod:yz", + "cli-tools:download": "test \"$KOALA_BZ\" = \"0\" && npm run cli-tools:download:yz || npm run cli-tools:download:bz", + "cli-tools:check": "test -d ../../command-line-tools || npm run cli-tools:download" + } +} diff --git a/arkoala-arkts/cats/user/scripts/build-har.mjs b/arkoala-arkts/cats/user/scripts/build-har.mjs new file mode 100644 index 0000000000000000000000000000000000000000..48495614178f516e8eccb210b7eb568c32784fa6 --- /dev/null +++ b/arkoala-arkts/cats/user/scripts/build-har.mjs @@ -0,0 +1,49 @@ +import { execSync } from "child_process" +import { dirname } from "path" +import { fileURLToPath } from "url" + +import fs from "fs" +import path from "path" +import process from "process" +import minimist from "minimist" + +var args = minimist(process.argv.slice(2)) +const arch = args["arch"] +const name = args["name"] + +const _dirname = dirname(fileURLToPath(import.meta.url)) + +const CWD = process.cwd() +const HAR_PATH = path.join(CWD, `app/${name}`) + +function execCmdSync(cmd, options) { + return execSync(cmd, options).toString().trim().replace("\n", " ") +} + +function rollupLaunch() { + console.log(`> Run rollup`) + execCmdSync("npx rollup -c") +} + +function copyFilesToHar(from, to) { + if (!fs.existsSync(from)) { + throw new Error(`file ${from} does not exist`) + } + + console.log(`> Copy from: ${from} to ${to}`) + fs.cpSync(from, to, { recursive: true, force: true }) +} + + +function main(targetLibDir, name) { + copyFilesToHar(path.join(_dirname, `../build/${name}.abc`), path.join(HAR_PATH, `libs/${targetLibDir}/${name}.abc.so`)) +} + +if (arch == "arm32") { + main("armeabi-v7a", name) +} else if (arch == "arm64") { + main("arm64-v8a", name) +} else { + console.log("Unsupported architecture: ", arch) + exit(1) +} diff --git a/arkoala-arkts/cats/user/src/Page.ts b/arkoala-arkts/cats/user/src/Page.ts new file mode 100644 index 0000000000000000000000000000000000000000..b3cc192790126740469a7a4f09a7ea29f004ed92 --- /dev/null +++ b/arkoala-arkts/cats/user/src/Page.ts @@ -0,0 +1,17 @@ +import { Index } from "app/Index" +import { UserView, UserViewBuilder } from "@koalaui/arkts-arkui" + +export class ComExampleCats extends UserView { + private params: String + constructor(params: String) { + super() + this.params = params + } + getBuilder(): UserViewBuilder { + /** @memo */ + let wrapper = () => { + Index() + } + return wrapper + } +} diff --git a/arkoala-arkts/cats/user/src/ets/Index.ets b/arkoala-arkts/cats/user/src/ets/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8001ddb38ba60a820f1df3c56c13035ff6543c64 --- /dev/null +++ b/arkoala-arkts/cats/user/src/ets/Index.ets @@ -0,0 +1,107 @@ +import router from '@ohos.router' + +type T = [ ResourceColor, number ] + +@Entry +@Component +struct Index { + build() { + Column() { + Question({ + question: "Help!", + answer: "Don't panic!", + color: 0xf13428 + }) + Question({ + question: "I'm tired...", + answer: "Have some rest!", + color: 0x7bf128 + }) + Question({ + question: "Support me!", + answer: "We are proud of you!", + color: 0x28a6f1 + }) + // Button("Click me") + // .onClick(() => { + // console.log("On click") + // }) + // // .onHover((isHover) => this.isActive = isHover ?? false) + // // .radialGradient({ center: ["50%", "50%"], radius: "20%", colors: [[this.color, 0.0], ['#909090', 0.25], [this.color, 0.5]], repeating: true }) + // .fontColor(Color.Black) + // .fontWeight(FontWeight.Bold) + // .fontSize(30) + // .width(250) + // .height(250) + } + .width('100%') + .height('100%') + .backgroundColor(0xcedada) + .justifyContent(FlexAlign.SpaceEvenly) + } + + pageTransition() { + PageTransitionEnter({ duration: 1000, curve : Curve.EaseIn }) + .opacity(1) + .slide(SlideEffect.Left) + PageTransitionExit({ duration: 1000, curve : Curve.EaseOut }) + .slide(SlideEffect.Left) + // .scale({x: 0.5, y: 0.5} as ScaleOptions) + .opacity(0) + // .onEnter((type: RouteType, progress: number) => { + // console.log("Progress", progress) + // }) + } +} + +@Component +struct Question { + @Prop question: string + @Prop color: number + @Prop answer: string + @State isActive: boolean = false + + build() { + let radial:T[] = [[this.color, 0.0], ['#909090', 0.25], [this.color, 0.5]] + + Button(this.question) + .onClick((event: ClickEvent) => { + router.pushUrl({ + url: "SomeCat", + params: new RouterParams(this.answer) + }) + }) + .onHover((isHover:boolean, event: HoverEvent) => { + this.isActive = isHover + }) + .radialGradient({ center: ["50%", "50%"], + radius: "25%", + colors: Array.from(radial), + repeating: true + } as Type_CommonMethod_radialGradient_value) + .fontColor(Color.Black) + .fontWeight(this.isActive ? FontWeight.Bold : FontWeight.Normal) + .fontSize(this.isActive ? 30 : 24) + .width(this.isActive ? 250 : 210) + .height(this.isActive ? 250 : 210) + // .animation({ + // duration: 2000, + // curve: Curve.EaseOut, + // playMode: PlayMode.Normal + // }) + } +} + +export class RouterParams { + readonly message: string + + constructor(message: string) { + this.message = message + } +} + +export function getRouterParams(defaultMessage: string): RouterParams { + const params = router.getParams() + return params ? params as RouterParams : new RouterParams(defaultMessage) +} + diff --git a/arkoala-arkts/cats/user/src/ets/SomeCat.ets b/arkoala-arkts/cats/user/src/ets/SomeCat.ets new file mode 100644 index 0000000000000000000000000000000000000000..daeb3878fe45fc1a1ea9a762b015d93c0568e12d --- /dev/null +++ b/arkoala-arkts/cats/user/src/ets/SomeCat.ets @@ -0,0 +1,88 @@ +import router from '@ohos.router' +import { getRouterParams } from './Index' + +// function catUrl(counter: number): string { +// return `https://cataas.com/cat?counter=${counter}` +// // return `http://localhost:8080/cats?counter=${counter}` +// } + +@Entry +@Component +struct SomeCat { + @State message: string = getRouterParams("Meow").message + // @State loading: boolean = false + @State error: string = "" + + counter:number = 0 + + aboutToAppear() { + this.counter = Math.random() + // this.loading = true + this.error = "" + } + + build() { + Stack() { + // if (this.loading) { + // LoadingProgress() + // .color(Color.Blue) + // .width('20%') + // .height('20%') + // .align(Alignment.Center) + // } + if (this.error. length > 0) { + Text("Error: " + this.error) + .fontColor('#ff0000') + .fontSize(30) + } + // Image(catUrl(this.counter)) + Image("/resources/koala.png") + // .onFinish(() => { + // this.loading = false + // }) + .objectFit(ImageFit.Cover) + .onError((e: ImageError) => { + // this.loading = false + this.error = this.error.length > 0 ? this.error : (e?.message ?? "Unknown") + console.log("Image onError", e?.message) + }) + .onClick((event: ClickEvent) => { + console.log("%%%%%%% Cat click back %%%%%%%%") + router.back() + }) + .height('100%') + .width('100%') + Text(this.message) + .fontColor(Color.White) + .fontSize(30) + .fontWeight(FontWeight.Bold) + .offset({y: 300} as Position) + .borderWidth(3) + .borderColor('#404040') + .backgroundColor('#202020') + .padding(7) + .borderRadius(5) + } + .width('100%') + .height('100%') + .backgroundColor(0xcedada) + .alignContent(Alignment.Center) + } + + pageTransition() { + PageTransitionEnter({ duration: 1000, curve : Curve.EaseIn }) + .opacity(1) + .slide(SlideEffect.Right) + .onEnter((type: RouteType, progress: number) => { + console.log("Cat on enter: ", progress) + }) + + PageTransitionExit({ duration: 1000, curve : Curve.EaseOut }) + .slide(SlideEffect.Right) + // .scale({x: 0.5, y: 0.5} as ScaleOptions) + .opacity(0) + .onExit((type: RouteType, progress: number) => { + console.log("Cat on exit: ", progress) + }) + } +} \ No newline at end of file diff --git a/arkoala-arkts/cats/user/src/ets/etsconfig.json b/arkoala-arkts/cats/user/src/ets/etsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..1c10b08df0c131615f2f1afa7ac8ef5aa604ad4a --- /dev/null +++ b/arkoala-arkts/cats/user/src/ets/etsconfig.json @@ -0,0 +1,29 @@ +{ + "extends": "../../../../arkui/config/etsconfig-base.json", + "include": [ + "./**/*.ets" + ], + "compilerOptions": { + "types": [], + "baseUrl": ".", + "rootDirs": [ + "." + ], + "outDir": "../../build/ets-junk", + "plugins": [ + { + "transform": "@koalaui/ets-plugin/build/lib/src/ArkExpander.js", + "destination": "../../build/generated", + "arkui": "@koalaui/arkts-arkui" + } + ], + "paths": { + "@ohos.*": [ + "../../../../../arkoala/arkui-common/interface_sdk-js/api/@ohos.*" + ], + "@system.*": [ + "../../../../../arkoala/arkui-common/interface_sdk-js/api/@system.*" + ] + } + } +} diff --git a/arkoala-arkts/cats/user/tsconfig-unmemoize.json b/arkoala-arkts/cats/user/tsconfig-unmemoize.json new file mode 100644 index 0000000000000000000000000000000000000000..e214e4c24d523e9dd489d971723bf0e7e87f8b0f --- /dev/null +++ b/arkoala-arkts/cats/user/tsconfig-unmemoize.json @@ -0,0 +1,55 @@ +{ + "extends": "@koalaui/build-common/tsconfig.json", + "compilerOptions": { + "types": [], + "plugins": [ + { + "transform": "@koalaui/compiler-plugin/build/lib/src/koala-transformer.js", + "trace": false, + "only_unmemoize": true, + "unmemoizeDir": "./build/unmemoized" + } + ], + "outDir": "./build/junk", + "baseUrl": ".", + "paths": { + "@koalaui/arkui-common": [ + "../../../arkoala/arkui-common/src/arkts" + ], + "@koalaui/runtime": [ + "../../../incremental/runtime" + ], + "#arkcompat": [ + "../../../arkoala/arkui-common/src/arkts" + ], + "@koalaui/arkts-arkui": [ + "../../arkui/src" + ], + "@koalaui/arkts-arkui/ohos.router": [ + "../../arkui/src/ohos.router.ts" + ], + "app/*": [ + "./build/generated/*" + ] + } + }, + "files": [ + "../../../incremental/tools/panda/arkts/std-lib/global.d.ts" + ], + "include": [ + "./build/generated", + "./src/**/*.ts" + ], + "exclude": [ + "../../arkui/src/generated/arkts", + "../../arkui/src/generated/common.ts", + "../../arkui/src/generated/test_utils.ts", + "../../arkui/src/generated/main.ts" + ], + "references": [ + { "path": "../../../arkoala/arkui-common" }, + { "path": "../../../arkoala/arkui-common/tsconfig-unmemoize.json" }, + { "path": "../../../incremental/runtime" }, + { "path": "../../arkui/tsconfig-unmemoize.json" } + ] +} diff --git a/arkoala-arkts/navigation/application/AppScope/resources/base/element/string.json b/arkoala-arkts/navigation/application/AppScope/resources/base/element/string.json index ea81d75010c3f23eb68b489e90527f8cba9450b6..a21f8ded814c4e90f74c7b6092ef26c67d04d024 100644 --- a/arkoala-arkts/navigation/application/AppScope/resources/base/element/string.json +++ b/arkoala-arkts/navigation/application/AppScope/resources/base/element/string.json @@ -2,7 +2,7 @@ "string": [ { "name": "app_name", - "value": "ShoppingApplication" + "value": "NavigationApplication" } ] } diff --git a/arkoala-arkts/navigation/application/oh-package-lock.json5 b/arkoala-arkts/navigation/application/oh-package-lock.json5 index 28784df1cda4b2b041e604870cb8b0e626361b1d..c515a170a788b4e15a0f13cd39e020a0ec945ede 100644 --- a/arkoala-arkts/navigation/application/oh-package-lock.json5 +++ b/arkoala-arkts/navigation/application/oh-package-lock.json5 @@ -6,7 +6,7 @@ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", "specifiers": { "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har": "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har", - "@koalaui/shopping@../../shopping/app/shopping/build/default/outputs/default/shopping.har": "@koalaui/shopping@../../shopping/app/shopping/build/default/outputs/default/shopping.har" + "@koalaui/user@../user/app/user/build/default/outputs/default/user.har": "@koalaui/user@../user/app/user/build/default/outputs/default/user.har" }, "packages": { "@koalaui/arkoala-arkui@../../har/app/arkoala/build/default/outputs/default/arkoala.har": { @@ -15,10 +15,10 @@ "resolved": "../../har/app/arkoala/build/default/outputs/default/arkoala.har", "registryType": "local" }, - "@koalaui/shopping@../../shopping/app/shopping/build/default/outputs/default/shopping.har": { - "name": "@koalaui/shopping", + "@koalaui/user@../user/app/user/build/default/outputs/default/user.har": { + "name": "@koalaui/user", "version": "1.0.0", - "resolved": "../../shopping/app/shopping/build/default/outputs/default/shopping.har", + "resolved": "../user/app/user/build/default/outputs/default/user.har", "registryType": "local" } } diff --git a/arkoala-arkts/navigation/package.json b/arkoala-arkts/navigation/package.json index 2f79c0ee44be4f5a3d43b517cdc3bfca6ef1eeb0..fbdb0199871b7f0427a4d51533ce47dade8efde1 100644 --- a/arkoala-arkts/navigation/package.json +++ b/arkoala-arkts/navigation/package.json @@ -7,7 +7,7 @@ "clean:user": "npm run clean --prefix ./user", "clean:all": "npm run clean && npm run clean:user", - "ets-plugin": "npm run arkoala:plugin --prefix ../../..", + "ets-plugin": "npm run arkoala:plugin --prefix ../..", "arkoala:har:arm32": "npm run arkoala:har-arm32 --prefix ../../arkoala-arkts", "arkoala:har:arm64": "npm run arkoala:har-arm64 --prefix ../../arkoala-arkts", diff --git a/arkoala/arkui-common/src/typescript/ArkPageTransition.ts b/arkoala/arkui-common/src/typescript/ArkPageTransition.ts deleted file mode 100644 index 785a42b153992849afd85be9dbb64c034c94ebb6..0000000000000000000000000000000000000000 --- a/arkoala/arkui-common/src/typescript/ArkPageTransition.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2022-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 { ArkRouteType } from "./ArkRouteType" - -export interface ArkPageTransitionParams { - kind: ArkRouteType - duration: number - curve: Curve | string - delay: number -} - -export class ArkPageTransitionData { - params: Partial - _onEnter?: (type: ArkRouteType, progress: number) => void - _onExit?: (type: ArkRouteType, progress: number) => void - _slide?: SlideEffect - _translate?: { x?: string | number | undefined; y?: string | number | undefined; z?: string | number | undefined; } - _scale?: { x?: number | undefined; y?: number | undefined; z?: number | undefined; centerX?: string | number | undefined; centerY?: string | number | undefined; } - _opacity?: number - - constructor(params: Partial) { - this.params = params - } - onEnter(event: (type: ArkRouteType, progress: number) => void): this { - this._onEnter = event - return this - } - onExit(event: (type: ArkRouteType, progress: number) => void): this { - this._onExit = event - return this - } - slide(value: SlideEffect): this { - this._slide = value - return this - } - translate(value: { x?: string | number | undefined; y?: string | number | undefined; z?: string | number | undefined; }): this { - this._translate = value - return this - } - scale(value: { x?: number | undefined; y?: number | undefined; z?: number | undefined; centerX?: string | number | undefined; centerY?: string | number | undefined; }): this { - this._scale = value - return this - } - opacity(value: number): this { - this._opacity = value - return this - } -} - -export class ArkPageTransitionEnterComponent extends ArkPageTransitionData /* implements PageTransitionEnterInterface */ { - constructor(params: Partial) { - super(params) - } -} - -export class ArkPageTransitionExitComponent extends ArkPageTransitionData /* implements PageTransitionExitInterface */ { - constructor(params: Partial) { - super(params) - } -} diff --git a/arkoala/arkui-common/src/typescript/ArkRouteType.ts b/arkoala/arkui-common/src/typescript/ArkRouteType.ts deleted file mode 100644 index cfe20ce7b1feacdd62ef5f44d6fe05bd45df765d..0000000000000000000000000000000000000000 --- a/arkoala/arkui-common/src/typescript/ArkRouteType.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum ArkRouteType { - NONE = 0, - None = 0, - PUSH = 1, - Push = 1, - POP = 2, - Pop = 2, -} diff --git a/arkoala/arkui-common/src/typescript/Router.ts b/arkoala/arkui-common/src/typescript/Router.ts index 40089158a94ccdae77373c824079f12ddc7e0b74..1a5dfca77c9facab5e719be2c74cd5d4130b2c63 100644 --- a/arkoala/arkui-common/src/typescript/Router.ts +++ b/arkoala/arkui-common/src/typescript/Router.ts @@ -14,7 +14,7 @@ */ -import { int32, observableProxyArray } from "@koalaui/common" +import { int32 } from "@koalaui/common" import { MutableState, RunEffect, @@ -23,8 +23,9 @@ import { mutableState, remember, RepeatByArray, + arrayState, + scheduleCallback, } from "@koalaui/runtime" -import { ArkRouteType } from "./ArkRouteType" export enum RouterTransitionVisibility { Hidden, @@ -33,14 +34,23 @@ export enum RouterTransitionVisibility { Hiding, } +enum RouteType { + NONE, + None = NONE, + PUSH = 1, + Push = PUSH, + POP = 2, + Pop = POP, +} + export type MemoFunction = /** @memo */ () => void export interface RouterTransitionState { - readonly pageId: int32 readonly visibility: RouterTransitionVisibility - readonly route?: ArkRouteType + readonly pageId: int32 + readonly route?: RouteType } class VisiblePage { @@ -53,14 +63,14 @@ class VisiblePage { page: MemoFunction, version: number, visibility: RouterTransitionVisibility, - route?: ArkRouteType + route?: RouteType ) { this.page = page this.version = version this.transitionState = mutableState({ pageId: version, visibility, route }) } - setTransitionState(visibility: RouterTransitionVisibility, route?: ArkRouteType) { + setTransitionState(visibility: RouterTransitionVisibility, route?: RouteType) { this.transitionState.value = { pageId: this.version, visibility, route } } @@ -70,7 +80,7 @@ class VisiblePage { } class RouterState { - readonly visiblePages = observableProxyArray() + readonly visiblePages = arrayState() currentActivePage = mutableState(0) constructor( page: MemoFunction, @@ -120,6 +130,8 @@ export class PageInfo { constructor(public depth: number, public page: string) { } } +export type PageTransition = () => void + /** * Interface providing page routing functionality. */ @@ -196,7 +208,8 @@ export interface Router { */ pageInfo: PageInfo - onPageTransitionEnd(pageId: int32): void + onPageTransitionEnd(pageId: int32, targetVisibility: RouterTransitionVisibility): void + schedulePageTransition(pageId: int32, transition: PageTransition): void } const CURRENT_ROUTER = "ohos.arkoala.router" @@ -235,7 +248,7 @@ class RouterImpl implements Router { if (push) { this.stack.push(new RouterStackEntry(this.state.url, this.state.page, this.state.params)) } - this.activate(entry, push ? ArkRouteType.PUSH : ArkRouteType.NONE, params, resolve) + this.activate(entry, push ? RouteType.Push : RouteType.None, params, resolve) } else { if (this.resolver) { return this @@ -244,7 +257,7 @@ class RouterImpl implements Router { if (push) { this.stack.push(new RouterStackEntry(this.state.url, this.state.page, this.state.params)) } - this.activate(new RouterRegistryEntry(url, page), push ? ArkRouteType.PUSH : ArkRouteType.NONE, params, resolve) + this.activate(new RouterRegistryEntry(url, page), push ? RouteType.Push : RouteType.None, params, resolve) }) .catch(error => reject(error)) } @@ -257,12 +270,12 @@ class RouterImpl implements Router { showingPage: number = -1 hidingPage: number = -1 - private activate(entry: RouterRegistryEntry, route: ArkRouteType, params: Map | undefined, resolve: () => void) { + private activate(entry: RouterRegistryEntry, route: RouteType, params: Map | undefined, resolve: () => void) { const state = this.state state.version.value++ - console.log("activating", ArkRouteType[route], entry.url, "version", state.version.value) + console.log("activating", RouteType[route], entry.url, "version", state.version.value) let previousVisiblePageIndex = this.findIndexByVersion(state.currentActivePage.value) - let previousVisiblePage = state.visiblePages[previousVisiblePageIndex] + let previousVisiblePage = state.visiblePages.value[previousVisiblePageIndex] if (previousVisiblePage) previousVisiblePage.setTransitionState(RouterTransitionVisibility.Hiding, route) state.page = entry.page state.url = entry.url @@ -270,26 +283,26 @@ class RouterImpl implements Router { state.resolve = resolve let newVisiblePage: VisiblePage switch (route) { - case ArkRouteType.PUSH: { + case RouteType.Push: { newVisiblePage = new VisiblePage(entry.page, state.version.value, RouterTransitionVisibility.Showing, route) state.visiblePages.splice(previousVisiblePageIndex + 1, 0, newVisiblePage) break } - case ArkRouteType.POP: { + case RouteType.Pop: { const index = this.stack.length // TODO: store uid in registry to find a page - newVisiblePage = state.visiblePages[index] + newVisiblePage = state.visiblePages.value[index] newVisiblePage.setTransitionState(RouterTransitionVisibility.Showing, route) // remove all hidden pages removed from the stack for (let i = state.visiblePages.length - 1; i > index; i--) { - const visibility = state.visiblePages[i].transition.visibility - if (visibility == RouterTransitionVisibility.Hidden) state.visiblePages.splice(i) + const visibility = state.visiblePages.value[i].transition.visibility + if (visibility == RouterTransitionVisibility.Hidden) state.visiblePages.splice(i, undefined) } break } - case ArkRouteType.NONE: { + case RouteType.None: { // TODO: can/shall we animate replace? newVisiblePage = new VisiblePage(entry.page, state.version.value, RouterTransitionVisibility.Showing, route) - state.visiblePages[previousVisiblePageIndex] = newVisiblePage + state.visiblePages.set(previousVisiblePageIndex, newVisiblePage) break } default: @@ -304,33 +317,64 @@ class RouterImpl implements Router { const array = this.state.visiblePages const length = array.length for (let i = 0; i < length; i++) { - if (array[i].version == version) return i + if (array.value[i].version == version) return i } return -1 } - onPageTransitionEnd(pageId: int32): void { + private pageTransitionMap = new Map>() + + schedulePageTransition(pageId: int32, transition: PageTransition): void { + let queuedTransitions = this.pageTransitionMap.get(pageId) + if (queuedTransitions === undefined) { + queuedTransitions = [] + this.pageTransitionMap.set(pageId, queuedTransitions) + } + + const length = queuedTransitions.length + queuedTransitions.splice(length, 0, transition) + + if (length == 0) { + scheduleCallback(transition) + } + } + + onPageTransitionEnd(pageId: int32, targetVisibility: RouterTransitionVisibility): void { const index = this.findIndexByVersion(pageId) - if (index < 0) return - const page = this.state.visiblePages[index] - if (page.transition.visibility == RouterTransitionVisibility.Showing) { - if (pageId == this.state.currentActivePage.value) { - console.log("PAGE VISIBLE:", page.transition.pageId) - page.setTransitionState(RouterTransitionVisibility.Visible) - } else { - console.log("ERROR: showing page cannot be shown:", page.transition.route ? ArkRouteType[page.transition.route] : "unknown") - page.setTransitionState(RouterTransitionVisibility.Hidden) + if (index >= 0) { + const page = this.state.visiblePages.value[index] + if (page.transition.visibility == targetVisibility) { + if (page.transition.visibility == RouterTransitionVisibility.Showing) { + if (pageId == this.state.currentActivePage.value) { + page.setTransitionState(RouterTransitionVisibility.Visible) + } else { + console.log("ERROR: showing page cannot be shown:", page.transition.route ? RouteType[page.transition.route] : "unknown") + page.setTransitionState(RouterTransitionVisibility.Hidden) + } + } else if (page.transition.visibility == RouterTransitionVisibility.Hiding) { + if (index < this.stack.length) { + console.log("PAGE HIDDEN:", page.transition.pageId) + page.setTransitionState(RouterTransitionVisibility.Hidden) + } else { + this.state.visiblePages.splice(index, 1) + console.log("PAGE REMOVED:", page.transition.pageId) + } + } else { + console.log("ERROR: no page transition:", pageId, RouterTransitionVisibility[page.transition.visibility], page.transition.route ? RouteType[page.transition.route] : "unknown") + } + } // Otherwise ignore transition because it has been updated during this animation period + } + + let queuedTransitions = this.pageTransitionMap.get(pageId) + if (queuedTransitions && queuedTransitions.length > 0) { + queuedTransitions.splice(0, 1) // Remove current transition + if (queuedTransitions.length == 0) { + this.pageTransitionMap.delete(pageId) } - } else if (page.transition.visibility == RouterTransitionVisibility.Hiding) { - if (index < this.stack.length) { - console.log("PAGE HIDDEN:", page.transition.pageId) - page.setTransitionState(RouterTransitionVisibility.Hidden) - } else { - console.log("PAGE REMOVED:", page.transition.pageId) - this.state.visiblePages.splice(index, 1) + + if (queuedTransitions.length > 0) { + scheduleCallback(queuedTransitions[0]) } - } else { - console.log("ERROR: no page transition:", RouterTransitionVisibility[page.transition.visibility], page.transition.route ? ArkRouteType[page.transition.route] : "unknown") } } @@ -358,7 +402,7 @@ class RouterImpl implements Router { entry = this.stack.length > 0 ? this.stack.pop() : undefined } if (entry) { - this.activate(entry, ArkRouteType.POP, params ?? entry.params, resolve) + this.activate(entry, RouteType.Pop, params ?? entry.params, resolve) } else { reject(`history is empty`) } @@ -393,7 +437,7 @@ export function Routed( /** @memo */ () => { RepeatByArray( - routerState.visiblePages, + routerState.visiblePages.value, (page) => page.version, (page: VisiblePage) => { WithRouterTransitionState(page.transition, () => { diff --git a/arkoala/arkui-common/src/typescript/index.ts b/arkoala/arkui-common/src/typescript/index.ts index b448e82e19fd1350aaebec87f307cbabb0387c49..16aa01b6c39a05713b6392b4a3d1c8b84667e3f2 100644 --- a/arkoala/arkui-common/src/typescript/index.ts +++ b/arkoala/arkui-common/src/typescript/index.ts @@ -13,8 +13,6 @@ * limitations under the License. */ -export * from "./ArkPageTransition" -export * from "./ArkRouteType" export * from "./Storage" export * from "./Router" diff --git a/arkoala/arkui/src/ArkStructCommon.ts b/arkoala/arkui/src/ArkStructCommon.ts index 022ca9a66dcf0a3db1afc1bb8c2de0c25659b3df..b4d55c37ef33be22ee7f1408ebaf972e886b76d5 100644 --- a/arkoala/arkui/src/ArkStructCommon.ts +++ b/arkoala/arkui/src/ArkStructCommon.ts @@ -17,6 +17,7 @@ import { remember } from "@koalaui/runtime" import { CustomComponentImpl } from "./CustomComponent"; import { ArkComponentRoot } from "./ArkComponentRoot"; import { ArkCommonMethodComponent } from "./generated/ArkCommon"; +import { ArkPageTransitionEnter, ArkPageTransitionExit } from "./handwritten/ArkPageTransition"; /** base class for user's structs */ export abstract class ArkStructBase extends CustomComponentImpl { @@ -73,7 +74,8 @@ export abstract class ArkStructBase extends CustomComponentImpl { ): void /** @memo */ - pageTransition?(): void { - + pageTransition(): void { + ArkPageTransitionEnter(undefined, undefined, { duration: 100 }) + ArkPageTransitionExit(undefined, undefined, { duration: 100 }) } } diff --git a/arkoala/arkui/src/handwritten/ArkPageTransition.ts b/arkoala/arkui/src/handwritten/ArkPageTransition.ts index 7b3adec0c3a614fad74f22a3c12eac55411d699c..cc045abac8380969138f991e310ef3381765d0a5 100644 --- a/arkoala/arkui/src/handwritten/ArkPageTransition.ts +++ b/arkoala/arkui/src/handwritten/ArkPageTransition.ts @@ -13,58 +13,277 @@ * limitations under the License. */ +import { ArkUINativeModule, PeerNode, PeerNodeType } from "@koalaui/arkoala" +import { CurrentRouter, CurrentRouterTransitionState, Router, RouterTransitionVisibility } from "@koalaui/arkui-common" +import { int32 } from "@koalaui/common" +import { remember, contextNode } from "@koalaui/runtime" +import { ArkCommonMethodPeer } from "../generated/peers/ArkCommonPeer" +import { ArkComponentRootPeer } from "../generated/peers/ArkStaticComponentsPeer" +import { TranslateOptions, ScaleOptions } from "../generated/ArkCommonInterfaces" +import { PageTransitionOptions, SlideEffect, RouteType } from "../generated/ArkPageTransitionInterfaces" +import { AnimationExtender } from "../generated/ArkAnimationExtenderMaterialized" -// WARNING! THIS FILE IS AUTO-GENERATED, DO NOT MAKE CHANGES, THEY WILL BE LOST ON NEXT GENERATION! +const NO_SCALE:ScaleOptions = { x: 1.0, y: 1.0, z: 1.0, centerX: "50%", centerY: "50%" } +const ZERO_TRANSLATE:TranslateOptions = { x: 0.0, y: 0.0, z:0.0 } +const KEY_PAGE_TRANSITION_PROPERTY = "pageTransitionProperty" // See frameworks/core/components_ng/pattern/stage/page_pattern.cpp -import { ComponentBase } from "../ComponentBase" +function sizeNotEmpty(size: SizeOptions): boolean { + const w = (size?.width as number) ?? 0 + const h = (size?.height as number) ?? 0 + return w > 0 && h > 0 +} -/** @memo:stable */ -export class ArkCommonTransitionComponent extends ComponentBase { - // getPeer(): ArkCommonTransitionPeer { - // return (this.peer as ArkCommonTransitionPeer) - // } - /** @memo */ +function getNodeSize(ptr: PeerNode): SizeOptions { + return { width: ArkUINativeModule._GetMeasureWidth(ptr.getPeerPtr()), + height: ArkUINativeModule._GetMeasureHeight(ptr.getPeerPtr())} +} + +// see rosen_render_context.cpp:SlideTransitionEffect in ace_engine +function slideTransition(size: SizeOptions, value: SlideEffect) : TranslateOptions { + if (sizeNotEmpty(size)) { + let xOffset = 0 + let yOffset = 0 + switch (value) { + case SlideEffect.Left: + xOffset = -(size.width as number) + break + case SlideEffect.Right: + xOffset = size.width as number + break + case SlideEffect.Top: + yOffset = -(size.height as number) + break + case SlideEffect.Bottom: + yOffset = size.height as number + break + case SlideEffect.START: + xOffset = -(size.width as number) // TODO: support RTL applications with x = width + break + case SlideEffect.END: + xOffset = size.width as number // TODO: support RTL applications with x = -width + break + } + + return { x: xOffset, y: yOffset, z: 0 } + } else { + throw Error("Size is empty of has undefined components") + } +} + +function progressAnimation(state: RouterTransitionVisibility, style: ArkPageTransitionData): DoubleAnimationParam | undefined { + if (state == RouterTransitionVisibility.Hiding && style._onExit != undefined || + state == RouterTransitionVisibility.Showing && style._onEnter != undefined) + { + return { + propertyName: KEY_PAGE_TRANSITION_PROPERTY, + startValue: 0, + endValue: 1.0, + duration: style.params.duration ?? 0, + delay: style.params.delay ?? 0, + curve: style.params.curve as Curve, + onProgress: (state == RouterTransitionVisibility.Hiding && style._onExit != undefined) ? + progress => style._onExit?.(RouteType.Pop, progress) : + progress => style._onEnter?.(RouteType.Push, progress), + + onFinish: () => {} + } + } else { + return undefined + } +} + +function findContainerNode(node: PeerNode): ArkCommonMethodPeer | undefined { + for (let child = node.firstChild; child; child = child.nextSibling) { + if (child.isKind(PeerNodeType)) return child as ArkCommonMethodPeer + } + return undefined +} + +function launchTransitionForSize(node: ArkCommonMethodPeer, router: Router | undefined, size: SizeOptions, + pageId: int32, style: ArkPageTransitionData, state: RouterTransitionVisibility) { + router?.schedulePageTransition(pageId, () => { + // console.log("#### Page transition animation: pageID =", pageId, " duration =", style.params.duration, + // " curve = ", style.params.curve === undefined || (typeof style.params.curve === "string") ? style.params.curve : Curve[style.params.curve], + // " delay = ", style.params.delay, + // " state = ", RouterTransitionVisibility[state], + // " opacity = ", style._opacity, + // " slide = ", style._slide !== undefined ? SlideEffect[style._slide] : "undefined", + // " scale = ", style._scale, + // " translate = ", style._translate) + + if (style._opacity !== undefined) { + if (state == RouterTransitionVisibility.Hiding) { + node.opacityAttribute(1.0) + } else if (state == RouterTransitionVisibility.Showing) { + node.opacityAttribute(style._opacity) + } + } + + if (style._slide !== undefined || style._translate !== undefined || style._scale !== undefined) { + if (state == RouterTransitionVisibility.Hiding) { + node.scaleAttribute(NO_SCALE) + AnimationExtender.AnimationTranslate(node.getPeerPtr(), ZERO_TRANSLATE) + } else if (state == RouterTransitionVisibility.Showing) { + if (style._scale !== undefined) { + node.scaleAttribute(style._scale) + } + + if (style._slide !== undefined) { + const translate = slideTransition(size, style._slide) + AnimationExtender.AnimationTranslate(node.getPeerPtr(), translate) + } else if (style._translate !== undefined) { + AnimationExtender.AnimationTranslate(node.getPeerPtr(), style._translate) + } + } + } + + AnimationExtender.SetClipRect(node.getPeerPtr(), 0, 0, 10000, 10000) + + AnimationExtender.OpenImplicitAnimation({ + duration: style.params.duration, + curve:style.params.curve, + delay: style.params.delay, + onFinish: () => router?.onPageTransitionEnd(pageId, state) + }) + + if (style._opacity !== undefined) { + if (state == RouterTransitionVisibility.Hiding) { + node.opacityAttribute(style._opacity) + } else if (state == RouterTransitionVisibility.Showing) { + node.opacityAttribute(1.0) + } + } + + if (style._slide !== undefined || style._translate !== undefined || style._scale !== undefined) { + if (state == RouterTransitionVisibility.Hiding) { + if (style._scale !== undefined) { + node.scaleAttribute(style._scale) + } + + if (style._slide !== undefined) { + const translate = slideTransition(size, style._slide) + AnimationExtender.AnimationTranslate(node.getPeerPtr(), translate) + } else if (style._translate !== undefined) { + AnimationExtender.AnimationTranslate(node.getPeerPtr(), style._translate) + } + } else if (state == RouterTransitionVisibility.Showing) { + node.scaleAttribute(NO_SCALE) + AnimationExtender.AnimationTranslate(node.getPeerPtr(), ZERO_TRANSLATE) + } + } + + AnimationExtender.SetClipRect(node.getPeerPtr(), 0, 0, 10000, 10000) + AnimationExtender.CloseImplicitAnimation() + + const doubleParams = progressAnimation(state, style) + if (doubleParams) { + AnimationExtender.StartDoubleAnimation(node.getPeerPtr(), doubleParams) + } + }) +} + +/** + * @memo + */ +function NotifyPageTransition(pageId: int32, style: ArkPageTransitionData, state: RouterTransitionVisibility) { + const node = findContainerNode(contextNode(PeerNodeType)) + if (node) { + const size = getNodeSize(node) + const router = CurrentRouter() + if (sizeNotEmpty(size)) { + launchTransitionForSize(node, router, size, pageId, style, state) + } else { + node.onSizeChangeAttribute((oldSize, newSize) => { + if (sizeNotEmpty(newSize) && oldSize.width != newSize.width && oldSize.height != newSize.height) { + launchTransitionForSize(node, router, newSize, pageId, style, state) + } + }) + } + } +} + +export type ProgressCallback = (type: RouteType, progress: number) => void + +export class ArkPageTransitionData { + params: PageTransitionOptions + _onEnter?: ProgressCallback + _onExit?: ProgressCallback + _slide?: SlideEffect + _translate?: TranslateOptions + _scale?: ScaleOptions + _opacity?: number + + constructor(params: PageTransitionOptions) { + this.params = params + } + onEnter(event: ProgressCallback): this { + this._onEnter = event + return this + } + onExit(event: ProgressCallback): this { + this._onExit = event + return this + } slide(value: SlideEffect): this { - console.log("CommonTransition.slide") - // if (this.checkPriority("slide")) { - // const value_casted = value as (SlideEffect) - // this.getPeer()?.slideAttribute(value_casted) - // return this - // } + this._slide = value return this } - /** @memo */ translate(value: TranslateOptions): this { - // if (this.checkPriority("translate")) { - // const value_casted = value as (TranslateOptions) - // this.getPeer()?.translateAttribute(value_casted) - // return this - // } - console.log("CommonTransition.translate") + this._translate = value return this } - /** @memo */ - scale(value: ScaleOptions): this { - // if (this.checkPriority("scale")) { - // const value_casted = value as (ScaleOptions) - // this.getPeer()?.scaleAttribute(value_casted) - // return this - // } - console.log("CommonTransition.scale") + opacity(value: number): this { + this._opacity = value return this } - /** @memo */ - opacity(value: number): this { - // if (this.checkPriority("opacity")) { - // const value_casted = value as (number) - // this.getPeer()?.opacityAttribute(value_casted) - // return this - // } - console.log("CommonTransition.number") + scale(value: ScaleOptions): this { + this._scale = value return this } - public applyAttributesFinish(): void { - // we calls this function outside of class, so need to make it public - super.applyAttributesFinish() +} + +export class ArkPageTransitionEnterComponent extends ArkPageTransitionData { + constructor(params: PageTransitionOptions) { + super(params) + } +} + +export class ArkPageTransitionExitComponent extends ArkPageTransitionData { + constructor(params: PageTransitionOptions) { + super(params) + } +} + +/** + * @memo + */ +export function ArkPageTransitionEnter( + /** @memo */ + style: ((attributes: ArkPageTransitionEnterComponent) => void) | undefined, + contentUnused: (() => void) | undefined, + params: PageTransitionOptions +) { + const receiver = remember(() => new ArkPageTransitionEnterComponent(params)) + style?.(receiver) + const state = CurrentRouterTransitionState() + if (state !== undefined && state.visibility == RouterTransitionVisibility.Showing) { + NotifyPageTransition(state.pageId, receiver, RouterTransitionVisibility.Showing) } } + +/** + * @memo + */ +export function ArkPageTransitionExit( + /** @memo */ + style: ((attributes: ArkPageTransitionExitComponent) => void) | undefined, + contentUnused: (() => void) | undefined, + params: PageTransitionOptions +) { + const receiver = remember(() => new ArkPageTransitionExitComponent(params)) + style?.(receiver) + const state = CurrentRouterTransitionState() + if (state !== undefined && state.visibility == RouterTransitionVisibility.Hiding) { + NotifyPageTransition(state.pageId, receiver, RouterTransitionVisibility.Hiding) + } +} \ No newline at end of file diff --git a/arkoala/arkui/src/index.ts b/arkoala/arkui/src/index.ts index cf654d25924006d80bba95b421cbec52f9021a9e..7d1a2f060c893a30a77e9d70a9f8d3c6fd5e8526 100644 --- a/arkoala/arkui/src/index.ts +++ b/arkoala/arkui/src/index.ts @@ -123,15 +123,8 @@ export { _r, _rawfile, __registerResources } from "./resources" export * from "./ArkTransition" export * from "./generated/ArkDataPanel" export * from "./generated/ArkPanel" -export { - ArkPageTransitionEnterComponent, - ArkPageTransitionEnterComponent as PageTransitionEnterAttribute, - ArkPageTransitionExitComponent, - ArkPageTransitionExitComponent as PageTransitionExitAttribute, - // todo: why we need explicit export here? - LocalStorage -} from "@koalaui/arkui-common" export { Observed, observableProxy } from "@koalaui/common" +export { LocalStorage } from "@koalaui/arkui-common" export * from "@koalaui/arkui-common" export * from "./shared/ArkUtils" export * from "./generated/peers/ArkButtonPeer" @@ -154,6 +147,7 @@ export { Attach } from "./ComponentBase" export * from "./generated/ArkNavPathStackMaterialized" export * from "./generated/ArkTabsControllerMaterialized" export * from "./generated/ArkRenderingContextSettingsMaterialized" +export * from "./generated/ArkAnimationExtenderMaterialized" export * from "./generated/ArkAlertDialogInterfaces" export * from "./generated/ArkAlphabetIndexerInterfaces" diff --git a/arkoala/ohos-sdk/scripts/ohos-app/build.mjs b/arkoala/ohos-sdk/scripts/ohos-app/build.mjs index 40e6dac4bc24202836ed9feddcdab8815b45ad89..36cf9c48fa73b08bf358c925b46a88439c7f69b5 100644 --- a/arkoala/ohos-sdk/scripts/ohos-app/build.mjs +++ b/arkoala/ohos-sdk/scripts/ohos-app/build.mjs @@ -42,8 +42,6 @@ export async function build(options) { [`"${path.join(LZ_TOOLS(), "ohpm/bin/ohpm")}"`, "install", "--all", - "--registry", - "https://cmc.centralrepo.rnd.huawei.com/artifactory/api/npm/product_npm", "--strict_ssl", "false", ...extraOptions],