@tarojs/plugin-platform-harmony-ets 4.0.0-alpha.29 → 4.0.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/media/image/index.ts +207 -44
- package/dist/apis/utils/index.ts +18 -1
- package/dist/apis/utils/permissions.ts +6 -0
- package/dist/components-harmony-ets/style.ets +9 -4
- package/dist/components-harmony-ets/utils/styles.ets +2 -0
- package/dist/runtime-ets/dom/element/element.ts +20 -1
- package/dist/runtime-ets/dom/stylesheet/covertWeb2Hm.ts +2 -2
- package/dist/runtime-ets/dom/stylesheet/type.ts +4 -4
- package/dist/runtime-framework/react/native-page.ts +25 -16
- package/dist/runtime-utils.js +219 -67
- package/dist/runtime-utils.js.map +1 -1
- package/dist/runtime.js +219 -67
- package/dist/runtime.js.map +1 -1
- package/package.json +9 -9
- package/types/harmony.d.ts +1 -0
|
@@ -9,11 +9,15 @@
|
|
|
9
9
|
// ❌ wx.saveImageToPhotosAlbum(Object object) api 9+ HarmonyOS不支持
|
|
10
10
|
// ❌ wx.previewImage(Object object) api 9+ HarmonyOS不支持
|
|
11
11
|
|
|
12
|
+
import fs from '@ohos.file.fs'
|
|
12
13
|
import picker from '@ohos.file.picker'
|
|
13
14
|
import image from '@ohos.multimedia.image'
|
|
15
|
+
import { Current } from '@tarojs/runtime'
|
|
14
16
|
import { isNull } from '@tarojs/shared'
|
|
15
17
|
|
|
16
|
-
import {
|
|
18
|
+
import { getSystemInfoSync } from '../../base'
|
|
19
|
+
import { callAsyncFail, callAsyncSuccess, requestPermissions, temporarilyNotSupport, validateParams } from '../../utils'
|
|
20
|
+
import { IMAGE_PERMISSION } from '../../utils/permissions'
|
|
17
21
|
|
|
18
22
|
import type Taro from '@tarojs/taro/types'
|
|
19
23
|
|
|
@@ -22,12 +26,21 @@ interface IPackingOptionOHOS {
|
|
|
22
26
|
quality: number
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
interface IChooseImageData {
|
|
30
|
+
tempFilePaths?: string[]
|
|
31
|
+
|
|
32
|
+
tempFiles?: {
|
|
33
|
+
path: string
|
|
34
|
+
size: number
|
|
35
|
+
}[]
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
const getImageInfoSchema = {
|
|
26
|
-
|
|
39
|
+
src: 'String'
|
|
27
40
|
}
|
|
28
41
|
|
|
29
42
|
const compressImageSchema = {
|
|
30
|
-
|
|
43
|
+
src: 'String'
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
const chooseImageSchema = {
|
|
@@ -60,61 +73,211 @@ export const getImageInfo: typeof Taro.getImageInfo = function (options) {
|
|
|
60
73
|
})
|
|
61
74
|
}
|
|
62
75
|
|
|
76
|
+
|
|
77
|
+
class CompressedImageInfo {
|
|
78
|
+
imageUri = '' // 压缩后图片保存位置的uri
|
|
79
|
+
imageByteLength = 0 // 压缩后图片字节长度
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function saveImage(compressedImageData, compressedImageUri) {
|
|
83
|
+
const tempArr = compressedImageUri.split('/')
|
|
84
|
+
const name = tempArr[tempArr.length - 1]
|
|
85
|
+
const context = getContext(Current?.page)
|
|
86
|
+
const applicationContext = context.getApplicationContext()
|
|
87
|
+
const tempDir = applicationContext.tempDir
|
|
88
|
+
const filePath = `${tempDir}/${name}`
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const res = fs.accessSync(filePath)
|
|
92
|
+
if (res) {
|
|
93
|
+
// 如果图片afterCompressiona.jpeg已存在,则删除
|
|
94
|
+
fs.unlinkSync(filePath)
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.error(`[Taro] saveImage Error: AccessSync failed with error message: ${err.message}, error code: ${err.code}`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 知识点:保存图片。获取最终图片压缩数据compressedImageData,保存图片。
|
|
101
|
+
// 压缩图片数据写入文件
|
|
102
|
+
const file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
|
|
103
|
+
fs.writeSync(file.fd, compressedImageData)
|
|
104
|
+
fs.closeSync(file)
|
|
105
|
+
|
|
106
|
+
// 获取压缩图片信息
|
|
107
|
+
const compressedImageInfo = new CompressedImageInfo()
|
|
108
|
+
compressedImageInfo.imageUri = filePath
|
|
109
|
+
compressedImageInfo.imageByteLength = compressedImageData.byteLength
|
|
110
|
+
|
|
111
|
+
return compressedImageInfo
|
|
112
|
+
}
|
|
113
|
+
|
|
63
114
|
export const compressImage: typeof Taro.compressImage = function (options) {
|
|
64
115
|
return new Promise((resolve, reject) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
116
|
+
requestPermissions(IMAGE_PERMISSION).then(() => {
|
|
117
|
+
try {
|
|
118
|
+
validateParams('compressImage', options, compressImageSchema)
|
|
119
|
+
} catch (error) {
|
|
120
|
+
const res = { errMsg: error.message }
|
|
121
|
+
return callAsyncFail(reject, res, options)
|
|
122
|
+
}
|
|
123
|
+
const { src, quality = 80, compressedWidth, compressedHeight } = options
|
|
124
|
+
const srcAfterCompress = src.includes('_after_compress') ? src : src.split('.').join('_after_compress.')
|
|
125
|
+
const file = fs.openSync(src, fs.OpenMode.READ_ONLY)
|
|
72
126
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const createImageSourceError = { errMsg: 'compressImage fail: createImageSource has failed.' }
|
|
76
|
-
callAsyncFail(reject, createImageSourceError, options)
|
|
77
|
-
return
|
|
78
|
-
}
|
|
127
|
+
// const stat = fs.statSync(file.fd)
|
|
128
|
+
// console.log('[Taro] 压缩前图片的大小为:', stat.size)
|
|
79
129
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
130
|
+
const source = image.createImageSource(file.fd)
|
|
131
|
+
if (isNull(source)) {
|
|
132
|
+
const createImageSourceError = { errMsg: 'compressImage fail: createImageSource has failed.' }
|
|
133
|
+
callAsyncFail(reject, createImageSourceError, options)
|
|
134
|
+
return
|
|
135
|
+
}
|
|
85
136
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
137
|
+
const width = source.getImageInfoSync().size.width
|
|
138
|
+
const height = source.getImageInfoSync().size.height
|
|
139
|
+
let wantWidth = compressedWidth || compressedHeight || 0
|
|
140
|
+
let wantHeight = compressedHeight || compressedWidth || 0
|
|
141
|
+
|
|
142
|
+
if (width > wantWidth || height > wantHeight) {
|
|
143
|
+
const heightRatio = height / wantHeight
|
|
144
|
+
const widthRatio = width / wantWidth
|
|
145
|
+
const finalRatio = heightRatio < widthRatio ? heightRatio : widthRatio
|
|
146
|
+
|
|
147
|
+
wantWidth = Math.round(width / finalRatio)
|
|
148
|
+
wantHeight = Math.round(height / finalRatio)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const decodingOptions = {
|
|
152
|
+
editable: true,
|
|
153
|
+
desiredPixelFormat: image.PixelMapFormat.RGBA_8888,
|
|
154
|
+
desiredSize: { width: wantWidth, height: wantHeight }
|
|
155
|
+
}
|
|
156
|
+
source.createPixelMap(decodingOptions, (error, pixelMap) => {
|
|
157
|
+
if (error !== undefined) {
|
|
158
|
+
fs.closeSync(file)
|
|
159
|
+
const res = { errMsg: error }
|
|
160
|
+
callAsyncFail(reject, res, options)
|
|
161
|
+
} else {
|
|
162
|
+
const packer = image.createImagePacker(file.fd)
|
|
163
|
+
if (isNull(packer)) {
|
|
164
|
+
fs.closeSync(file)
|
|
165
|
+
const createImagePackerError = { errMsg: 'compressImage fail: createImagePacker has failed.' }
|
|
166
|
+
callAsyncFail(reject, createImagePackerError, options)
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const isPNG = src.endsWith('.png')
|
|
171
|
+
const packingOptionsOHOS: IPackingOptionOHOS = {
|
|
172
|
+
format: isPNG ? 'image/png' : 'image/jpeg',
|
|
173
|
+
quality: quality
|
|
174
|
+
}
|
|
175
|
+
packer.packing(pixelMap, packingOptionsOHOS).then((value) => {
|
|
176
|
+
fs.closeSync(file)
|
|
177
|
+
saveImage(value, srcAfterCompress).then(result => {
|
|
178
|
+
callAsyncSuccess(resolve, { tempFilePath: result.imageUri }, options)
|
|
179
|
+
})
|
|
180
|
+
}).catch((error) => {
|
|
181
|
+
fs.closeSync(file)
|
|
182
|
+
callAsyncFail(reject, error, options)
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
}, (error: string) => {
|
|
187
|
+
const res = { errMsg: error }
|
|
188
|
+
return callAsyncFail(reject, res, options)
|
|
95
189
|
})
|
|
96
190
|
})
|
|
97
191
|
}
|
|
98
192
|
|
|
99
193
|
export const chooseImage: typeof Taro.chooseImage = function (options) {
|
|
100
194
|
return new Promise((resolve, reject) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
195
|
+
requestPermissions(IMAGE_PERMISSION).then(() => {
|
|
196
|
+
try {
|
|
197
|
+
validateParams('chooseImage', options, chooseImageSchema)
|
|
198
|
+
} catch (error) {
|
|
199
|
+
const res = { errMsg: error.message }
|
|
200
|
+
return callAsyncFail(reject, res, options)
|
|
201
|
+
}
|
|
107
202
|
|
|
108
|
-
|
|
109
|
-
|
|
203
|
+
const { count = 9 } = options
|
|
204
|
+
const photoViewPicker = new picker.PhotoViewPicker()
|
|
205
|
+
let sizeType = options.sizeType
|
|
110
206
|
|
|
111
|
-
|
|
112
|
-
|
|
207
|
+
if (!sizeType || !sizeType.length) {
|
|
208
|
+
sizeType = ['compressed', 'original']
|
|
209
|
+
}
|
|
113
210
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
211
|
+
photoSelectOptions.maxSelectNumber = count // 选择媒体文件的最大数目
|
|
212
|
+
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE // 过滤选择媒体文件类型为IMAGE
|
|
213
|
+
|
|
214
|
+
photoViewPicker.select(photoSelectOptions).then((photoSelectResult) => {
|
|
215
|
+
const result: IChooseImageData = {}
|
|
216
|
+
const isOrigin = photoSelectResult.isOriginalPhoto
|
|
217
|
+
|
|
218
|
+
if (isOrigin) {
|
|
219
|
+
const tempFilePaths: string[] = []
|
|
220
|
+
const tempFiles = photoSelectResult.photoUris.map(uri => {
|
|
221
|
+
const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
|
|
222
|
+
const stat = fs.statSync(file.fd)
|
|
223
|
+
const size = stat.size
|
|
224
|
+
|
|
225
|
+
fs.closeSync(file)
|
|
226
|
+
tempFilePaths.push(uri)
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
size,
|
|
230
|
+
path: uri,
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
result.tempFiles = tempFiles
|
|
235
|
+
result.tempFilePaths = tempFilePaths
|
|
236
|
+
|
|
237
|
+
callAsyncSuccess(resolve, result, options)
|
|
238
|
+
} else {
|
|
239
|
+
const actions: Promise<string>[] = photoSelectResult.photoUris.map(uri => {
|
|
240
|
+
return new Promise<string>(resolve => {
|
|
241
|
+
compressImage({
|
|
242
|
+
src: uri,
|
|
243
|
+
compressedWidth: getSystemInfoSync().screenWidth / 2,
|
|
244
|
+
compressedHeight: getSystemInfoSync().screenHeight / 2,
|
|
245
|
+
success: (compressResult) => {
|
|
246
|
+
resolve(compressResult.tempFilePath)
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
Promise.all(actions).then(tempFilePaths => {
|
|
253
|
+
const tempFiles = tempFilePaths.map(uri => {
|
|
254
|
+
const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
|
|
255
|
+
const stat = fs.statSync(file.fd)
|
|
256
|
+
const size: number = stat.size
|
|
257
|
+
|
|
258
|
+
fs.closeSync(file)
|
|
259
|
+
|
|
260
|
+
return {
|
|
261
|
+
size,
|
|
262
|
+
path: uri,
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
result.tempFilePaths = tempFilePaths
|
|
267
|
+
result.tempFiles = tempFiles
|
|
268
|
+
|
|
269
|
+
callAsyncSuccess(resolve, result, options)
|
|
270
|
+
}).catch(error => {
|
|
271
|
+
const res = { errMsg: error }
|
|
272
|
+
return callAsyncFail(reject, res, options)
|
|
273
|
+
})
|
|
274
|
+
}
|
|
275
|
+
}).catch((error) => {
|
|
276
|
+
callAsyncFail(reject, error, options)
|
|
277
|
+
})
|
|
278
|
+
}, (error: string) => {
|
|
279
|
+
const res = { errMsg: error }
|
|
280
|
+
return callAsyncFail(reject, res, options)
|
|
118
281
|
})
|
|
119
282
|
})
|
|
120
283
|
}
|
package/dist/apis/utils/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
|
|
2
|
+
import { Current, eventCenter } from '@tarojs/runtime'
|
|
2
3
|
|
|
3
4
|
import { ICallbackResult, MethodHandler } from './handler'
|
|
4
5
|
|
|
@@ -8,6 +9,22 @@ export * from './validate'
|
|
|
8
9
|
export { MethodHandler }
|
|
9
10
|
export { noop } from '@tarojs/shared'
|
|
10
11
|
|
|
12
|
+
export function requestPermissions (permissions: string[]) {
|
|
13
|
+
return new Promise<void>((resolve, reject) => {
|
|
14
|
+
const context = getContext(Current?.page)
|
|
15
|
+
const atManager = abilityAccessCtrl.createAtManager()
|
|
16
|
+
|
|
17
|
+
atManager.requestPermissionsFromUser(context, permissions, (err, _) => {
|
|
18
|
+
if (err) {
|
|
19
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
20
|
+
reject(`[Taro] 请求用户授权 ${permissions.join('、')} 失败:${JSON.stringify(err)}`)
|
|
21
|
+
} else {
|
|
22
|
+
resolve()
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
11
28
|
export function object2String (obj) {
|
|
12
29
|
let str = ''
|
|
13
30
|
for (const item in obj) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const READ_IMAGEVIDEO_PERMISSIONS = 'ohos.permission.READ_IMAGEVIDEO'
|
|
2
|
+
export const READ_MEDIA_PERMISSIONS = 'ohos.permission.READ_MEDIA'
|
|
3
|
+
export const WRITE_MEDIA_PERMISSIONS = 'ohos.permission.WRITE_MEDIA'
|
|
4
|
+
export const MEDIA_LOCATION_PERMISSIONS = 'ohos.permission.MEDIA_LOCATION'
|
|
5
|
+
|
|
6
|
+
export const IMAGE_PERMISSION = [READ_IMAGEVIDEO_PERMISSIONS, READ_MEDIA_PERMISSIONS, WRITE_MEDIA_PERMISSIONS, MEDIA_LOCATION_PERMISSIONS]
|
|
@@ -222,6 +222,7 @@ export function setSpecialTextAttributeIntoInstance(instance: TextAttribute, sty
|
|
|
222
222
|
}
|
|
223
223
|
if (!isUndefined(style.WebkitLineClamp)) {
|
|
224
224
|
instance.maxLines(style.WebkitLineClamp)
|
|
225
|
+
instance.textOverflow({overflow: TextOverflow.Ellipsis})
|
|
225
226
|
}
|
|
226
227
|
if (!isUndefined(style.letterSpacing)) {
|
|
227
228
|
instance.letterSpacing(style.letterSpacing)
|
|
@@ -368,16 +369,20 @@ export function setNormalAttributeIntoInstance(instance: CommonAttribute, style:
|
|
|
368
369
|
}
|
|
369
370
|
if (style.position === 'absolute' || style.position === 'fixed') {
|
|
370
371
|
instance.position({
|
|
371
|
-
|
|
372
|
-
|
|
372
|
+
left: style.left,
|
|
373
|
+
top: style.top,
|
|
374
|
+
right: style.right,
|
|
375
|
+
bottom: style.bottom,
|
|
373
376
|
})
|
|
374
377
|
// 绝对定位和固定定位在web上都会脱离文档流,因此需要设置zIndex让它相比正常流的元素更上层
|
|
375
378
|
instance.zIndex(1)
|
|
376
379
|
}
|
|
377
380
|
if (style.position === 'relative') {
|
|
378
381
|
instance.offset({
|
|
379
|
-
|
|
380
|
-
|
|
382
|
+
left: style.left,
|
|
383
|
+
top: style.top,
|
|
384
|
+
right: style.right,
|
|
385
|
+
bottom: style.bottom,
|
|
381
386
|
})
|
|
382
387
|
// 绝对定位和固定定位在web上都会脱离文档流,因此需要设置zIndex让它相比正常流的元素更上层
|
|
383
388
|
instance.zIndex(1)
|
|
@@ -34,7 +34,26 @@ export class TaroElement<
|
|
|
34
34
|
layer: 0 // 渲染层级
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
public
|
|
37
|
+
public _hm_instance: TaroAny
|
|
38
|
+
public weak_hm_instance: WeakRef<TaroAny>
|
|
39
|
+
public use_weak_hm_instance: boolean = true
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
public get hm_instance(): TaroAny {
|
|
43
|
+
if (this.use_weak_hm_instance && this.weak_hm_instance) {
|
|
44
|
+
return this.weak_hm_instance?.deref()
|
|
45
|
+
}
|
|
46
|
+
return this._hm_instance
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public set hm_instance(instance) {
|
|
50
|
+
if (this.use_weak_hm_instance && instance) {
|
|
51
|
+
this.weak_hm_instance = new WeakRef(instance)
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
this._hm_instance = instance
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
|
|
39
58
|
public get _instance () {
|
|
40
59
|
return this.hm_instance
|
|
@@ -594,9 +594,9 @@ function setBackgroundPosistion (hmStyle, value) {
|
|
|
594
594
|
} else if (horizontal === 'right' && vertical === 'bottom') {
|
|
595
595
|
hmStyle.backgroundPosition = Alignment.BottomEnd
|
|
596
596
|
} else {
|
|
597
|
-
if (
|
|
597
|
+
if (/^-?\d+(\.\d+)?(px|%|vw|vh)$/.test(horizontal)) {
|
|
598
598
|
hmStyle.backgroundPosition = { x: getUnit(horizontal) }
|
|
599
|
-
if (
|
|
599
|
+
if (/^-?\d+(\.\d+)?(px|%|vw|vh)$/.test(vertical)) {
|
|
600
600
|
hmStyle.backgroundPosition = { x: getUnit(horizontal), y: getUnit(vertical) }
|
|
601
601
|
}
|
|
602
602
|
}
|
|
@@ -38,10 +38,10 @@ export interface TaroStyleType {
|
|
|
38
38
|
|
|
39
39
|
// position
|
|
40
40
|
position?: 'relative' | 'absolute' | 'fixed'
|
|
41
|
-
top?:
|
|
42
|
-
left?:
|
|
43
|
-
bottom?:
|
|
44
|
-
right?:
|
|
41
|
+
top?: Dimension
|
|
42
|
+
left?: Dimension
|
|
43
|
+
bottom?: Dimension
|
|
44
|
+
right?: Dimension
|
|
45
45
|
|
|
46
46
|
// flex
|
|
47
47
|
flexBasis?: number | string
|
|
@@ -133,27 +133,33 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
|
|
|
133
133
|
},
|
|
134
134
|
}),
|
|
135
135
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
|
|
137
|
+
ReactDOM.flushSync(() => {
|
|
138
|
+
this.setState(
|
|
139
|
+
{
|
|
140
|
+
components: [...this.state.components, item],
|
|
141
|
+
},
|
|
142
|
+
() => cb && cb()
|
|
143
|
+
)
|
|
144
|
+
})
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
unmount (compId, cb?) {
|
|
145
148
|
const components = this.state.components
|
|
146
149
|
const index = components.findIndex((item) => item.compId === compId)
|
|
147
150
|
const next = [...components.slice(0, index), ...components.slice(index + 1)]
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
|
|
152
|
+
ReactDOM.flushSync(() => {
|
|
153
|
+
this.setState(
|
|
154
|
+
{
|
|
155
|
+
components: next,
|
|
156
|
+
},
|
|
157
|
+
() => {
|
|
158
|
+
removePageInstance(compId)
|
|
159
|
+
cb && cb()
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
})
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
render () {
|
|
@@ -175,7 +181,10 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
|
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
const root = ReactDOM.createRoot(app)
|
|
178
|
-
|
|
184
|
+
|
|
185
|
+
ReactDOM.flushSync(() => {
|
|
186
|
+
root.render?.(h(Entry))
|
|
187
|
+
})
|
|
179
188
|
}
|
|
180
189
|
|
|
181
190
|
|