Skip to content

Commit

Permalink
feat(harmony): 实现基础页面创建
Browse files Browse the repository at this point in the history
  • Loading branch information
zhetengbiji committed May 21, 2024
1 parent a7e62ae commit 0d4bfc9
Show file tree
Hide file tree
Showing 16 changed files with 319 additions and 16 deletions.
6 changes: 4 additions & 2 deletions packages/uni-app-harmony/build.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"__UNI_FEATURE_I18N_ES__": "true",
"__UNI_FEATURE_I18N_FR__": "true",
"__UNI_FEATURE_I18N_ZH_HANS__": "true",
"__UNI_FEATURE_I18N_ZH_HANT__": "true"
"__UNI_FEATURE_I18N_ZH_HANT__": "true",
"plus.os.name": "'Harmony'",
"plus.os.version": "''"
},
"external": [
"vue",
Expand All @@ -29,4 +31,4 @@
}
]
}
]
]
4 changes: 4 additions & 0 deletions packages/uni-app-harmony/src/helpers/statusBar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function getStatusbarHeight() {
// TODO
return 0
}
82 changes: 82 additions & 0 deletions packages/uni-app-harmony/src/service/api/route/navigateTo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { EventChannel, ON_HIDE, parseUrl } from '@dcloudio/uni-shared'
import { invokeHook } from '@dcloudio/uni-core'
import {
API_NAVIGATE_TO,
type API_TYPE_NAVIGATE_TO,
type DefineAsyncApiFn,
NavigateToOptions,
NavigateToProtocol,
defineAsyncApi,
} from '@dcloudio/uni-api'
import { type RouteOptions, navigate } from './utils'
import { showWebview } from '@dcloudio/uni-app-plus/service/api/route/webview'
import { registerPage } from '../../framework/page'
import { getWebviewId } from '@dcloudio/uni-app-plus/service/framework/webview/utils'
import { initAnimation } from '@dcloudio/uni-app-plus/service/api/route/navigateTo'

export const $navigateTo: DefineAsyncApiFn<API_TYPE_NAVIGATE_TO> = (
args,
{ resolve, reject }
) => {
const { url, events, animationType, animationDuration } = args
const { path, query } = parseUrl(url)
const [aniType, aniDuration] = initAnimation(
path,
animationType,
animationDuration
)
navigate(
path,
() => {
_navigateTo({
url,
path,
query,
events,
aniType,
aniDuration,
})
.then(resolve)
.catch(reject)
},
(args as any).openType === 'appLaunch'
)
}

export const navigateTo = defineAsyncApi<API_TYPE_NAVIGATE_TO>(
API_NAVIGATE_TO,
$navigateTo,
NavigateToProtocol,
NavigateToOptions
)

interface NavigateToOptions extends RouteOptions {
events: Record<string, any>
aniType: string
aniDuration: number
}

function _navigateTo({
url,
path,
query,
events,
aniType,
aniDuration,
}: NavigateToOptions): Promise<void | { eventChannel: EventChannel }> {
// 当前页面触发 onHide
invokeHook(ON_HIDE)
invokeHook(ON_HIDE)
const eventChannel = new EventChannel(getWebviewId() + 1, events)
return new Promise((resolve) => {
showWebview(
registerPage({ url, path, query, openType: 'navigateTo', eventChannel }),
aniType,
aniDuration,
() => {
resolve({ eventChannel })
}
)
// TODO setStatusBarStyle()
})
}
8 changes: 8 additions & 0 deletions packages/uni-app-harmony/src/service/api/route/switchTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { API_TYPE_SWITCH_TAB, DefineAsyncApiFn } from '@dcloudio/uni-api'

export const $switchTab: DefineAsyncApiFn<API_TYPE_SWITCH_TAB> = (
args,
{ resolve, reject }
) => {
throw new Error('API $switchTab is not yet implemented')
}
43 changes: 43 additions & 0 deletions packages/uni-app-harmony/src/service/api/route/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
getPendingNavigator,
pendingNavigate,
setPendingNavigator,
} from '@dcloudio/uni-app-plus/service/api/route/utils'
import {
getPreloadWebview,
onWebviewReady,
} from '@dcloudio/uni-app-plus/service/framework/webview'
export type { RouteOptions } from '@dcloudio/uni-app-plus/service/api/route/utils'

