已开启
fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理 #32
fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理 #32
已开启
mazheng创建于 5 天前
54 个文件变更+1029-40
@@ -0,0 +1,12 @@
1+node_modules
2+.vscode
3+/**/.vscode
4+bundle.harmony.js
5+*.code-workspace
6+**/.DS_Store
7+**/oh-package-lock.json5
8+**/BuildProfile.ets
9+/OHOS_OpenSDK1.0.0/*
10+lib/*
11+oh_modules/*
12+**/oh_modules/*
@@ -0,0 +1,5 @@
1+.idea
2+package-lock.json
3+node_modules
4+OAT.xml
5+example
ACHANGELOG.md+10-0文件内容审核中,请稍后刷新重试
AOAT.xml+83-0
@@ -0,0 +1,83 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<configuration>
3+ <oatconfig>
4+ <licensefile>LICENSE</licensefile>
5+ <policylist>
6+ <policy name="projectPolicy" desc="">
7+ <policyitem type="license" name="MIT" path=".*" desc="license under the MIT"/>
8+ </policy>
9+ <policy name="projectPolicy" desc="">
10+ <policyitem type="compatibility" name="GPL-2.0+" path=".*" desc="Process that runs independently, invoked by the X process."/>
11+ <policyitem type="compatibility" name="Apache-2.0" path=".*" desc="不影响兼容性"/>
12+ <policyitem type="compatibility" name="BSDStyleLicense" path=".*" desc="不影响兼容性" />
13+ <policyitem type="compatibility" name="MIT" path=".*" desc="不影响兼容性" />
14+ <policyitem type="compatibility" name="GPLStyleLicense" path=".*" desc="不影响兼容性" />
15+ </policy>
16+ </policylist>
17+ <filefilterlist>
18+ <filefilter name="copyrightPolicyFilter" desc="Filters for compatibility,license header policies">
19+ <filteritem type="filepath" name="harmony/doc-viewer/hvigorfile.ts" desc="hvigor构建脚本,DevEco Studio自动生成,不手动修改"/>
20+ <filteritem type="filepath" name="harmony/doc-viewer/src/main/cpp/generated/.*" desc="Codegen生成文件,不手动修改"/>
21+ <filteritem type="filepath" name="harmony/doc-viewer/src/main/ets/generated/.*" desc="Codegen生成文件,不手动修改"/>
22+ <filteritem type="filename" name="*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
23+ <filteritem type="filename" name="*/*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
24+ <filteritem type="filename" name="*.config.js" desc="工程配置文件,不手动修改"/>
25+ <filteritem type="filename" name=".prettierrc.js" desc="工程配置文件,不手动修改"/>
26+ <filteritem type="filename" name=".yarnrc" desc="工程配置文件,不手动修改"/>
27+ <filteritem type="filename" name=".npmignore" desc="工程配置文件,不手动修改"/>
28+ <filteritem type="filename" name=".ohpmignore" desc="工程配置文件,不手动修改"/>
29+ <filteritem type="filename" name="BuildProfile.ets" desc="工程配置文件,不手动修改"/>
30+ <filteritem type="filename" name="LICENSE" desc="版权文件,不添加版权头"/>
31+ <filteritem type="filename" name="LICENSE.md" desc="版权文件,不添加许可证头"/>
32+ <filteritem type="filename" name="yarn.lock" desc="依赖配置文件,不添加许可证头"/>
33+ <filteritem type="filepath" name="hvigorw" desc="工程模板,不修改版权头,以防有修改版权风险"/>
34+ <filteritem type="filepath" name="hvigorw.bat" desc="工程模板,不修改版权头,以防有修改版权风险"/>
35+ <filteritem type="filepath" name="js/*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
36+ <filteritem type="filepath" name="js/*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
37+ <filteritem type="filepath" name="src/*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
38+ <filteritem type="filepath" name="src/*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
39+ <filteritem type="filepath" name="*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
40+ <filteritem type="filepath" name="*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
41+ <filteritem type="filepath" name="index.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
42+ <filteritem type="filepath" name="hvigor/hvigor-wrapper.js" desc="工程模板,不修改版权头,以防有修改版权风险"/>
43+ <filteritem type="filepath" name="hvigor/hvigor-config.json5" desc="工程模板,不修改版权头,以防有修改版权风险"/>
44+ <filteritem type="filename" name="buildEnv.sh" desc="构建环境脚本文件,不修改版权头,以防有修改版权风险"/>
45+ <filteritem type="filepath" name="example/**/*" desc="示例工程,不添加版权头"/>
46+ </filefilter>
47+ <filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
48+ <filteritem type="filepath" name="harmony/doc-viewer/hvigorfile.ts" desc="hvigor构建脚本,DevEco Studio自动生成,不手动修改"/>
49+ <filteritem type="filepath" name="harmony/doc-viewer/src/main/cpp/generated/.*" desc="Codegen生成文件,不手动修改"/>
50+ <filteritem type="filepath" name="harmony/doc-viewer/src/main/ets/generated/.*" desc="Codegen生成文件,不手动修改"/>
51+ <filteritem type="filename" name="*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
52+ <filteritem type="filename" name="*/*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
53+ <filteritem type="filename" name="*.config.js" desc="工程配置文件,不手动修改"/>
54+ <filteritem type="filename" name=".prettierrc.js" desc="工程配置文件,不手动修改"/>
55+ <filteritem type="filename" name=".yarnrc" desc="工程配置文件,不手动修改"/>
56+ <filteritem type="filename" name=".npmignore" desc="工程配置文件,不手动修改"/>
57+ <filteritem type="filename" name=".ohpmignore" desc="工程配置文件,不手动修改"/>
58+ <filteritem type="filename" name="BuildProfile.ets" desc="工程配置文件,不手动修改"/>
59+ <filteritem type="filename" name="LICENSE" desc="版权文件,不添加许可证头"/>
60+ <filteritem type="filename" name="LICENSE.md" desc="版权文件,不添加许可证头"/>
61+ <filteritem type="filename" name="yarn.lock" desc="依赖配置文件,不添加许可证头"/>
62+ <filteritem type="filepath" name="hvigorw" desc="工程模板,不添加许可证头"/>
63+ <filteritem type="filepath" name="hvigorw.bat" desc="工程模板,不添加许可证头"/>
64+ <filteritem type="filepath" name="js/*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
65+ <filteritem type="filepath" name="js/*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
66+ <filteritem type="filepath" name="src/*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
67+ <filteritem type="filepath" name="src/*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
68+ <filteritem type="filepath" name="*.js" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
69+ <filteritem type="filepath" name="*.ts" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
70+ <filteritem type="filepath" name="index.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
71+ <filteritem type="filepath" name="hvigor/hvigor-wrapper.js" desc="工程模板,不修改版权头,以防有修改版权风险"/>
72+ <filteritem type="filepath" name="hvigor/hvigor-config.json5" desc="工程模板,不修改版权头,以防有修改版权风险"/>
73+ <filteritem type="filename" name="buildEnv.sh" desc="构建环境脚本文件,不修改版权头,以防有修改版权风险"/>
74+ <filteritem type="filepath" name="example/**/*" desc="示例工程,不添加版权头"/>
75+ </filefilter>
76+ 
77+ <filefilter name="binaryFileTypePolicyFilter" desc="Filters for copyright header policies">
78+ <filteritem type="filepath" name="harmony/doc_viewer.har" desc="项目打包文件"/>
79+ <filteritem type="filepath" name="example/**/*" desc="示例工程,不添加版权头"/>
80+ </filefilter>
81+ </filefilterlist>
82+ </oatconfig>
83+</configuration>
@@ -0,0 +1,4 @@
1+#!/bin/bash
2+BUILD_PKG_DIR=example
3+BUILD_SAMPLE_DIR=example/harmony
4+BUILD_THIRD_PARTY_DIR=harmony
@@ -0,0 +1,13 @@
1+{
2+ "extends": "@react-native",
3+ "rules": {
4+ "react-native/no-inline-styles": "off",
5+ "react/no-unstable-nested-components": "off",
6+ "react/react-in-jsx-scope": "off",
7+ "@typescript-eslint/no-unused-vars": "warn",
8+ "react-hooks/exhaustive-deps": "off",
9+ "radix": "off",
10+ "prettier/prettier": "warn",
11+ "max-lines": "off"
12+ }
13+}
@@ -0,0 +1,71 @@
1+.husky
2+bundle.harmony.js
3+package-lock.json
4+*.hbc
5+lintCppResult.txt
6+ 
7+# ---
8+ 
9+# OSX
10+#
11+.DS_Store
12+ 
13+# Xcode
14+#
15+build/
16+*.pbxuser
17+!default.pbxuser
18+*.mode1v3
19+!default.mode1v3
20+*.mode2v3
21+!default.mode2v3
22+*.perspectivev3
23+!default.perspectivev3
24+xcuserdata
25+*.xccheckout
26+*.moved-aside
27+DerivedData
28+*.hmap
29+*.ipa
30+*.xcuserstate
31+ 
32+# Android/IntelliJ
33+#
34+build/
35+.idea
36+.gradle
37+local.properties
38+*.iml
39+*.hprof
40+.cxx/
41+*.keystore
42+!debug.keystore
43+BuildProfile.ets
44+ 
45+# node.js
46+#
47+node_modules/
48+npm-debug.log
49+yarn-error.log
50+ 
51+# fastlane
52+#
53+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
54+# screenshots whenever they are needed.
55+# For more information about the recommended setup visit:
56+# https://docs.fastlane.tools/best-practices/source-control/
57+ 
58+**/fastlane/report.xml
59+**/fastlane/Preview.html
60+**/fastlane/screenshots
61+**/fastlane/test_output
62+ 
63+# Bundle artifact
64+*.jsbundle
65+ 
66+# Ruby / CocoaPods
67+/vendor/bundle/
68+ 
69+# Temporary files created by Metro to check the health of the file watcher
70+.metro-health-check*
71+*.htrace
@@ -0,0 +1 @@
1+18
@@ -0,0 +1,7 @@
1+module.exports = {
2+ arrowParens: 'avoid',
3+ bracketSameLine: true,
4+ bracketSpacing: true,
5+ singleQuote: true,
6+ trailingComma: 'all',
7+};
@@ -0,0 +1 @@
1+{}
@@ -0,0 +1,4 @@
1+{
2+ "name": "app_name",
3+ "displayName": "tester"
4+}
@@ -0,0 +1,3 @@
1+module.exports = {
2+ presets: ['module:metro-react-native-babel-preset'],
3+};
@@ -0,0 +1,24 @@
1+# it may cause some issues when building the project when switching branches
2+package-lock.json
3+# we add this because we want to keep the signing configs out of git
4+/build-profile.json5
5+ 
6+rnoh_modules
7+ 
8+**/oh-package-lock.json5
9+# ---
10+ 
11+/node_modules
12+/local.properties
13+/.idea
14+**/build
15+/.hvigor
16+.cxx
17+/.clangd
18+/.clang-format
19+/.clang-tidy
20+/oh_modules
21+hvigorw
22+hvigorw.bat
23+hvigor/hvigor-wrapper.js
24+ 
@@ -0,0 +1,10 @@
1+{
2+ "app": {
3+ "bundleName": "com.harmony.doc.viewer.demo",
4+ "vendor": "example",
5+ "versionCode": 1000000,
6+ "versionName": "1.0.0",
7+ "icon": "$media:app_icon",
8+ "label": "$string:app_name"
9+ }
10+}
@@ -0,0 +1,8 @@
1+{
2+ "string": [
3+ {
4+ "name": "app_name",
5+ "value": "RN Tester"
6+ }
7+ ]
8+}
@@ -0,0 +1,39 @@
1+{
2+ "app": {
3+ "products": [
4+ {
5+ "name": 'default',
6+ "signingConfig": 'default',
7+ "compatibleSdkVersion": '5.0.0(12)',
8+ "runtimeOS": 'HarmonyOS'
9+ },
10+ ],
11+ "buildModeSet": [
12+ {
13+ "name": 'debug',
14+ },
15+ {
16+ "name": 'release',
17+ },
18+ ],
19+ "signingConfigs": []
20+ },
21+ "modules": [
22+ {
23+ "name": 'entry',
24+ "srcPath": './entry',
25+ "targets": [
26+ {
27+ "name": 'default',
28+ "applyToProducts": [
29+ 'default'
30+ ],
31+ },
32+ ],
33+ },
34+ {
35+ "name": "doc_viewer",
36+ "srcPath": '../../harmony/doc-viewer'
37+ }
38+ ],
39+}
@@ -0,0 +1,32 @@
1+{
2+ "files": ["**/*.ts", "**/*.ets"],
3+ "ignore": [
4+ "**/ohosTest/**/*",
5+ "**/node_modules/**/*",
6+ "**/hvigorfile.ts",
7+ "**/node_modules/**/*",
8+ "**/oh_modules/**/*",
9+ "**/build/**/*",
10+ "**/.preview/**/*"
11+ ],
12+ "plugins": ["@typescript-eslint"],
13+ "ruleSet": [],
14+ "rules": {
15+ "@typescript-eslint/await-thenable": "warn",
16+ "@typescript-eslint/consistent-type-imports": "warn",
17+ "@typescript-eslint/explicit-function-return-type": "warn",
18+ "@typescript-eslint/explicit-module-boundary-types": "warn",
19+ "@typescript-eslint/no-dynamic-delete": "warn",
20+ "@typescript-eslint/no-explicit-any": "warn",
21+ "@typescript-eslint/no-for-in-array": "warn",
22+ "@typescript-eslint/no-this-alias": "warn",
23+ "@typescript-eslint/no-unnecessary-type-constraint": "warn",
24+ "@typescript-eslint/no-unsafe-argument": "warn",
25+ "@typescript-eslint/no-unsafe-assignment": "warn",
26+ "@typescript-eslint/no-unsafe-call": "warn",
27+ "@typescript-eslint/no-unsafe-member-access": "warn",
28+ "@typescript-eslint/no-unsafe-return": "warn",
29+ "@typescript-eslint/prefer-literal-enum-member": "warn"
30+ },
31+ "overrides": []
32+}
@@ -0,0 +1,7 @@
1+/node_modules
2+/.preview
3+/build
4+/.cxx
5+package-lock.json
6+/oh_modules
7+/assets
@@ -0,0 +1,22 @@
1+{
2+ "apiType": 'stageMode',
3+ "buildOption": {
4+ "externalNativeOptions": {
5+ "path": "./src/main/cpp/CMakeLists.txt",
6+ "arguments": "",
7+ "cppFlags": "-s",
8+ "abiFilters": [
9+ "arm64-v8a",
10+ "x86_64"
11+ ]
12+ },
13+ },
14+ "targets": [
15+ {
16+ "name": "default",
17+ },
18+ {
19+ "name": "ohosTest",
20+ }
21+ ]
22+}
@@ -0,0 +1,2 @@
1+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
2+export { hapTasks } from '@ohos/hvigor-ohos-plugin';
@@ -0,0 +1,11 @@
1+{
2+ "license": "ISC",
3+ "devDependencies": {},
4+ "name": "entry",
5+ "description": "example description",
6+ "version": "1.0.0",
7+ "dependencies": {
8+ "@rnoh/react-native-openharmony": "file:../../node_modules/react-native-harmony/react_native_openharmony.har",
9+ "@react-native-ohos/react-native-doc-viewer": "file:../../node_modules/@react-native-ohos/react-native-doc-viewer/harmony/doc_viewer.har"
10+ }
11+}
@@ -0,0 +1,2 @@
1+jsbundle.h
2+generated/
@@ -0,0 +1,41 @@
1+project(rnapp)
2+cmake_minimum_required(VERSION 3.4.1)
3+set(CMAKE_SKIP_BUILD_RPATH TRUE)
4+set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
5+set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
6+set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
7+set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/@rnoh/react-native-openharmony/src/main/cpp")
8+set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
9+set(LOG_VERBOSITY_LEVEL 1)
10+set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
11+set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
12+set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
13+ 
14+set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
15+add_compile_definitions(WITH_HITRACE_SYSTRACE)
16+ 
17+# (VM) Define a variable and assign it to the current module's cpp directory
18+set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
19+ 
20+# Add the Header File directory, including cpp, cpp/include, and tell cmake to find the Header Files introduced by the code here
21+include_directories(${NATIVERENDER_ROOT_PATH}
22+ ${NATIVERENDER_ROOT_PATH}/include)
23+ 
24+add_subdirectory("${RNOH_CPP_DIR}" ./rn)
25+ 
26+# RNOH_BEGIN: manual_package_linking_1
27+add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-doc-viewer/src/main/cpp" ./doc-viewer)
28+# RNOH_END: manual_package_linking_1
29+ 
30+file(GLOB GENERATED_CPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/generated/*.cpp") # this line is needed by codegen v1
31+ 
32+add_library(rnoh_app SHARED
33+ ${GENERATED_CPP_FILES}
34+ "./PackageProvider.cpp"
35+ "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
36+)
37+target_link_libraries(rnoh_app PUBLIC rnoh)
38+ 
39+# RNOH_BEGIN: manual_package_linking_2
40+target_link_libraries(rnoh_app PUBLIC rnoh_doc_viewer)
41+# RNOH_END: manual_package_linking_2
Aexample/harmony/entry/src/main/cpp/PackageProvider.cpp+13-0文件内容审核中,请稍后刷新重试
Aexample/harmony/entry/src/main/ets/RNPackagesFactory.ets+6-0文件内容审核中,请稍后刷新重试
Binary files do not support preview
Aexample/harmony/entry/src/main/ets/entryability/EntryAbility.ets+15-0文件内容审核中,请稍后刷新重试
Aexample/harmony/entry/src/main/ets/pages/Index.ets+106-0文件内容审核中,请稍后刷新重试
@@ -0,0 +1,47 @@
1+{
2+ "module": {
3+ "name": "entry",
4+ "type": "entry",
5+ "description": "$string:module_desc",
6+ "mainElement": "EntryAbility",
7+ "deviceTypes": [
8+ "default"
9+ ],
10+ "deliveryWithInstall": true,
11+ "installationFree": false,
12+ "pages": "$profile:main_pages",
13+ "requestPermissions": [
14+ {
15+ "name": "ohos.permission.INTERNET"
16+ },
17+ ],
18+ "metadata": [
19+ {
20+ "name": "OPTLazyForEach",
21+ "value": "true",
22+ }
23+ ],
24+ "abilities": [
25+ {
26+ "name": "EntryAbility",
27+ "srcEntry": "./ets/entryability/EntryAbility.ets",
28+ "description": "$string:EntryAbility_desc",
29+ "icon": "$media:icon",
30+ "label": "$string:EntryAbility_label",
31+ "startWindowIcon": "$media:icon",
32+ "startWindowBackground": "$color:start_window_background",
33+ "visible": true,
34+ "skills": [
35+ {
36+ "entities": [
37+ "entity.system.home"
38+ ],
39+ "actions": [
40+ "action.system.home"
41+ ]
42+ }
43+ ]
44+ }
45+ ]
46+ }
47+}
@@ -0,0 +1 @@
1+rawfile/assets
@@ -0,0 +1,8 @@
1+{
2+ "color": [
3+ {
4+ "name": "start_window_background",
5+ "value": "#FFFFFF"
6+ }
7+ ]
8+}
@@ -0,0 +1,16 @@
1+{
2+ "string": [
3+ {
4+ "name": "module_desc",
5+ "value": "module description"
6+ },
7+ {
8+ "name": "EntryAbility_desc",
9+ "value": "description"
10+ },
11+ {
12+ "name": "EntryAbility_label",
13+ "value": "RN Tester"
14+ }
15+ ]
16+}
@@ -0,0 +1,5 @@
1+{
2+ "src": [
3+ "pages/Index"
4+ ]
5+}
@@ -0,0 +1,12 @@
1+$directoryPath = Split-Path -Parent $MyInvocation.MyCommand.Path
2+$filePaths = Get-ChildItem $directoryPath -Recurse -Include *.h, *.cpp |
3+Where-Object {
4+ $_.DirectoryName -notmatch 'third-party' -and
5+ $_.DirectoryName -notmatch 'patches' -and
6+ $_.DirectoryName -notmatch 'node_modules' -and
7+ $_.DirectoryName -notmatch '.cxx' -and
8+ $_.DirectoryName -notmatch 'build'
9+}
10+foreach ($filePath in $filePaths) {
11+ & "clang-format.exe" -style=file -i $filePath.FullName
12+}
@@ -0,0 +1 @@
1+*.tgz
@@ -0,0 +1,21 @@
1+{
2+ "modelVersion": "5.0.0",
3+ "dependencies": {
4+ },
5+ "execution": {
6+ // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
7+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
8+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
9+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
10+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
11+ },
12+ "logging": {
13+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
14+ },
15+ "debugging": {
16+ "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
17+ },
18+ "nodeOptions": {
19+ // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */
20+ }
21+}
@@ -0,0 +1,2 @@
1+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
2+export { appTasks } from '@ohos/hvigor-ohos-plugin';
@@ -0,0 +1,12 @@
1+{
2+ "modelVersion": "5.0.0",
3+ "license": "ISC",
4+ "name": "rnoh",
5+ "description": "example description",
6+ "repository": {},
7+ "version": "1.0.0",
8+ "overrides": {
9+ "@rnoh/react-native-openharmony": "file:./../node_modules/react-native-harmony/react_native_openharmony.har"
10+ },
11+ "dynamicDependencies": {}
12+}
Aexample/index.js+5-0文件内容审核中,请稍后刷新重试
@@ -0,0 +1,5 @@
1+/** @type {import('ts-jest').JestConfigWithTsJest} */
2+module.exports = {
3+ preset: 'ts-jest',
4+ testEnvironment: 'node',
5+};
@@ -0,0 +1,24 @@
1+const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
2+const {createHarmonyMetroConfig} = require('react-native-harmony/metro.config');
3+ 
4+/**
5+ * @type {import("metro-config").ConfigT}
6+ */
7+const config = {
8+ transformer: {
9+ getTransformOptions: async () => ({
10+ transform: {
11+ experimentalImportSupport: false,
12+ inlineRequires: true,
13+ },
14+ }),
15+ },
16+};
17+ 
18+module.exports = mergeConfig(
19+ getDefaultConfig(__dirname),
20+ createHarmonyMetroConfig({
21+ reactNativeHarmonyPackageName: 'react-native-harmony',
22+ }),
23+ config,
24+);
@@ -0,0 +1,53 @@
1+{
2+ "name": "react-native-harmony-tester",
3+ "version": "1.0.0",
4+ "private": true,
5+ "scripts": {
6+ "i": "cd ../ && npm i && npm run pack && cd ./example && npm i",
7+ "reStart": "npm run install:pkg && npm run codegen && hdc rport tcp:8081 tcp:8081 && react-native start",
8+ "start": "hdc rport tcp:8081 tcp:8081 && react-native start",
9+ "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",
10+ "pack:pkg": "cd ../ && npm pack && cd ./example",
11+ "install:pkg": "npm uninstall @react-native-ohos/react-native-doc-viewer && npm run pack:pkg && npm i @react-native-ohos/react-native-doc-viewer@file:../react-native-ohos-react-native-doc-viewer-2.7.10-beta.1.tgz",
12+ "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",
13+ "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",
14+ "postinstall": "node ./scripts/create-build-profile",
15+ "fast:pkg": "cd ../ && npm i --legacy-peer-deps && npm pack && cd ./example && npm i --legacy-peer-deps && npm run dev"
16+ },
17+ "dependencies": {
18+ "@react-native-ohos/react-native-doc-viewer": "file:../react-native-ohos-react-native-doc-viewer-2.7.10-beta.1.tgz",
19+ "react": "18.2.0",
20+ "react-native": "0.72.5",
21+ "react-native-harmony": "npm:@react-native-oh/react-native-harmony@0.72.140"
22+ },
23+ "devDependencies": {
24+ "@babel/core": "^7.20.0",
25+ "@babel/preset-env": "^7.20.0",
26+ "@babel/runtime": "^7.20.0",
27+ "@react-native-community/cli": "15.0.1",
28+ "@react-native-community/eslint-config": "^3.2.0",
29+ "@react-native/metro-config": "^0.72.9",
30+ "@rnoh/react-native-harmony-cli": "npm:@react-native-oh/react-native-harmony-cli@0.72.140",
31+ "@tsconfig/react-native": "^2.0.2",
32+ "@types/jest": "^29.2.1",
33+ "@types/react": "^18.0.24",
34+ "@types/react-test-renderer": "^18.0.0",
35+ "babel-jest": "^29.2.1",
36+ "eslint": "^8.19.0",
37+ "jest": "^29.2.1",
38+ "metro-config": "^0.76.3",
39+ "metro-react-native-babel-preset": "0.73.9",
40+ "prettier": "^2.4.1",
41+ "react-test-renderer": "18.2.0",
42+ "typescript": "4.8.4"
43+ },
44+ "overrides": {
45+ "deprecated-react-native-prop-types": "4.1.0"
46+ },
47+ "resolutions": {
48+ "deprecated-react-native-prop-types": "4.1.0"
49+ },
50+ "engines": {
51+ "node": ">=18"
52+ }
53+}
@@ -0,0 +1,5 @@
1+module.exports = {
2+ project: {
3+ },
4+ assets: ['./assets/fonts/'],
5+};
@@ -0,0 +1,39 @@
1+const fs = require('fs');
2+const JSON5 = require('json5');
3+const path = require('path');
4+ 
5+const templatePath = path.join(
6+ __dirname,
7+ '..',
8+ 'harmony',
9+ 'build-profile.template.json5',
10+);
11+const existingProfilePath = path.join(
12+ __dirname,
13+ '..',
14+ 'harmony',
15+ 'build-profile.json5',
16+);
17+ 
18+if (fs.existsSync(existingProfilePath)) {
19+ let existingProfile = JSON5.parse(
20+ fs.readFileSync(existingProfilePath, 'utf-8'),
21+ );
22+ let template = JSON5.parse(fs.readFileSync(templatePath, 'utf-8'));
23+ let signingConfigs =
24+ existingProfile.app && existingProfile.app.signingConfigs;
25+ 
26+ existingProfile = {...template};
27+ 
28+ if (signingConfigs) {
29+ existingProfile.app.signingConfigs = signingConfigs;
30+ }
31+ 
32+ fs.writeFileSync(
33+ existingProfilePath,
34+ JSON5.stringify(existingProfile, null, 2),
35+ );
36+} else {
37+ // File doesn't exist, create a copy from the template
38+ fs.copyFileSync(templatePath, existingProfilePath);
39+}
@@ -0,0 +1,140 @@
1+import React from 'react';
2+import {ScrollView, StyleSheet, View, Button, Text} from 'react-native';
3+import OpenFile from '@react-native-ohos/react-native-doc-viewer';
4+ 
5+interface FileInfo {
6+ url?: string;
7+ fileName?: string;
8+ fileType?: string;
9+ cache?: boolean;
10+ base64?: string;
11+}
12+ 
13+const testUrls = {
14+ pdf: 'https://filesamples.com/samples/document/pdf/sample3.pdf',
15+ mp3: 'https://filesamples.com/samples/audio/mp3/sample3.mp3',
16+ mp4: 'https://filesamples.com/samples/video/mp4/sample_960x400_ocean_with_audio.mp4',
17+ doc: 'https://filesamples.com/samples/document/doc/sample1.doc',
18+ jpeg: 'https://filesamples.com/samples/image/jpeg/sample_1280x853.jpeg',
19+ xlsx: 'https://filesamples.com/samples/document/xlsx/sample1.xlsx',
20+};
21+ 
22+const base64Png =
23+ 'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA4pOS9AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEUlEQVQoz2P8z0AZYKQWGBgYAMXeAT3H9Lh1AAAAAElFTkSuQmCC';
24+ 
25+export function DocViewerExample() {
26+ const [status, setStatus] = React.useState('idle');
27+ 
28+ const openDoc = (config: FileInfo) => {
29+ setStatus(`openDoc ${config.fileName ?? ''}`);
30+ OpenFile.openDoc([config], (err: string) => {
31+ setStatus(err ? `openDoc err: ${err}` : 'openDoc success');
32+ });
33+ };
34+ 
35+ const openDocBinaryinUrl = (config: FileInfo) => {
36+ setStatus(`openDocBinaryinUrl ${config.fileName ?? ''}`);
37+ OpenFile.openDocBinaryinUrl([config], (err: string) => {
38+ setStatus(err ? `openDocBinaryinUrl err: ${err}` : 'openDocBinaryinUrl success');
39+ });
40+ };
41+ 
42+ const openDocb64 = (config: FileInfo) => {
43+ setStatus('openDocb64');
44+ OpenFile.openDocb64([config], (err: string) => {
45+ setStatus(err ? `openDocb64 err: ${err}` : 'openDocb64 success');
46+ });
47+ };
48+ 
49+ return (
50+ <View style={styles.container}>
51+ <Text style={styles.title}>react-native-doc-viewer tester</Text>
52+ <Text style={styles.status}>status: {status}</Text>
53+ <ScrollView>
54+ <View style={styles.item}>
55+ <Button
56+ title="Open PDF with openDoc"
57+ onPress={() =>
58+ openDoc({url: testUrls.pdf, fileName: 'sample.pdf', fileType: 'pdf', cache: true})
59+ }
60+ />
61+ </View>
62+ <View style={styles.item}>
63+ <Button
64+ title="Open PDF with openDoc (no cache)"
65+ onPress={() =>
66+ openDoc({url: testUrls.pdf, fileName: 'sample.pdf', fileType: 'pdf', cache: false})
67+ }
68+ />
69+ </View>
70+ <View style={styles.item}>
71+ <Button
72+ title="Open MP4 with openDoc"
73+ onPress={() =>
74+ openDoc({url: testUrls.mp4, fileName: 'sample.mp4', fileType: 'mp4', cache: true})
75+ }
76+ />
77+ </View>
78+ <View style={styles.item}>
79+ <Button
80+ title="Open MP3 with openDoc"
81+ onPress={() =>
82+ openDoc({url: testUrls.mp3, fileName: 'sample.mp3', fileType: 'mp3', cache: true})
83+ }
84+ />
85+ </View>
86+ <View style={styles.item}>
87+ <Button
88+ title="Open DOC with openDoc"
89+ onPress={() =>
90+ openDoc({url: testUrls.doc, fileName: 'sample.doc', fileType: 'doc', cache: true})
91+ }
92+ />
93+ </View>
94+ <View style={styles.item}>
95+ <Button
96+ title="Open XLSX with openDoc"
97+ onPress={() =>
98+ openDoc({url: testUrls.xlsx, fileName: 'sample.xlsx', fileType: 'xlsx', cache: true})
99+ }
100+ />
101+ </View>
102+ <View style={styles.item}>
103+ <Button
104+ title="Open JPEG with openDocBinaryinUrl"
105+ onPress={() =>
106+ openDocBinaryinUrl({
107+ url: testUrls.jpeg,
108+ fileName: 'sample.jpeg',
109+ fileType: 'jpeg',
110+ cache: true,
111+ })
112+ }
113+ />
114+ </View>
115+ <View style={styles.item}>
116+ <Button
117+ title="Open base64 PNG with openDocb64"
118+ onPress={() =>
119+ openDocb64({
120+ base64: base64Png,
121+ fileName: 'sample.png',
122+ fileType: 'png',
123+ cache: false,
124+ })
125+ }
126+ />
127+ </View>
128+ </ScrollView>
129+ </View>
130+ );
131+}
132+ 
133+const styles = StyleSheet.create({
134+ container: {flex: 1, backgroundColor: '#fff', padding: 16},
135+ title: {fontSize: 18, fontWeight: 'bold', marginBottom: 8},
136+ status: {fontSize: 12, color: '#666', marginBottom: 12},
137+ item: {marginBottom: 12},
138+});
139+ 
140+export default DocViewerExample;
@@ -0,0 +1,14 @@
1+{
2+ "extends": "@react-native/typescript-config/tsconfig.json",
3+ "compilerOptions": {
4+ "jsx": "react-native",
5+ "paths": {
6+ "react-native": [
7+ "./node_modules/react-native-harmony"
8+ ],
9+ },
10+ },
11+ "exclude": [
12+ "harmony"
13+ ]
14+}
@@ -1,6 +1,6 @@
1{1{
2 "name": "@react-native-ohos/react-native-doc-viewer",2 "name": "@react-native-ohos/react-native-doc-viewer",
3- "version": "2.7.9",3+ "version": "2.7.10-beta.1",
4 type: 'module',4 type: 'module',
5 dependencies: {5 dependencies: {
6 "@rnoh/react-native-openharmony": 'file:../react_native_openharmony'6 "@rnoh/react-native-openharmony": 'file:../react_native_openharmony'
@@ -87,6 +87,6 @@ const mimeMap = {
87}87}
88 88 
89export function getMimeType(fileType: string) {89export function getMimeType(fileType: string) {
90- fileType = fileType.toLowerCase()90+ fileType = typeof fileType === 'string' ? fileType.toLowerCase() : ''
91 return mimeMap[fileType] || mimeMap['pdf']91 return mimeMap[fileType] || mimeMap['pdf']
92}92}
@@ -58,6 +58,10 @@ export class DocViewTurboModule extends TurboModule {
58 if (base64 && fileName && fileType) {58 if (base64 && fileName && fileType) {
59 try {59 try {
60 const filePath = this.getFilePath(fileName)60 const filePath = this.getFilePath(fileName)
61+ if (!filePath) {
62+ callback(`invalid fileName:${fileName}`)
63+ return
64+ }
61 if (cache) {65 if (cache) {
62 Log.debug(`try to use cache base64 file`)66 Log.debug(`try to use cache base64 file`)
63 this.useCache(fileType, '', fileName, callback, async () => {67 this.useCache(fileType, '', fileName, callback, async () => {
@@ -111,23 +115,27 @@ export class DocViewTurboModule extends TurboModule {
111 }115 }
112 }116 }
113 getFilePath(fileName: string, url?: string) {117 getFilePath(fileName: string, url?: string) {
114- const context = this.ctx.uiAbilityContext118+ let name = fileName ?? ''
115- let filedDir = this.tempDir119+ if (!name && url) {
116- if (fileName) {120+ name = url.split('/').pop() ?? ''
117- return `${filedDir}/${fileName}`
118 }121 }
119- if (url) {122+ name = name.split('?')[0].split('#')[0]
120- const urlSplit = url?.split('/')123+ name = name.split('/').pop() ?? ''
121- const name = urlSplit[urlSplit.length - 1]124+ name = name.split('\\').pop() ?? ''
122- Log.debug(`getFilePath name:${name}`)125+ if (!name || name === '.' || name === '..') {
123- const filePath = filedDir + `/${name}`126+ Log.debug(`getFilePath invalid fileName:${JSON.stringify(fileName)}, url:${url}`)
124- return filePath127+ return ''
125 }128 }
126- return ''129+ Log.debug(`getFilePath name:${name}`)
130+ return `${this.tempDir}/${name}`
127 }131 }
128 async useCache(fileType: string, url: string, fileName: string, callback: Function, notExistsFn?: Function) {132 async useCache(fileType: string, url: string, fileName: string, callback: Function, notExistsFn?: Function) {
129 Log.debug(`useCache start`)133 Log.debug(`useCache start`)
130 const filePath = this.getFilePath(fileName, url)134 const filePath = this.getFilePath(fileName, url)
135+ if (!filePath) {
136+ callback(`invalid fileName:${fileName}`)
137+ return
138+ }
131 const isExists = await fs.access(filePath)139 const isExists = await fs.access(filePath)
132 if (isExists) {140 if (isExists) {
133 Log.debug(`useCache isExists:${filePath}`)141 Log.debug(`useCache isExists:${filePath}`)
@@ -152,43 +160,62 @@ export class DocViewTurboModule extends TurboModule {
152 Log.debug(`removeFile err:${JSON.stringify(err)}`)160 Log.debug(`removeFile err:${JSON.stringify(err)}`)
153 }161 }
154 }162 }
163+ normalizeUrl(url: string): string {
164+ const idx = url.indexOf('://');
165+ if (idx > 0) {
166+ return `${url.substring(0, idx).toLowerCase()}://${url.substring(idx + 3)}`;
167+ }
168+ return url;
169+ }
155 async download(url: string, fileType: string, fileName: string, callback: Function) {170 async download(url: string, fileType: string, fileName: string, callback: Function) {
156- Log.debug(`download start url:${url}`)171+ url = this.normalizeUrl(url);
157- const filePath = this.getFilePath(fileName, url)172+ Log.debug(`download start url:${url}`);
158- this.removeFile(filePath)173+ const filePath = this.getFilePath(fileName, url);
159- const context = this.ctx.uiAbilityContext174+ if (!filePath) {
175+ callback(`invalid fileName:${fileName}`);
176+ return;
177+ }
178+ await this.removeFile(filePath);
179+ const context = this.ctx.uiAbilityContext;
160 try {180 try {
161- request.downloadFile(context, {181+ const downloadTask = await request.downloadFile(context, {
162 url,182 url,
163 filePath183 filePath
164- }).then(downloadTask => {184+ });
165- Log.debug(`downloadTask start`)185+ Log.debug(`downloadTask start`);
166- downloadTask.on('complete', () => {186+ this.watchDownloadTask(downloadTask, filePath, fileType, fileName, callback);
167- Log.debug(`download complete:${fileName}`)
168- this.shareFile(filePath, fileType, callback)
169- })
170- downloadTask.on('fail', () => {
171- Log.debug(`download fail:${fileName}`)
172- this.removeFile(filePath)
173- callback(`download fail`)
174- })
175- }).catch(err => {
176- Log.debug(`Invoke catch downloadTask failed:${JSON.stringify(err)}`)
177- })
178 } catch (err) {187 } catch (err) {
179- Log.debug(`Invoke catch downloadTask failed:${JSON.stringify(err)}`)188+ Log.debug(`Invoke catch downloadTask failed:${JSON.stringify(err)}`);
180 if (err.code === 13400002) {189 if (err.code === 13400002) {
181- Log.debug(`file is exists:${fileName}`)190+ Log.debug(`file is exists:${fileName}`);
182- this.shareFile(filePath, fileType, callback)191+ this.shareFile(filePath, fileType, callback);
183 } else {192 } else {
184- callback(`download fail`)193+ callback(`download fail`);
185 }194 }
186 }195 }
187 }196 }
197+ 
198+ watchDownloadTask(downloadTask: request.DownloadTask, filePath: string, fileType: string, fileName: string, callback: Function) {
199+ downloadTask.on('complete', () => {
200+ Log.debug(`download complete:${fileName}`);
201+ this.shareFile(filePath, fileType, callback);
202+ });
203+ downloadTask.on('fail', (err: number) => {
204+ Log.debug(`download fail:${fileName}, code:${err}`);
205+ this.removeFile(filePath);
206+ callback(`download fail, code:${err}`);
207+ });
208+ }
209+ 
188 shareFile(filePath: string, fileType: string, callback: Function) {210 shareFile(filePath: string, fileType: string, callback: Function) {
189- const uri = fileUri.getUriFromPath(filePath)211+ try {
190- Log.debug(`shareFile uri: ${uri}, filePath: ${filePath}`)212+ const uri = fileUri.getUriFromPath(filePath)
191- this.start(uri, fileType, callback)213+ Log.debug(`shareFile uri: ${uri}, filePath: ${filePath}`)
214+ this.start(uri, fileType, callback)
215+ } catch (e) {
216+ Log.debug(`shareFile err:${JSON.stringify(e)}`)
217+ callback(`shareFile err:${JSON.stringify(e)}`)
218+ }
192 }219 }
193 start(uri: string, fileType: string, callback: Function) {220 start(uri: string, fileType: string, callback: Function) {
194 const mimeType = getMimeType(fileType)221 const mimeType = getMimeType(fileType)
Binary files do not support preview
@@ -1,6 +1,6 @@
1{1{
2 "name": "@react-native-ohos/react-native-doc-viewer",2 "name": "@react-native-ohos/react-native-doc-viewer",
3- "version": "2.7.9",3+ "version": "2.7.10-beta.1",
4 "description": "React Native Native Module Bridge Quicklock Document Viewer for IOS + Android supports pdf, png, jpg, xls, ppt, doc, docx, pptx, xlx + Video Player mp4 supported ",4 "description": "React Native Native Module Bridge Quicklock Document Viewer for IOS + Android supports pdf, png, jpg, xls, ppt, doc, docx, pptx, xlx + Video Player mp4 supported ",
5 "main": "lib/commonjs/index",5 "main": "lib/commonjs/index",
6 "scripts": {6 "scripts": {