export function navigate(
path: string,
callback: () => void,
isAppLaunch: boolean
) {
const pendingNavigator = getPendingNavigator()
if (!isAppLaunch && pendingNavigator) {
return console.error(
`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`
)
}

// 未创建 preloadWebview 或 preloadWebview 已被使用
const preloadWebview = getPreloadWebview()
const waitPreloadWebview =
!preloadWebview || (preloadWebview && preloadWebview.__uniapp_route)
// 已创建未 loaded
const waitPreloadWebviewReady = preloadWebview && !preloadWebview.loaded

if (waitPreloadWebview || waitPreloadWebviewReady) {
setPendingNavigator(
path,
callback,
waitPreloadWebview ? 'waitForCreate' : 'waitForReady'
)
} else {
callback()
}
if (waitPreloadWebviewReady) {
onWebviewReady(preloadWebview.id!, pendingNavigate)
}
}
3 changes: 2 additions & 1 deletion packages/uni-app-harmony/src/service/bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ function publishHandler(
}
pageIds.forEach((id) => {
const idStr = String(id)
const webview = plus.webview.getWebviewById(idStr)
const code = evalJSCode.replace('__PAGE_ID__', idStr)
console.log('TODO eval:', idStr, code)
webview && webview.evalJS(code)
})
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { subscribePlusMessage } from '@dcloudio/uni-app-plus/service/framework/app/initGlobalEvent'

export function initGlobalEvent() {
// TODO
const plusGlobalEvent = (plus as any).globalEvent

// TODO KeyboardHeightChange

plusGlobalEvent.addEventListener('plusMessage', subscribePlusMessage)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
import { getRouteOptions } from '@dcloudio/uni-core'
import { addLeadingSlash } from '@dcloudio/uni-shared'
import { $navigateTo } from '../../../api/route/navigateTo'
import { $switchTab } from '../../../api/route/switchTab'
import {
getPreloadWebview,
setPreloadWebview,
} from '@dcloudio/uni-app-plus/service/framework/webview'
import { ON_WEBVIEW_READY } from '@dcloudio/uni-app-plus/constants'

let isLaunchWebviewReady = false // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady
export function subscribeWebviewReady(_data: unknown, pageId: string) {
// TODO
const isLaunchWebview = pageId === '1'
if (isLaunchWebview && isLaunchWebviewReady) {
if (__DEV__) {
console.log('[uni-app] onLaunchWebviewReady.prevent')
}
return
}
let preloadWebview = getPreloadWebview()
if (isLaunchWebview) {
// 首页
isLaunchWebviewReady = true
preloadWebview = setPreloadWebview(plus.webview.getLaunchWebview())
} else if (!preloadWebview) {
// preloadWebview 不存在,重新加载一下
preloadWebview = setPreloadWebview(plus.webview.getWebviewById(pageId))
}
// 仅当 preloadWebview 未 loaded 时处理
if (!preloadWebview.loaded) {
if (preloadWebview.id !== pageId) {
return console.error(
`webviewReady[${preloadWebview.id}][${pageId}] not match`
)
}
;(preloadWebview as any).loaded = true // 标记已 ready
}
UniServiceJSBridge.emit(ON_WEBVIEW_READY + '.' + pageId)
isLaunchWebview && onLaunchWebviewReady()
}

function onLaunchWebviewReady() {
// TODO closeSplashscreen
const entryPagePath = addLeadingSlash(__uniConfig.entryPagePath!)
const routeOptions = getRouteOptions(entryPagePath)!
const args = {
url: entryPagePath + (__uniConfig.entryPageQuery || ''),
openType: 'appLaunch',
}
const handler = { resolve() {}, reject() {} }
if (routeOptions.meta.isTabBar) {
return $switchTab(args, handler)
}
return $navigateTo(args, handler)
}
2 changes: 2 additions & 0 deletions packages/uni-app-harmony/src/service/framework/page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { definePage } from '@dcloudio/uni-app-plus/service/framework/page/define'
export { registerPage } from './register'
86 changes: 86 additions & 0 deletions packages/uni-app-harmony/src/service/framework/page/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { hasOwn } from '@vue/shared'
import type { RegisterPageOptions } from '@dcloudio/uni-app-plus/service/framework/page/register'
import { initRouteOptions } from '@dcloudio/uni-app-plus/service/framework/page/routeOptions'
import { createWebview } from '../webview'
import {
ON_REACH_BOTTOM_DISTANCE,
type PageNodeOptions,
formatLog,
} from '@dcloudio/uni-shared'
import { initPageInternalInstance } from '@dcloudio/uni-core'
import { createVuePage } from '@dcloudio/uni-app-plus/service/framework/page/define'
import { getStatusbarHeight } from '../../../helpers/statusBar'
import { getBaseSystemInfo } from '../../api/base/getBaseSystemInfo'

export function registerPage({
url,
path,
query,
openType,
webview,
nvuePageVm,
eventChannel,
}: RegisterPageOptions) {
// TODO initEntry()
// TODO preloadWebviews[url]

const routeOptions = initRouteOptions(path, openType)

if (!webview) {
webview = createWebview({ path, routeOptions, query })
} else {
webview = plus.webview.getWebviewById(webview.id)
;(webview as any).nvue = routeOptions.meta.isNVue
}

routeOptions.meta.id = parseInt(webview.id!)

if (__DEV__) {
console.log(formatLog('registerPage', path, webview.id))
}

// TODO initWebview
const route = path.slice(1)
;(webview as any).__uniapp_route = route

const pageInstance = initPageInternalInstance(
openType,
url,
query,
routeOptions.meta,
eventChannel,
// TODO theme
'light'
)

const id = parseInt(webview.id!)

createVuePage(id, route, query, pageInstance, initPageOptions(routeOptions))

return webview
}

function initPageOptions({ meta }: UniApp.UniRoute): PageNodeOptions {
const statusbarHeight = getStatusbarHeight()
const { platform, pixelRatio, windowWidth } = getBaseSystemInfo()
return {
css: true,
route: meta.route,
version: 1,
locale: '',
platform,
pixelRatio,
windowWidth,
disableScroll: meta.disableScroll === true,
onPageScroll: false,
onPageReachBottom: false,
onReachBottomDistance: hasOwn(meta, 'onReachBottomDistance')
? meta.onReachBottomDistance!
: ON_REACH_BOTTOM_DISTANCE,
statusbarHeight,
// TODO meta.navigationBar.type === 'float'
windowTop: 0,
// TODO tabBar.cover
windowBottom: 0,
}
}
10 changes: 10 additions & 0 deletions packages/uni-app-harmony/src/service/framework/webview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { CreateWebviewOptions } from '@dcloudio/uni-app-plus/service/framework/webview'
import { getWebviewId } from '@dcloudio/uni-app-plus/service/framework/webview/utils'
import { getPreloadWebview } from '@dcloudio/uni-app-plus/service/framework/webview/preload'

export function createWebview(options: CreateWebviewOptions) {
if (getWebviewId() === 2) {
return plus.webview.getLaunchWebview()
}
return getPreloadWebview()
}
11 changes: 5 additions & 6 deletions packages/uni-app-plus/src/service/api/route/navigateTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ import { registerPage } from '../../framework/page'
import { getWebviewId } from '../../framework/webview/utils'
import { setStatusBarStyle } from '../../statusBar'

export const $navigateTo: DefineAsyncApiFn<API_TYPE_NAVIGATE_TO> = (
args,
{ resolve, reject }
) => {
export const $navigateTo: DefineAsyncApiFn<
API_TYPE_NAVIGATE_TO
> = /*#__PURE__*/ (args, { resolve, reject }) => {
const { url, events, animationType, animationDuration } = args
const { path, query } = parseUrl(url)
const [aniType, aniDuration] = initAnimation(
Expand All @@ -45,7 +44,7 @@ export const $navigateTo: DefineAsyncApiFn<API_TYPE_NAVIGATE_TO> = (
)
}

export const navigateTo = defineAsyncApi<API_TYPE_NAVIGATE_TO>(
export const navigateTo = /*#__PURE__*/ defineAsyncApi<API_TYPE_NAVIGATE_TO>(
API_NAVIGATE_TO,
$navigateTo,
NavigateToProtocol,
Expand Down Expand Up @@ -82,7 +81,7 @@ function _navigateTo({
})
}

function initAnimation(
export function initAnimation(
path: string,
animationType?: string,
animationDuration?: number
Expand Down
12 changes: 10 additions & 2 deletions packages/uni-app-plus/src/service/api/route/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ interface PendingNavigator {

let pendingNavigator: PendingNavigator | false = false

function setPendingNavigator(path: string, callback: Function, msg: string) {
export function getPendingNavigator() {
return pendingNavigator
}

export function setPendingNavigator(
path: string,
callback: Function,
msg: string
) {
pendingNavigator = {
path,
nvue: getRouteMeta(path)!.isNVue,
Expand Down Expand Up @@ -80,7 +88,7 @@ export function navigate(
}
}

function pendingNavigate() {
export function pendingNavigate() {
if (!pendingNavigator) {
return
}
Expand Down
Loading

0 comments on commit 0d4bfc9

Please sign in to comment.