createViewManagers(@NonNull ReactApplicationContext reactContext) {
26 | return Collections.emptyList();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/example/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/example/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native-community',
4 | parser: '@typescript-eslint/parser',
5 | plugins: ['@typescript-eslint'],
6 | overrides: [
7 | {
8 | files: ['*.ts', '*.tsx'],
9 | rules: {
10 | '@typescript-eslint/no-shadow': ['error'],
11 | 'no-shadow': 'off',
12 | 'no-undef': 'off',
13 | },
14 | },
15 | ],
16 | };
17 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 |
24 | # Android/IntelliJ
25 | #
26 | build/
27 | .idea
28 | .gradle
29 | local.properties
30 | *.iml
31 | *.hprof
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 | !debug.keystore
44 |
45 | # fastlane
46 | #
47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48 | # screenshots whenever they are needed.
49 | # For more information about the recommended setup visit:
50 | # https://docs.fastlane.tools/best-practices/source-control/
51 |
52 | */fastlane/report.xml
53 | */fastlane/Preview.html
54 | */fastlane/screenshots
55 |
56 | # Bundle artifact
57 | *.jsbundle
58 |
59 | # Ruby / CocoaPods
60 | /ios/Pods/
61 | /vendor/bundle/
62 |
--------------------------------------------------------------------------------
/example/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/example/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby '2.7.4'
5 |
6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2'
7 |
--------------------------------------------------------------------------------
/example/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.5)
5 | rexml
6 | activesupport (6.1.5)
7 | concurrent-ruby (~> 1.0, >= 1.0.2)
8 | i18n (>= 1.6, < 2)
9 | minitest (>= 5.1)
10 | tzinfo (~> 2.0)
11 | zeitwerk (~> 2.3)
12 | addressable (2.8.0)
13 | public_suffix (>= 2.0.2, < 5.0)
14 | algoliasearch (1.27.5)
15 | httpclient (~> 2.8, >= 2.8.3)
16 | json (>= 1.5.1)
17 | atomos (0.1.3)
18 | claide (1.1.0)
19 | cocoapods (1.11.3)
20 | addressable (~> 2.8)
21 | claide (>= 1.0.2, < 2.0)
22 | cocoapods-core (= 1.11.3)
23 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
24 | cocoapods-downloader (>= 1.4.0, < 2.0)
25 | cocoapods-plugins (>= 1.0.0, < 2.0)
26 | cocoapods-search (>= 1.0.0, < 2.0)
27 | cocoapods-trunk (>= 1.4.0, < 2.0)
28 | cocoapods-try (>= 1.1.0, < 2.0)
29 | colored2 (~> 3.1)
30 | escape (~> 0.0.4)
31 | fourflusher (>= 2.3.0, < 3.0)
32 | gh_inspector (~> 1.0)
33 | molinillo (~> 0.8.0)
34 | nap (~> 1.0)
35 | ruby-macho (>= 1.0, < 3.0)
36 | xcodeproj (>= 1.21.0, < 2.0)
37 | cocoapods-core (1.11.3)
38 | activesupport (>= 5.0, < 7)
39 | addressable (~> 2.8)
40 | algoliasearch (~> 1.0)
41 | concurrent-ruby (~> 1.1)
42 | fuzzy_match (~> 2.0.4)
43 | nap (~> 1.0)
44 | netrc (~> 0.11)
45 | public_suffix (~> 4.0)
46 | typhoeus (~> 1.0)
47 | cocoapods-deintegrate (1.0.5)
48 | cocoapods-downloader (1.6.3)
49 | cocoapods-plugins (1.0.0)
50 | nap
51 | cocoapods-search (1.0.1)
52 | cocoapods-trunk (1.6.0)
53 | nap (>= 0.8, < 2.0)
54 | netrc (~> 0.11)
55 | cocoapods-try (1.2.0)
56 | colored2 (3.1.2)
57 | concurrent-ruby (1.1.10)
58 | escape (0.0.4)
59 | ethon (0.15.0)
60 | ffi (>= 1.15.0)
61 | ffi (1.15.5)
62 | fourflusher (2.3.1)
63 | fuzzy_match (2.0.4)
64 | gh_inspector (1.1.3)
65 | httpclient (2.8.3)
66 | i18n (1.10.0)
67 | concurrent-ruby (~> 1.0)
68 | json (2.6.1)
69 | minitest (5.15.0)
70 | molinillo (0.8.0)
71 | nanaimo (0.3.0)
72 | nap (1.1.0)
73 | netrc (0.11.0)
74 | public_suffix (4.0.7)
75 | rexml (3.2.5)
76 | ruby-macho (2.5.1)
77 | typhoeus (1.4.0)
78 | ethon (>= 0.9.0)
79 | tzinfo (2.0.4)
80 | concurrent-ruby (~> 1.0)
81 | xcodeproj (1.21.0)
82 | CFPropertyList (>= 2.3.3, < 4.0)
83 | atomos (~> 0.1.3)
84 | claide (>= 1.0.2, < 2.0)
85 | colored2 (~> 3.1)
86 | nanaimo (~> 0.3.0)
87 | rexml (~> 3.2.4)
88 | zeitwerk (2.5.4)
89 |
90 | PLATFORMS
91 | ruby
92 |
93 | DEPENDENCIES
94 | cocoapods (~> 1.11, >= 1.11.2)
95 |
96 | RUBY VERSION
97 | ruby 2.7.4p191
98 |
99 | BUNDLED WITH
100 | 2.2.27
101 |
--------------------------------------------------------------------------------
/example/__tests__/App-test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../src/App';
8 |
9 | // Note: test renderer must be required after react-native.
10 | import renderer from 'react-test-renderer';
11 |
12 | it('renders correctly', () => {
13 | renderer.create( );
14 | });
15 |
--------------------------------------------------------------------------------
/example/_bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/example/_ruby-version:
--------------------------------------------------------------------------------
1 | 2.7.4
2 |
--------------------------------------------------------------------------------
/example/android/app/_BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 |
17 | create_jar_targets(glob(["libs/*.jar"]))
18 |
19 | android_library(
20 | name = "all-libs",
21 | exported_deps = lib_deps,
22 | )
23 |
24 | android_library(
25 | name = "app-code",
26 | srcs = glob([
27 | "src/main/java/**/*.java",
28 | ]),
29 | deps = [
30 | ":all-libs",
31 | ":build_config",
32 | ":res",
33 | ],
34 | )
35 |
36 | android_build_config(
37 | name = "build_config",
38 | package = "com.toolkitexample",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.toolkitexample",
44 | res = "src/main/res",
45 | )
46 |
47 | android_binary(
48 | name = "app",
49 | keystore = "//android/keystores:debug",
50 | manifest = "src/main/AndroidManifest.xml",
51 | package_type = "debug",
52 | deps = [
53 | ":app-code",
54 | ],
55 | )
56 |
--------------------------------------------------------------------------------
/example/android/app/build_defs.bzl:
--------------------------------------------------------------------------------
1 | """Helper definitions to glob .aar and .jar targets"""
2 |
3 | def create_aar_targets(aarfiles):
4 | for aarfile in aarfiles:
5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
6 | lib_deps.append(":" + name)
7 | android_prebuilt_aar(
8 | name = name,
9 | aar = aarfile,
10 | )
11 |
12 | def create_jar_targets(jarfiles):
13 | for jarfile in jarfiles:
14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
15 | lib_deps.append(":" + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
--------------------------------------------------------------------------------
/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/com/toolkitexample/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.toolkitexample;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
22 | import com.facebook.react.ReactInstanceEventListener;
23 | import com.facebook.react.ReactInstanceManager;
24 | import com.facebook.react.bridge.ReactContext;
25 | import com.facebook.react.modules.network.NetworkingModule;
26 | import okhttp3.OkHttpClient;
27 |
28 | public class ReactNativeFlipper {
29 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
30 | if (FlipperUtils.shouldEnableFlipper(context)) {
31 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
32 |
33 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
34 | client.addPlugin(new ReactFlipperPlugin());
35 | client.addPlugin(new DatabasesFlipperPlugin(context));
36 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
37 | client.addPlugin(CrashReporterPlugin.getInstance());
38 |
39 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
40 | NetworkingModule.setCustomClientBuilder(
41 | new NetworkingModule.CustomClientBuilder() {
42 | @Override
43 | public void apply(OkHttpClient.Builder builder) {
44 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
45 | }
46 | });
47 | client.addPlugin(networkFlipperPlugin);
48 | client.start();
49 |
50 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
51 | // Hence we run if after all native modules have been initialized
52 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
53 | if (reactContext == null) {
54 | reactInstanceManager.addReactInstanceEventListener(
55 | new ReactInstanceEventListener() {
56 | @Override
57 | public void onReactContextInitialized(ReactContext reactContext) {
58 | reactInstanceManager.removeReactInstanceEventListener(this);
59 | reactContext.runOnNativeModulesQueueThread(
60 | new Runnable() {
61 | @Override
62 | public void run() {
63 | client.addPlugin(new FrescoFlipperPlugin());
64 | }
65 | });
66 | }
67 | });
68 | } else {
69 | client.addPlugin(new FrescoFlipperPlugin());
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/toolkitexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.toolkitexample;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.ReactRootView;
6 |
7 | public class MainActivity extends ReactActivity {
8 |
9 | /**
10 | * Returns the name of the main component registered from JavaScript. This is used to schedule
11 | * rendering of the component.
12 | */
13 | @Override
14 | protected String getMainComponentName() {
15 | return "ToolkitExample";
16 | }
17 |
18 | /**
19 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
20 | * you can specify the rendered you wish to use (Fabric or the older renderer).
21 | */
22 | @Override
23 | protected ReactActivityDelegate createReactActivityDelegate() {
24 | return new MainActivityDelegate(this, getMainComponentName());
25 | }
26 |
27 | public static class MainActivityDelegate extends ReactActivityDelegate {
28 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
29 | super(activity, mainComponentName);
30 | }
31 |
32 | @Override
33 | protected ReactRootView createRootView() {
34 | ReactRootView reactRootView = new ReactRootView(getContext());
35 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
36 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
37 | return reactRootView;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/toolkitexample/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.toolkitexample;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import com.facebook.react.PackageList;
6 | import com.facebook.react.ReactApplication;
7 | import com.facebook.react.ReactInstanceManager;
8 | import com.facebook.react.ReactNativeHost;
9 | import com.facebook.react.ReactPackage;
10 | import com.facebook.react.config.ReactFeatureFlags;
11 | import com.facebook.soloader.SoLoader;
12 | import com.toolkitexample.newarchitecture.MainApplicationReactNativeHost;
13 | import java.lang.reflect.InvocationTargetException;
14 | import java.util.List;
15 |
16 | public class MainApplication extends Application implements ReactApplication {
17 |
18 | private final ReactNativeHost mReactNativeHost =
19 | new ReactNativeHost(this) {
20 | @Override
21 | public boolean getUseDeveloperSupport() {
22 | return BuildConfig.DEBUG;
23 | }
24 |
25 | @Override
26 | protected List getPackages() {
27 | @SuppressWarnings("UnnecessaryLocalVariable")
28 | List packages = new PackageList(this).getPackages();
29 | // Packages that cannot be autolinked yet can be added manually here, for example:
30 | // packages.add(new MyReactNativePackage());
31 | return packages;
32 | }
33 |
34 | @Override
35 | protected String getJSMainModuleName() {
36 | return "index";
37 | }
38 | };
39 |
40 | private final ReactNativeHost mNewArchitectureNativeHost =
41 | new MainApplicationReactNativeHost(this);
42 |
43 | @Override
44 | public ReactNativeHost getReactNativeHost() {
45 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
46 | return mNewArchitectureNativeHost;
47 | } else {
48 | return mReactNativeHost;
49 | }
50 | }
51 |
52 | @Override
53 | public void onCreate() {
54 | super.onCreate();
55 | // If you opted-in for the New Architecture, we enable the TurboModule system
56 | ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
57 | SoLoader.init(this, /* native exopackage */ false);
58 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
59 | }
60 |
61 | /**
62 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like
63 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
64 | *
65 | * @param context
66 | * @param reactInstanceManager
67 | */
68 | private static void initializeFlipper(
69 | Context context, ReactInstanceManager reactInstanceManager) {
70 | if (BuildConfig.DEBUG) {
71 | try {
72 | /*
73 | We use reflection here to pick up the class that initializes Flipper,
74 | since Flipper library is not available in release mode
75 | */
76 | Class> aClass = Class.forName("com.toolkitexample.ReactNativeFlipper");
77 | aClass
78 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
79 | .invoke(null, context, reactInstanceManager);
80 | } catch (ClassNotFoundException e) {
81 | e.printStackTrace();
82 | } catch (NoSuchMethodException e) {
83 | e.printStackTrace();
84 | } catch (IllegalAccessException e) {
85 | e.printStackTrace();
86 | } catch (InvocationTargetException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/toolkitexample/newarchitecture/MainApplicationReactNativeHost.java:
--------------------------------------------------------------------------------
1 | package com.toolkitexample.newarchitecture;
2 |
3 | import android.app.Application;
4 | import androidx.annotation.NonNull;
5 | import com.facebook.react.PackageList;
6 | import com.facebook.react.ReactInstanceManager;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
10 | import com.facebook.react.bridge.JSIModulePackage;
11 | import com.facebook.react.bridge.JSIModuleProvider;
12 | import com.facebook.react.bridge.JSIModuleSpec;
13 | import com.facebook.react.bridge.JSIModuleType;
14 | import com.facebook.react.bridge.JavaScriptContextHolder;
15 | import com.facebook.react.bridge.ReactApplicationContext;
16 | import com.facebook.react.bridge.UIManager;
17 | import com.facebook.react.fabric.ComponentFactory;
18 | import com.facebook.react.fabric.CoreComponentsRegistry;
19 | import com.facebook.react.fabric.EmptyReactNativeConfig;
20 | import com.facebook.react.fabric.FabricJSIModuleProvider;
21 | import com.facebook.react.uimanager.ViewManagerRegistry;
22 | import com.toolkitexample.BuildConfig;
23 | import com.toolkitexample.newarchitecture.components.MainComponentsRegistry;
24 | import com.toolkitexample.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
30 | * TurboModule delegates and the Fabric Renderer.
31 | *
32 | * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
33 | * `newArchEnabled` property). Is ignored otherwise.
34 | */
35 | public class MainApplicationReactNativeHost extends ReactNativeHost {
36 | public MainApplicationReactNativeHost(Application application) {
37 | super(application);
38 | }
39 |
40 | @Override
41 | public boolean getUseDeveloperSupport() {
42 | return BuildConfig.DEBUG;
43 | }
44 |
45 | @Override
46 | protected List getPackages() {
47 | List packages = new PackageList(this).getPackages();
48 | // Packages that cannot be autolinked yet can be added manually here, for example:
49 | // packages.add(new MyReactNativePackage());
50 | // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
51 | // packages.add(new TurboReactPackage() { ... });
52 | // If you have custom Fabric Components, their ViewManagers should also be loaded here
53 | // inside a ReactPackage.
54 | return packages;
55 | }
56 |
57 | @Override
58 | protected String getJSMainModuleName() {
59 | return "index";
60 | }
61 |
62 | @NonNull
63 | @Override
64 | protected ReactPackageTurboModuleManagerDelegate.Builder
65 | getReactPackageTurboModuleManagerDelegateBuilder() {
66 | // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
67 | // for the new architecture and to use TurboModules correctly.
68 | return new MainApplicationTurboModuleManagerDelegate.Builder();
69 | }
70 |
71 | @Override
72 | protected JSIModulePackage getJSIModulePackage() {
73 | return new JSIModulePackage() {
74 | @Override
75 | public List getJSIModules(
76 | final ReactApplicationContext reactApplicationContext,
77 | final JavaScriptContextHolder jsContext) {
78 | final List specs = new ArrayList<>();
79 |
80 | // Here we provide a new JSIModuleSpec that will be responsible of providing the
81 | // custom Fabric Components.
82 | specs.add(
83 | new JSIModuleSpec() {
84 | @Override
85 | public JSIModuleType getJSIModuleType() {
86 | return JSIModuleType.UIManager;
87 | }
88 |
89 | @Override
90 | public JSIModuleProvider getJSIModuleProvider() {
91 | final ComponentFactory componentFactory = new ComponentFactory();
92 | CoreComponentsRegistry.register(componentFactory);
93 |
94 | // Here we register a Components Registry.
95 | // The one that is generated with the template contains no components
96 | // and just provides you the one from React Native core.
97 | MainComponentsRegistry.register(componentFactory);
98 |
99 | final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
100 |
101 | ViewManagerRegistry viewManagerRegistry =
102 | new ViewManagerRegistry(
103 | reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
104 |
105 | return new FabricJSIModuleProvider(
106 | reactApplicationContext,
107 | componentFactory,
108 | new EmptyReactNativeConfig(),
109 | viewManagerRegistry);
110 | }
111 | });
112 | return specs;
113 | }
114 | };
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/toolkitexample/newarchitecture/components/MainComponentsRegistry.java:
--------------------------------------------------------------------------------
1 | package com.toolkitexample.newarchitecture.components;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.proguard.annotations.DoNotStrip;
5 | import com.facebook.react.fabric.ComponentFactory;
6 | import com.facebook.soloader.SoLoader;
7 |
8 | /**
9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a
10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
11 | * folder for you).
12 | *
13 | * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
14 | * `newArchEnabled` property). Is ignored otherwise.
15 | */
16 | @DoNotStrip
17 | public class MainComponentsRegistry {
18 | static {
19 | SoLoader.loadLibrary("fabricjni");
20 | }
21 |
22 | @DoNotStrip private final HybridData mHybridData;
23 |
24 | @DoNotStrip
25 | private native HybridData initHybrid(ComponentFactory componentFactory);
26 |
27 | @DoNotStrip
28 | private MainComponentsRegistry(ComponentFactory componentFactory) {
29 | mHybridData = initHybrid(componentFactory);
30 | }
31 |
32 | @DoNotStrip
33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) {
34 | return new MainComponentsRegistry(componentFactory);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/toolkitexample/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java:
--------------------------------------------------------------------------------
1 | package com.toolkitexample.newarchitecture.modules;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.soloader.SoLoader;
8 | import java.util.List;
9 |
10 | /**
11 | * Class responsible to load the TurboModules. This class has native methods and needs a
12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
13 | * folder for you).
14 | *
15 | *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
16 | * `newArchEnabled` property). Is ignored otherwise.
17 | */
18 | public class MainApplicationTurboModuleManagerDelegate
19 | extends ReactPackageTurboModuleManagerDelegate {
20 |
21 | private static volatile boolean sIsSoLibraryLoaded;
22 |
23 | protected MainApplicationTurboModuleManagerDelegate(
24 | ReactApplicationContext reactApplicationContext, List packages) {
25 | super(reactApplicationContext, packages);
26 | }
27 |
28 | protected native HybridData initHybrid();
29 |
30 | native boolean canCreateTurboModule(String moduleName);
31 |
32 | public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
33 | protected MainApplicationTurboModuleManagerDelegate build(
34 | ReactApplicationContext context, List packages) {
35 | return new MainApplicationTurboModuleManagerDelegate(context, packages);
36 | }
37 | }
38 |
39 | @Override
40 | protected synchronized void maybeLoadOtherSoLibraries() {
41 | if (!sIsSoLibraryLoaded) {
42 | // If you change the name of your application .so file in the Android.mk file,
43 | // make sure you update the name here as well.
44 | SoLoader.loadLibrary("toolkitexample_appmodules");
45 | sIsSoLibraryLoaded = true;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | THIS_DIR := $(call my-dir)
2 |
3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
4 |
5 | # If you wish to add a custom TurboModule or Fabric component in your app you
6 | # will have to include the following autogenerated makefile.
7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
8 | include $(CLEAR_VARS)
9 |
10 | LOCAL_PATH := $(THIS_DIR)
11 |
12 | # You can customize the name of your application .so file here.
13 | LOCAL_MODULE := toolkitexample_appmodules
14 |
15 | LOCAL_C_INCLUDES := $(LOCAL_PATH)
16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
18 |
19 | # If you wish to add a custom TurboModule or Fabric component in your app you
20 | # will have to uncomment those lines to include the generated source
21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
22 | #
23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
26 |
27 | # Here you should add any native library you wish to depend on.
28 | LOCAL_SHARED_LIBRARIES := \
29 | libfabricjni \
30 | libfbjni \
31 | libfolly_futures \
32 | libfolly_json \
33 | libglog \
34 | libjsi \
35 | libreact_codegen_rncore \
36 | libreact_debug \
37 | libreact_nativemodule_core \
38 | libreact_render_componentregistry \
39 | libreact_render_core \
40 | libreact_render_debug \
41 | libreact_render_graphics \
42 | librrc_view \
43 | libruntimeexecutor \
44 | libturbomodulejsijni \
45 | libyoga
46 |
47 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
48 |
49 | include $(BUILD_SHARED_LIBRARY)
50 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainApplicationModuleProvider.cpp:
--------------------------------------------------------------------------------
1 | #include "MainApplicationModuleProvider.h"
2 |
3 | #include
4 |
5 | namespace facebook {
6 | namespace react {
7 |
8 | std::shared_ptr MainApplicationModuleProvider(
9 | const std::string moduleName,
10 | const JavaTurboModule::InitParams ¶ms) {
11 | // Here you can provide your own module provider for TurboModules coming from
12 | // either your application or from external libraries. The approach to follow
13 | // is similar to the following (for a library called `samplelibrary`:
14 | //
15 | // auto module = samplelibrary_ModuleProvider(moduleName, params);
16 | // if (module != nullptr) {
17 | // return module;
18 | // }
19 | // return rncore_ModuleProvider(moduleName, params);
20 | return rncore_ModuleProvider(moduleName, params);
21 | }
22 |
23 | } // namespace react
24 | } // namespace facebook
25 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainApplicationModuleProvider.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 |
8 | namespace facebook {
9 | namespace react {
10 |
11 | std::shared_ptr MainApplicationModuleProvider(
12 | const std::string moduleName,
13 | const JavaTurboModule::InitParams ¶ms);
14 |
15 | } // namespace react
16 | } // namespace facebook
17 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp:
--------------------------------------------------------------------------------
1 | #include "MainApplicationTurboModuleManagerDelegate.h"
2 | #include "MainApplicationModuleProvider.h"
3 |
4 | namespace facebook {
5 | namespace react {
6 |
7 | jni::local_ref
8 | MainApplicationTurboModuleManagerDelegate::initHybrid(
9 | jni::alias_ref) {
10 | return makeCxxInstance();
11 | }
12 |
13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() {
14 | registerHybrid({
15 | makeNativeMethod(
16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
17 | makeNativeMethod(
18 | "canCreateTurboModule",
19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
20 | });
21 | }
22 |
23 | std::shared_ptr
24 | MainApplicationTurboModuleManagerDelegate::getTurboModule(
25 | const std::string name,
26 | const std::shared_ptr jsInvoker) {
27 | // Not implemented yet: provide pure-C++ NativeModules here.
28 | return nullptr;
29 | }
30 |
31 | std::shared_ptr
32 | MainApplicationTurboModuleManagerDelegate::getTurboModule(
33 | const std::string name,
34 | const JavaTurboModule::InitParams ¶ms) {
35 | return MainApplicationModuleProvider(name, params);
36 | }
37 |
38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
39 | std::string name) {
40 | return getTurboModule(name, nullptr) != nullptr ||
41 | getTurboModule(name, {.moduleName = name}) != nullptr;
42 | }
43 |
44 | } // namespace react
45 | } // namespace facebook
46 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | namespace facebook {
8 | namespace react {
9 |
10 | class MainApplicationTurboModuleManagerDelegate
11 | : public jni::HybridClass<
12 | MainApplicationTurboModuleManagerDelegate,
13 | TurboModuleManagerDelegate> {
14 | public:
15 | // Adapt it to the package you used for your Java class.
16 | static constexpr auto kJavaDescriptor =
17 | "Lcom/toolkitexample/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
18 |
19 | static jni::local_ref initHybrid(jni::alias_ref);
20 |
21 | static void registerNatives();
22 |
23 | std::shared_ptr getTurboModule(
24 | const std::string name,
25 | const std::shared_ptr jsInvoker) override;
26 | std::shared_ptr getTurboModule(
27 | const std::string name,
28 | const JavaTurboModule::InitParams ¶ms) override;
29 |
30 | /**
31 | * Test-only method. Allows user to verify whether a TurboModule can be
32 | * created by instances of this class.
33 | */
34 | bool canCreateTurboModule(std::string name);
35 | };
36 |
37 | } // namespace react
38 | } // namespace facebook
39 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainComponentsRegistry.cpp:
--------------------------------------------------------------------------------
1 | #include "MainComponentsRegistry.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace facebook {
9 | namespace react {
10 |
11 | MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
12 |
13 | std::shared_ptr
14 | MainComponentsRegistry::sharedProviderRegistry() {
15 | auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
16 |
17 | // Custom Fabric Components go here. You can register custom
18 | // components coming from your App or from 3rd party libraries here.
19 | //
20 | // providerRegistry->add(concreteComponentDescriptorProvider<
21 | // AocViewerComponentDescriptor>());
22 | return providerRegistry;
23 | }
24 |
25 | jni::local_ref
26 | MainComponentsRegistry::initHybrid(
27 | jni::alias_ref,
28 | ComponentFactory *delegate) {
29 | auto instance = makeCxxInstance(delegate);
30 |
31 | auto buildRegistryFunction =
32 | [](EventDispatcher::Weak const &eventDispatcher,
33 | ContextContainer::Shared const &contextContainer)
34 | -> ComponentDescriptorRegistry::Shared {
35 | auto registry = MainComponentsRegistry::sharedProviderRegistry()
36 | ->createComponentDescriptorRegistry(
37 | {eventDispatcher, contextContainer});
38 |
39 | auto mutableRegistry =
40 | std::const_pointer_cast(registry);
41 |
42 | mutableRegistry->setFallbackComponentDescriptor(
43 | std::make_shared(
44 | ComponentDescriptorParameters{
45 | eventDispatcher, contextContainer, nullptr}));
46 |
47 | return registry;
48 | };
49 |
50 | delegate->buildRegistryFunction = buildRegistryFunction;
51 | return instance;
52 | }
53 |
54 | void MainComponentsRegistry::registerNatives() {
55 | registerHybrid({
56 | makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
57 | });
58 | }
59 |
60 | } // namespace react
61 | } // namespace facebook
62 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/MainComponentsRegistry.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace facebook {
9 | namespace react {
10 |
11 | class MainComponentsRegistry
12 | : public facebook::jni::HybridClass {
13 | public:
14 | // Adapt it to the package you used for your Java class.
15 | constexpr static auto kJavaDescriptor =
16 | "Lcom/toolkitexample/newarchitecture/components/MainComponentsRegistry;";
17 |
18 | static void registerNatives();
19 |
20 | MainComponentsRegistry(ComponentFactory *delegate);
21 |
22 | private:
23 | static std::shared_ptr
24 | sharedProviderRegistry();
25 |
26 | static jni::local_ref initHybrid(
27 | jni::alias_ref,
28 | ComponentFactory *delegate);
29 | };
30 |
31 | } // namespace react
32 | } // namespace facebook
33 |
--------------------------------------------------------------------------------
/example/android/app/src/main/jni/OnLoad.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "MainApplicationTurboModuleManagerDelegate.h"
3 | #include "MainComponentsRegistry.h"
4 |
5 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
6 | return facebook::jni::initialize(vm, [] {
7 | facebook::react::MainApplicationTurboModuleManagerDelegate::
8 | registerNatives();
9 | facebook::react::MainComponentsRegistry::registerNatives();
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ToolkitExample
3 |
4 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | import org.apache.tools.ant.taskdefs.condition.Os
2 |
3 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
4 |
5 | buildscript {
6 | ext {
7 | buildToolsVersion = "31.0.0"
8 | minSdkVersion = 21
9 | compileSdkVersion = 31
10 | targetSdkVersion = 31
11 |
12 | if (System.properties['os.arch'] == "aarch64") {
13 | // For M1 Users we need to use the NDK 24 which added support for aarch64
14 | ndkVersion = "24.0.8215888"
15 | } else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
16 | // For Android Users, we need to use NDK 23, otherwise the build will
17 | // fail due to paths longer than the OS limit
18 | ndkVersion = "23.1.7779620"
19 | } else {
20 | // Otherwise we default to the side-by-side NDK version from AGP.
21 | ndkVersion = "21.4.7075529"
22 | }
23 | }
24 | repositories {
25 | google()
26 | mavenCentral()
27 | }
28 | dependencies {
29 | classpath("com.android.tools.build:gradle:7.0.4")
30 | classpath("com.facebook.react:react-native-gradle-plugin")
31 | classpath("de.undercouch:gradle-download-task:4.1.2")
32 | // NOTE: Do not place your application dependencies here; they belong
33 | // in the individual module build.gradle files
34 | }
35 | }
36 |
37 | allprojects {
38 | repositories {
39 | maven {
40 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
41 | url("$rootDir/../node_modules/react-native/android")
42 | }
43 | maven {
44 | // Android JSC is installed from npm
45 | url("$rootDir/../node_modules/jsc-android/dist")
46 | }
47 | mavenCentral {
48 | // We don't want to fetch react-native from Maven Central as there are
49 | // older versions over there.
50 | content {
51 | excludeGroup "com.facebook.react"
52 | }
53 | }
54 | google()
55 | maven { url 'https://www.jitpack.io' }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Version of flipper SDK to use with React Native
28 | FLIPPER_VERSION=0.125.0
29 |
30 | # Use this property to specify which architecture you want to build.
31 | # You can also override it from the CLI using
32 | # ./gradlew -PreactNativeArchitectures=x86_64
33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
34 |
35 | # Use this property to enable support to the new architecture.
36 | # This will allow you to use TurboModules and the Fabric render in
37 | # your application. You should enable this flag either if you want
38 | # to write custom TurboModules/Fabric components OR use libraries that
39 | # are providing them.
40 | newArchEnabled=false
41 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Use "xargs" to parse quoted args.
209 | #
210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
211 | #
212 | # In Bash we could simply go:
213 | #
214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
215 | # set -- "${ARGS[@]}" "$@"
216 | #
217 | # but POSIX shell has neither arrays nor command substitution, so instead we
218 | # post-process each arg (as a line of input to sed) to backslash-escape any
219 | # character that might be a shell metacharacter, then use eval to reverse
220 | # that process (while maintaining the separation between arguments), and wrap
221 | # the whole thing up as a single "set" statement.
222 | #
223 | # This will of course break if any of these variables contains a newline or
224 | # an unmatched quote.
225 | #
226 |
227 | eval "set -- $(
228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
229 | xargs -n1 |
230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
231 | tr '\n' ' '
232 | )" '"$@"'
233 |
234 | exec "$JAVACMD" "$@"
235 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'ToolkitExample'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/react-native-gradle-plugin')
5 |
6 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
7 | include(":ReactAndroid")
8 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
9 | }
10 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ToolkitExample",
3 | "displayName": "ToolkitExample"
4 | }
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import {AppRegistry} from 'react-native';
6 | import App from './src/App';
7 | import {name as appName} from './app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | require_relative '../node_modules/react-native/scripts/react_native_pods'
2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
3 |
4 | platform :ios, '11.0'
5 | install! 'cocoapods', :deterministic_uuids => false
6 |
7 | target 'ToolkitExample' do
8 | config = use_native_modules!
9 |
10 | # Flags change depending on the env values.
11 | flags = get_default_flags()
12 |
13 | use_react_native!(
14 | :path => config[:reactNativePath],
15 | # to enable hermes on iOS, change `false` to `true` and then install pods
16 | :hermes_enabled => flags[:hermes_enabled],
17 | :fabric_enabled => flags[:fabric_enabled],
18 | # An absolute path to your application root.
19 | :app_path => "#{Pod::Config.instance.installation_root}/.."
20 | )
21 |
22 | target 'ToolkitExampleTests' do
23 | inherit! :complete
24 | # Pods for testing
25 | end
26 |
27 | # Enables Flipper.
28 | #
29 | # Note that if you have use_frameworks! enabled, Flipper will not work and
30 | # you should disable the next line.
31 | use_flipper!()
32 |
33 | post_install do |installer|
34 | react_native_post_install(installer)
35 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample.xcodeproj/xcshareddata/xcschemes/ToolkitExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : UIResponder
5 |
6 | @property (nonatomic, strong) UIWindow *window;
7 |
8 | @end
9 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 | #import
6 |
7 | #import
8 |
9 | #if RCT_NEW_ARCH_ENABLED
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | #import
18 |
19 | @interface AppDelegate () {
20 | RCTTurboModuleManager *_turboModuleManager;
21 | RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
22 | std::shared_ptr _reactNativeConfig;
23 | facebook::react::ContextContainer::Shared _contextContainer;
24 | }
25 | @end
26 | #endif
27 |
28 | @implementation AppDelegate
29 |
30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
31 | {
32 | RCTAppSetupPrepareApp(application);
33 |
34 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
35 |
36 | #if RCT_NEW_ARCH_ENABLED
37 | _contextContainer = std::make_shared();
38 | _reactNativeConfig = std::make_shared();
39 | _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
40 | _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
41 | bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
42 | #endif
43 |
44 | UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"ToolkitExample", nil);
45 |
46 | if (@available(iOS 13.0, *)) {
47 | rootView.backgroundColor = [UIColor systemBackgroundColor];
48 | } else {
49 | rootView.backgroundColor = [UIColor whiteColor];
50 | }
51 |
52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
53 | UIViewController *rootViewController = [UIViewController new];
54 | rootViewController.view = rootView;
55 | self.window.rootViewController = rootViewController;
56 | [self.window makeKeyAndVisible];
57 | return YES;
58 | }
59 |
60 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
61 | {
62 | #if DEBUG
63 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
64 | #else
65 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
66 | #endif
67 | }
68 |
69 | #if RCT_NEW_ARCH_ENABLED
70 |
71 | #pragma mark - RCTCxxBridgeDelegate
72 |
73 | - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge
74 | {
75 | _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
76 | delegate:self
77 | jsInvoker:bridge.jsCallInvoker];
78 | return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
79 | }
80 |
81 | #pragma mark RCTTurboModuleManagerDelegate
82 |
83 | - (Class)getModuleClassFromName:(const char *)name
84 | {
85 | return RCTCoreModulesClassProvider(name);
86 | }
87 |
88 | - (std::shared_ptr)getTurboModule:(const std::string &)name
89 | jsInvoker:(std::shared_ptr)jsInvoker
90 | {
91 | return nullptr;
92 | }
93 |
94 | - (std::shared_ptr)getTurboModule:(const std::string &)name
95 | initParams:
96 | (const facebook::react::ObjCTurboModule::InitParams &)params
97 | {
98 | return nullptr;
99 | }
100 |
101 | - (id)getModuleInstanceFromClass:(Class)moduleClass
102 | {
103 | return RCTAppSetupDefaultModuleFromClass(moduleClass);
104 | }
105 |
106 | #endif
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ToolkitExample
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSExceptionDomains
30 |
31 | localhost
32 |
33 | NSExceptionAllowsInsecureHTTPLoads
34 |
35 |
36 |
37 |
38 | NSLocationWhenInUseUsageDescription
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UIViewControllerBasedStatusBarAppearance
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExample/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | @autoreleasepool {
8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExampleTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/example/ios/ToolkitExampleTests/ToolkitExampleTests.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | #define TIMEOUT_SECONDS 600
8 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
9 |
10 | @interface ToolkitExampleTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation ToolkitExampleTests
15 |
16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
17 | {
18 | if (test(view)) {
19 | return YES;
20 | }
21 | for (UIView *subview in [view subviews]) {
22 | if ([self findSubviewInView:subview matching:test]) {
23 | return YES;
24 | }
25 | }
26 | return NO;
27 | }
28 |
29 | - (void)testRendersWelcomeScreen
30 | {
31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
33 | BOOL foundElement = NO;
34 |
35 | __block NSString *redboxError = nil;
36 | #ifdef DEBUG
37 | RCTSetLogFunction(
38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
39 | if (level >= RCTLogLevelError) {
40 | redboxError = message;
41 | }
42 | });
43 | #endif
44 |
45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
48 |
49 | foundElement = [self findSubviewInView:vc.view
50 | matching:^BOOL(UIView *view) {
51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
52 | return YES;
53 | }
54 | return NO;
55 | }];
56 | }
57 |
58 | #ifdef DEBUG
59 | RCTSetLogFunction(RCTDefaultLogFunction);
60 | #endif
61 |
62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Metro configuration for React Native
3 | * https://github.com/facebook/react-native
4 | *
5 | * @format
6 | */
7 |
8 | module.exports = {
9 | transformer: {
10 | getTransformOptions: async () => ({
11 | transform: {
12 | experimentalImportSupport: false,
13 | inlineRequires: true,
14 | },
15 | }),
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ToolkitExample",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "ios:pods": "npx pod-install",
9 | "start": "react-native start",
10 | "test": "jest",
11 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
12 | },
13 | "dependencies": {
14 | "react": "17.0.2",
15 | "react-native": "0.68.1",
16 | "react-native-app-toolkit": "link:../"
17 | },
18 | "devDependencies": {
19 | "@babel/core": "^7.12.9",
20 | "@babel/runtime": "^7.12.5",
21 | "@react-native-community/eslint-config": "^2.0.0",
22 | "@types/jest": "^26.0.23",
23 | "@types/react-native": "^0.67.3",
24 | "@types/react-test-renderer": "^17.0.1",
25 | "@typescript-eslint/eslint-plugin": "^5.17.0",
26 | "@typescript-eslint/parser": "^5.17.0",
27 | "babel-jest": "^26.6.3",
28 | "eslint": "^7.32.0",
29 | "jest": "^26.6.3",
30 | "metro-react-native-babel-preset": "^0.67.0",
31 | "react-test-renderer": "17.0.2",
32 | "typescript": "^4.4.4"
33 | },
34 | "resolutions": {
35 | "@types/react": "^17"
36 | },
37 | "jest": {
38 | "preset": "react-native",
39 | "moduleFileExtensions": [
40 | "ts",
41 | "tsx",
42 | "js",
43 | "jsx",
44 | "json",
45 | "node"
46 | ]
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * React Native App Toolkit Example
3 | * https://github.com/luoxuhai/react-native-app-toolkit
4 | *
5 | * @format
6 | */
7 |
8 | import React from 'react';
9 | import {
10 | SafeAreaView,
11 | ScrollView,
12 | StatusBar,
13 | StyleSheet,
14 | Text,
15 | useColorScheme,
16 | View,
17 | } from 'react-native';
18 | import * as Toolkit from 'react-native-app-toolkit';
19 | import {
20 | Colors,
21 | DebugInstructions,
22 | Header,
23 | LearnMoreLinks,
24 | ReloadInstructions,
25 | } from 'react-native/Libraries/NewAppScreen';
26 |
27 | const Section: React.FC<{
28 | title: string;
29 | }> = ({children, title}) => {
30 | const isDarkMode = useColorScheme() === 'dark';
31 | return (
32 |
33 |
40 | {title}
41 |
42 |
49 | {children}
50 |
51 |
52 | );
53 | };
54 |
55 | const App = () => {
56 | const isDarkMode = useColorScheme() === 'dark';
57 |
58 | const backgroundStyle = {
59 | backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
60 | };
61 |
62 | return (
63 |
64 |
65 |
68 |
69 |
73 |
74 | Edit App.tsx to change this
75 | screen and then come back to see your edits.
76 |
77 |
80 |
83 |
84 | Read the docs to discover what to do next:
85 |
86 |
87 |
88 |
89 |
90 | );
91 | };
92 |
93 | const styles = StyleSheet.create({
94 | sectionContainer: {
95 | marginTop: 32,
96 | paddingHorizontal: 24,
97 | },
98 | sectionTitle: {
99 | fontSize: 24,
100 | fontWeight: '600',
101 | },
102 | sectionDescription: {
103 | marginTop: 8,
104 | fontSize: 18,
105 | fontWeight: '400',
106 | },
107 | highlight: {
108 | fontWeight: '700',
109 | },
110 | });
111 |
112 | export default App;
113 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "compilerOptions": {
4 | /* Basic Options */
5 | "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
7 | "lib": ["es2017"], /* Specify library files to be included in the compilation. */
8 | "allowJs": true, /* Allow javascript files to be compiled. */
9 | // "checkJs": true, /* Report errors in .js files. */
10 | "jsx": "react-native", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
12 | // "sourceMap": true, /* Generates corresponding '.map' file. */
13 | // "outFile": "./", /* Concatenate and emit output to single file. */
14 | // "outDir": "./", /* Redirect output structure to the directory. */
15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
16 | // "removeComments": true, /* Do not emit comments to output. */
17 | "noEmit": true, /* Do not emit outputs. */
18 | // "incremental": true, /* Enable incremental compilation */
19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
21 | "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
22 |
23 | /* Strict Type-Checking Options */
24 | "strict": true, /* Enable all strict type-checking options. */
25 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
26 | // "strictNullChecks": true, /* Enable strict null checks. */
27 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
28 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
29 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
30 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
31 |
32 | /* Additional Checks */
33 | // "noUnusedLocals": true, /* Report errors on unused locals. */
34 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
35 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
36 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
37 |
38 | /* Module Resolution Options */
39 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
40 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
41 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
42 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
43 | // "typeRoots": [], /* List of folders to include type definitions from. */
44 | // "types": [], /* Type declaration files to be included in compilation. */
45 | "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
46 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
48 | "skipLibCheck": true, /* Skip type checking of declaration files. */
49 | "resolveJsonModule": true /* Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. */
50 |
51 | /* Source Map Options */
52 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
53 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
54 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
55 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
56 |
57 | /* Experimental Options */
58 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
59 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
60 | },
61 | "exclude": [
62 | "node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
63 | ]
64 | }
65 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/.gitignore:
--------------------------------------------------------------------------------
1 | # xcode noise
2 | build/
3 | *.pbxuser
4 | *.mode1v3
5 | *.mode2v3
6 | *.perspectivev3
7 | xcuserdata/
8 | *.xccheckout
9 |
10 | # old skool
11 | .svn
12 |
13 | # osx noise
14 | .DS_Store
15 | profile
16 |
17 | # vim noise
18 | *~
19 | *.swp
20 |
21 | # AppCode noise
22 | .idea/
23 |
24 | # Ruby
25 | .ruby-version
26 |
27 | # Carthage
28 | Carthage/Build
29 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode11.2
3 |
4 | before_install:
5 | - env
6 | - locale
7 | - xcpretty --version
8 | - xcodebuild -version
9 | - xcodebuild -showsdks
10 |
11 | script:
12 | - set -o pipefail
13 |
14 | - xcodebuild clean build -workspace MBProgressHUD.xcworkspace -scheme HudDemo -sdk iphonesimulator -configuration Debug | xcpretty -c
15 | - xcodebuild clean build -workspace MBProgressHUD.xcworkspace -scheme HudDemoTV -sdk appletvsimulator -configuration Debug | xcpretty -c
16 | - xcodebuild clean build test -workspace MBProgressHUD.xcworkspace -scheme HudTests -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPad Air (3rd generation),OS=13.2.2" -configuration Debug GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES | xcpretty -c
17 |
18 | after_success:
19 | - bash <(curl -s https://codecov.io/bash)
20 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/CHANGELOG.mdown:
--------------------------------------------------------------------------------
1 | **Version 1.0.0** @ 14.07.16
2 |
3 | - Requires ARC and iOS 6+.
4 | - Includes a new default design for iOS 7+.
5 | - Deprecates certain helpers and exposes some more flexible API.
6 | - Removes KVO observing of local properties.
7 | - Migrates layout code to Auto Layout.
8 | - Includes a rewritten demo app.
9 | - Includes a rewritten iOS example app.
10 | - Updates and extends documentation.
11 | - Adds a new button property (cancellation support).
12 | - Adds support for `NSProgress`
13 | - Adds a new customizable background view class.
14 | - Adds new assertions.
15 | - Adds basic unit tests.
16 | - Adds support for motion effects.
17 | - Adds nullability.
18 | - Adds basic interface builder support.
19 | - Adds tvOS support.
20 | - Adds a simple tvOS example app.
21 | - Improves behavior when showing and hiding in quick succession.
22 | - Improves support for `UIAppearance `.
23 | - Various smaller bug-fixes
24 |
25 | **Version 0.9.2** @ 22.12.15
26 |
27 | - Timer improvements
28 | - Additional assertions
29 | - Added a framework target
30 | - Tint progress tint color enhancements
31 |
32 | **Version 0.9.1** @ 06.03.15
33 |
34 | - Bug-fixes
35 | - Modernization
36 |
37 | **Version 0.9** @ 12.08.14
38 |
39 | - iOS 8 compatibility and some bug fixes.
40 | - Additional iOS 7 / iOS 8 styling enhancements.
41 | - Improved 64bit support.
42 | - Demo modernization.
43 |
44 | **Version 0.8** @ 19.09.13
45 |
46 | - iOS 7 compatibility and some bug fixes.
47 |
48 | **Version 0.7** @ 25.06.13
49 |
50 | - Added horizontal bar mode. ([jjxtra](https://github.com/jjxtra)).
51 | - CI integration.
52 |
53 | **Version 0.6** @ 13.03.13
54 |
55 | - Full cocoapods support.
56 | - Static library integration option.
57 | - Improved blocks support.
58 | - Bezel color.
59 | - Demo app fixes (iOS 6).
60 | - Various bug-fixes and enhancements.
61 |
62 | **Version 0.5** @ 22.03.12
63 |
64 | - Major source code modernization and cleanup (KVO, layout code, instance vars, etc.).
65 | - New annular determinate mode.
66 | - New text only mode.
67 | - Added a static library project and Xcode 4 workspace.
68 | - Added methods to find and return HUD(s) on a view.
69 | - Various bug fixes.
70 | - Various demo project enhancements (hi-res rescues, new samples).
71 |
72 | IMPORTANT: Requires LLVM 3+.
73 |
74 | **Version 0.41** @ 03.01.12
75 |
76 | - Support for ARC.
77 |
78 | **Version 0.4** @ 25.07.10
79 |
80 | - Different animation modes. Default set to zoom.
81 | - Class convenience methods ([tadelv](http://github.com/tadelv)).
82 | - Autorotation when added to a UIWindow ([wuf810](http://github.com/wuf810)).
83 | - Extended demo app.
84 | - Several smaller fixes.
85 |
86 | **Version 0.33** @ 27.03.10
87 |
88 | - Custom view operation mode added.
89 | - Fixed a memory leak.
90 |
91 | **Version 0.32** @ 4.01.10
92 |
93 | - Added minShowTime, graceTime, xOffset, yOffset.
94 | - Various fixes.
95 |
96 | **Version 0.31** @ 8.10.09
97 |
98 | - Fix for touch through during the fade-out animation.
99 |
100 | **Version 0.3** @ 30.9.09
101 |
102 | - Added show: and hide: methods.
103 | - Now using UIViews layoutSubviews to automate layout calls.
104 | - Added some floors to round pixel positions and thereby prevent unsharp views.
105 | - Some additional documentation and code cleanup.
106 |
107 | **Version 0.2** @ 21.7.09
108 |
109 | - Added determinate progress mode and switching capabilities between determinate and indeterminate modes.
110 | - Various bug-fixes.
111 |
112 | **Version 0.11** @ 2.6.09.
113 |
114 | - Updated labelText and detailsLabelText properties to support text modifications while the HUD is being shown.
115 |
116 | **Version 0.1** @ 2.4.09
117 |
118 | - Initial release.
119 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Please take a moment to review this document in order to make the contribution
2 | process easy and effective for everyone involved.
3 |
4 |
5 | # Using the issue tracker
6 |
7 | The issue tracker is the preferred channel for [bug reports](#bugs) and
8 | [features requests](#features), but please respect the following restriction:
9 |
10 | * Please **do not** use the issue tracker for personal support requests (use
11 | a service like [Stack Overflow](http://stackoverflow.com) instead).
12 |
13 |
14 | ## Bug reports
15 |
16 | A bug is a _demonstrable problem_ that is caused by the code in the repository.
17 | Good bug reports are extremely helpful - thank you!
18 |
19 | Guidelines for bug reports:
20 |
21 | 1. **Use the GitHub issue search** — check if the issue has already been
22 | reported.
23 |
24 | 2. **Check if the issue has been fixed** — try to reproduce it using the
25 | latest `master` branch in the repository.
26 |
27 | 3. **Isolate the problem** — provide exact reproduction steps, preferably
28 | in the form of a failing test case or by providing modification steps in the
29 | `MBProgressHUD` Demo application.
30 |
31 | A good bug report shouldn't leave others needing to chase you up for more
32 | information. Please try to be as detailed as possible in your report. What is
33 | your environment? What steps will reproduce the issue? What iOS version did
34 | you use? What would you expect to be the outcome?
35 |
36 |
37 |
38 | ## Feature requests
39 |
40 | Feature requests are welcome. But take a moment to find out whether your idea
41 | fits with the scope and aims of the project. It's up to *you* to make a strong
42 | case to convince the project's developers of the merits of this feature. Please
43 | provide as much detail and context as possible.
44 |
45 |
46 |
47 | # Pull requests
48 |
49 | Good pull requests - patches, improvements, new features - are a fantastic
50 | help. They should remain focused in scope and avoid containing unrelated
51 | commits.
52 |
53 | **Please ask first** before embarking on any significant pull request (e.g.
54 | implementing features, refactoring code, porting to a different language),
55 | otherwise you risk spending a lot of time working on something that the
56 | project's developers might not want to merge into the project.
57 |
58 | Please adhere to the coding conventions used throughout a project (indentation,
59 | accurate comments, etc.) and any other requirements (such as test coverage).
60 |
61 | **IMPORTANT**: By submitting a patch, you agree to allow the project owner to
62 | license your work under the same license as that used by the project.
63 |
64 | This document is based on https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md.
65 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/Framework-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2009-2020 Matej Bukovinski
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'MBProgressHUD' target in the 'MBProgressHUD' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_8_0
8 | #warning "This project uses features only available in iOS SDK 8.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #import
15 | #endif
16 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "MBProgressHUD"
3 | s.version = "1.2.0"
4 | s.summary = "An iOS activity indicator view."
5 | s.description = <<-DESC
6 | MBProgressHUD is an iOS drop-in class that displays a translucent HUD
7 | with an indicator and/or labels while work is being done in a background thread.
8 | The HUD is meant as a replacement for the undocumented, private UIKit UIProgressHUD
9 | with some additional features.
10 | DESC
11 | s.homepage = "http://www.bukovinski.com"
12 | s.license = { :type => 'MIT', :file => 'LICENSE' }
13 | s.author = { 'Matej Bukovinski' => 'matej@bukovinski.com' }
14 | s.source = { :git => "https://github.com/matej/MBProgressHUD.git", :tag => s.version.to_s }
15 | s.ios.deployment_target = '9.0'
16 | s.tvos.deployment_target = '9.0'
17 | s.source_files = '*.{h,m}'
18 | s.frameworks = "CoreGraphics", "QuartzCore"
19 | s.requires_arc = true
20 | end
21 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.xcodeproj/xcshareddata/xcschemes/MBProgressHUD Framework tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.xcodeproj/xcshareddata/xcschemes/MBProgressHUD Framework.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.xcodeproj/xcshareddata/xcschemes/MBProgressHUD.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
62 |
63 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
15 |
16 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/MBProgressHUD.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/README.mdown:
--------------------------------------------------------------------------------
1 | # MBProgressHUD
2 |
3 | [](https://travis-ci.org/matej/MBProgressHUD) [](https://codecov.io/github/matej/MBProgressHUD?branch=master)
4 | [](https://github.com/apple/swift-package-manager) [](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) [](https://github.com/JamitLabs/Accio) [](https://cocoapods.org/pods/MBProgressHUD) [](http://opensource.org/licenses/MIT)
5 |
6 | `MBProgressHUD` is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private `UIKit` `UIProgressHUD` with some additional features.
7 |
8 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/1.png)
9 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/2.png)
10 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/3.png)
11 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/4.png)
12 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/5.png)
13 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/6.png)
14 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/7.png)
15 |
16 | ## Requirements
17 |
18 | `MBProgressHUD` works on iOS 9.0+. It depends on the following Apple frameworks, which should already be included with most Xcode templates:
19 |
20 | * Foundation.framework
21 | * UIKit.framework
22 | * CoreGraphics.framework
23 |
24 | You will need the latest developer tools in order to build `MBProgressHUD`. Old Xcode versions might work, but compatibility will not be explicitly maintained.
25 |
26 | ## Adding MBProgressHUD to your project
27 |
28 | ### CocoaPods
29 |
30 | [CocoaPods](http://cocoapods.org) is the recommended way to add MBProgressHUD to your project.
31 |
32 | 1. Add a pod entry for MBProgressHUD to your Podfile `pod 'MBProgressHUD', '~> 1.2.0'`
33 | 2. Install the pod(s) by running `pod install`.
34 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`.
35 |
36 | ### Carthage
37 |
38 | 1. Add MBProgressHUD to your Cartfile. e.g., `github "jdg/MBProgressHUD" ~> 1.2.0`
39 | 2. Run `carthage update`
40 | 3. Follow the rest of the [standard Carthage installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add MBProgressHUD to your project.
41 |
42 | ### SwiftPM / Accio
43 |
44 | 1. Add the following to your `Package.swift`:
45 | ```swift
46 | .package(url: "https://github.com/jdg/MBProgressHUD.git", .upToNextMajor(from: "1.2.0")),
47 | ```
48 | 2. Next, add `MBProgressHUD` to your App targets dependencies like so:
49 | ```swift
50 | .target(name: "App", dependencies: ["MBProgressHUD"]),
51 | ```
52 | 3. Then open your project in Xcode 11+ (SwiftPM) or run `accio update` (Accio).
53 |
54 | ### Source files
55 |
56 | Alternatively you can directly add the `MBProgressHUD.h` and `MBProgressHUD.m` source files to your project.
57 |
58 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/archive/master.zip) or add the repository as a git submodule to your git-tracked project.
59 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project.
60 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`.
61 |
62 | ### Static library
63 |
64 | You can also add MBProgressHUD as a static library to your project or workspace.
65 |
66 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/downloads) or add the repository as a git submodule to your git-tracked project.
67 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.xcodeproj` onto your project or workspace (use the "Product Navigator view").
68 | 3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add `libMBProgressHUD.a`. You might also need to add `MBProgressHUD` to the Target Dependencies list.
69 | 4. Include MBProgressHUD wherever you need it with `#import `.
70 |
71 | ## Usage
72 |
73 | The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread.
74 |
75 | ```objective-c
76 | [MBProgressHUD showHUDAddedTo:self.view animated:YES];
77 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
78 | // Do something...
79 | dispatch_async(dispatch_get_main_queue(), ^{
80 | [MBProgressHUD hideHUDForView:self.view animated:YES];
81 | });
82 | });
83 | ```
84 |
85 | You can add the HUD on any view or window. It is however a good idea to avoid adding the HUD to certain `UIKit` views with complex view hierarchies - like `UITableView` or `UICollectionView`. Those can mutate their subviews in unexpected ways and thereby break HUD display.
86 |
87 | If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns.
88 |
89 | ```objective-c
90 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
91 | hud.mode = MBProgressHUDModeAnnularDeterminate;
92 | hud.label.text = @"Loading";
93 | [self doSomethingInBackgroundWithProgressCallback:^(float progress) {
94 | hud.progress = progress;
95 | } completionCallback:^{
96 | [hud hideAnimated:YES];
97 | }];
98 | ```
99 |
100 | You can also use a `NSProgress` object and MBProgressHUD will update itself when there is progress reported through that object.
101 |
102 | ```objective-c
103 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
104 | hud.mode = MBProgressHUDModeAnnularDeterminate;
105 | hud.label.text = @"Loading";
106 | NSProgress *progress = [self doSomethingInBackgroundCompletion:^{
107 | [hud hideAnimated:YES];
108 | }];
109 | hud.progressObject = progress;
110 | ```
111 |
112 | Keep in mind that UI updates, including calls to MBProgressHUD should always be done on the main thread.
113 |
114 | If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task.
115 |
116 | ```objective-c
117 | [MBProgressHUD showHUDAddedTo:self.view animated:YES];
118 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC);
119 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
120 | // Do something...
121 | [MBProgressHUD hideHUDForView:self.view animated:YES];
122 | });
123 | ```
124 |
125 | You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes.
126 |
127 | For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h).
128 |
129 |
130 | ## License
131 |
132 | This code is distributed under the terms and conditions of the [MIT license](LICENSE).
133 |
134 | ## Change-log
135 |
136 | A brief summary of each MBProgressHUD release can be found in the [CHANGELOG](CHANGELOG.mdown).
137 |
138 | ## Privacy
139 |
140 | MBProgressHUD does not collect any data. See [SDK Privacy Practices](https://bukovinski.com/sdk-privacy/mbprogresshud/) for more information.
141 |
--------------------------------------------------------------------------------
/ios/MBProgressHUD/include/MBProgressHUD/MBProgressHUD.h:
--------------------------------------------------------------------------------
1 | ../../MBProgressHUD.h
--------------------------------------------------------------------------------
/ios/MBProgressHUD/include/module.modulemap:
--------------------------------------------------------------------------------
1 | module MBProgressHUD {
2 | umbrella header "MBProgressHUD/MBProgressHUD.h"
3 | export *
4 | module * { export * }
5 | }
6 |
--------------------------------------------------------------------------------
/ios/RCTConvert+RNToolkit.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | @import UIKit;
4 |
5 | @interface RCTConvert(RNToolkit)
6 |
7 | + (UIModalPresentationStyle)UIModalPresentationStyle:(NSString*)value;
8 | + (UIModalTransitionStyle)UIModalTransitionStyle:(NSString*)value;
9 | + (UIImagePickerControllerQualityType)UIImagePickerControllerQualityType:(NSString*)value;
10 | + (QLThumbnailGenerationRequestRepresentationTypes)QLThumbnailGenerationRequestRepresentationTypes:(NSString*)value API_AVAILABLE(ios(13.0));
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/ios/RCTConvert+RNToolkit.m:
--------------------------------------------------------------------------------
1 | #import "RCTConvert+RNToolkit.h"
2 |
3 | @implementation RCTConvert(RNToolkit)
4 |
5 | + (UIModalPresentationStyle)defaultModalPresentationStyle {
6 | if (@available(iOS 13.0, *)) {
7 | return UIModalPresentationAutomatic;
8 | } else {
9 | return UIModalPresentationFullScreen;
10 | }
11 | }
12 |
13 | RCT_ENUM_CONVERTER(UIModalTransitionStyle, (@{
14 | @"coverVertical" : @(UIModalTransitionStyleCoverVertical),
15 | @"flipHorizontal" : @(UIModalTransitionStyleFlipHorizontal),
16 | @"crossDissolve" : @(UIModalTransitionStyleCrossDissolve),
17 | @"partialCurl" : @(UIModalTransitionStylePartialCurl)
18 | }),
19 | UIModalTransitionStyleCoverVertical, integerValue)
20 |
21 | RCT_ENUM_CONVERTER(UIModalPresentationStyle, (@{
22 | @"fullScreen" : @(UIModalPresentationFullScreen),
23 | @"pageSheet" : @(UIModalPresentationPageSheet),
24 | @"formSheet" : @(UIModalPresentationFormSheet),
25 | @"currentContext" : @(UIModalPresentationCurrentContext),
26 | @"custom" : @(UIModalPresentationCustom),
27 | @"overFullScreen" : @(UIModalPresentationOverFullScreen),
28 | @"overCurrentContext" : @(UIModalPresentationOverCurrentContext),
29 | @"popover" : @(UIModalPresentationPopover),
30 | @"none" : @(UIModalPresentationNone),
31 | @"default" : @([RCTConvert defaultModalPresentationStyle])
32 | }),
33 | UIModalPresentationFullScreen, integerValue)
34 |
35 | RCT_ENUM_CONVERTER(UIImagePickerControllerQualityType,(@{
36 | @"high" : @(UIImagePickerControllerQualityTypeHigh),
37 | @"640x480" : @(UIImagePickerControllerQualityType640x480),
38 | @"medium" : @(UIImagePickerControllerQualityTypeMedium),
39 | @"low" : @(UIImagePickerControllerQualityTypeLow),
40 | @"iFrame1280x720" : @(UIImagePickerControllerQualityTypeIFrame1280x720),
41 | @"iFrame960x540" : @(UIImagePickerControllerQualityTypeIFrame960x540),
42 | }),
43 | UIImagePickerControllerQualityTypeHigh, integerValue)
44 |
45 | RCT_ENUM_CONVERTER(QLThumbnailGenerationRequestRepresentationTypes,(@{
46 | @"icon" : @(QLThumbnailGenerationRequestRepresentationTypeIcon),
47 | @"lowQualityThumbnail" : @(QLThumbnailGenerationRequestRepresentationTypeLowQualityThumbnail),
48 | @"thumbnail" : @(QLThumbnailGenerationRequestRepresentationTypeThumbnail),
49 | @"all" : @(QLThumbnailGenerationRequestRepresentationTypeAll),
50 | }),
51 | QLThumbnailGenerationRequestRepresentationTypeThumbnail, integerValue)
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/ios/RNToolkit.h:
--------------------------------------------------------------------------------
1 | //
2 | // DocumentCamera.h
3 | // RNToolkit
4 | //
5 | // Created by https://github.com/luoxuhai on 2022/4/9.
6 | //
7 |
8 | #import
9 |
10 | @interface RNToolkit : NSObject
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/ios/RNToolkit.m:
--------------------------------------------------------------------------------
1 | #import "RNToolkit.h"
2 |
3 | static NSString* const TMP_DIRECTORY = @"react-native-kit/";
4 |
5 | @interface RNToolkit()
6 |
7 | @end
8 |
9 | @implementation RNToolkit
10 |
11 | - (instancetype)init {
12 | NSString *directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
13 | NSFileManager *fileManager = [[NSFileManager alloc] init];
14 |
15 | BOOL isDir = YES;
16 | BOOL exists = [fileManager fileExistsAtPath:directory isDirectory:&isDir];
17 | if (!exists) {
18 | [fileManager createDirectoryAtPath: directory
19 | withIntermediateDirectories:YES attributes:nil error:nil];
20 | }
21 | return self;
22 | }
23 |
24 | RCT_EXPORT_MODULE(RNToolkit)
25 |
26 | RCT_EXPORT_METHOD(init:(RCTPromiseResolveBlock)resolve
27 | rejecter:(RCTPromiseRejectBlock)reject)
28 | {
29 | NSString *directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
30 | NSFileManager *fileManager = [[NSFileManager alloc] init];
31 |
32 | BOOL isDir = YES;
33 | BOOL exists = [fileManager fileExistsAtPath:directory isDirectory:&isDir];
34 | if (!exists) {
35 | [fileManager createDirectoryAtPath: directory
36 | withIntermediateDirectories:YES attributes:nil error:nil];
37 | }
38 | resolve(directory);
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/ios/RTKAppearance.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RTKAppearance : NSObject
4 |
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/RTKAppearance.m:
--------------------------------------------------------------------------------
1 | #import "RNToolkit.h"
2 | #import "RTKAppearance.h"
3 |
4 | @implementation RNToolkit
5 |
6 | RCT_EXPORT_MODULE(RTKAppearance)
7 |
8 | RCT_EXPORT_METHOD(setAppearanceColorScheme:(NSString *)style
9 | withResolver:(RCTPromiseResolveBlock)resolve
10 | withRejecter:(RCTPromiseRejectBlock)reject)
11 | {
12 | if (@available(iOS 13.0, *)) {
13 | dispatch_async(dispatch_get_main_queue(), ^{
14 | UIWindow *window = UIApplication.sharedApplication.delegate.window;
15 | if ([style isEqual:@"light"]) {
16 | window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
17 | } else if ([style isEqual:@"dark"]) {
18 | window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
19 | } else {
20 | window.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
21 | }
22 | });
23 | resolve(nil);
24 | } else {
25 | reject(@"ERROR", @"Only available on iOS 13.0 or newer", nil);
26 | }
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/ios/RTKDocumentCamera.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | typedef NS_ENUM(NSInteger, RTKDocumentCameraResultType) {
4 | RTKResultPdf,
5 | RTKResultImage
6 | };
7 |
8 | @interface RTKDocumentCamera : NSObject
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/ios/RTKDocumentCamera.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import "RTKDocumentCamera.h"
6 |
7 | static NSString* const TMP_DIRECTORY = @"react-native-kit/";
8 |
9 | @implementation RCTConvert (RTKDocumentCameraResultType)
10 |
11 | RCT_ENUM_CONVERTER(
12 | RTKDocumentCameraResultType,
13 | (@{
14 | @"pdf" : @(RTKResultPdf),
15 | @"image" : @(RTKResultImage)
16 | }),
17 | RTKResultPdf,
18 | integerValue)
19 | @end
20 |
21 | @interface RTKDocumentCamera()
22 |
23 | @property (nonatomic, copy) NSDictionary *options;
24 | @property (nonatomic, copy) NSString *directory;
25 | @property (nonatomic, copy) RCTPromiseResolveBlock resolve;
26 | @property (nonatomic, copy) RCTPromiseRejectBlock reject;
27 |
28 | @end
29 |
30 | @implementation RTKDocumentCamera
31 |
32 | - (instancetype)init {
33 | if ((self = [super init])) {
34 | self.directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
35 | }
36 | return self;
37 | }
38 |
39 | RCT_EXPORT_MODULE(RTKDocumentCamera)
40 |
41 | RCT_EXPORT_METHOD(openDocumentCamera:(NSDictionary *)options
42 | resolver:(RCTPromiseResolveBlock)resolve
43 | rejecter:(RCTPromiseRejectBlock)reject)
44 | {
45 | self.resolve = resolve;
46 | self.reject = reject;
47 | self.options = options;
48 |
49 | dispatch_async(dispatch_get_main_queue(), ^{
50 | if (@available(iOS 13.0, *)) {
51 | if (VNDocumentCameraViewController.isSupported) {
52 | VNDocumentCameraViewController* documentCameraViewController = [[VNDocumentCameraViewController alloc] init];
53 |
54 | documentCameraViewController.delegate = self;
55 |
56 | UIViewController *rootViewController = RCTPresentedViewController();
57 | [rootViewController presentViewController:documentCameraViewController animated:YES completion:nil];
58 | } else {
59 | self.reject(@"ERROR",@"The current device doesn't support document scanning", nil);
60 | }
61 | } else {
62 | self.reject(@"ERROR", @"Only available on iOS 13.0 or newer", nil);
63 | }
64 | });
65 | }
66 |
67 | RCT_EXPORT_METHOD(isSupported:(RCTPromiseResolveBlock)resolve
68 | rejecter:(RCTPromiseRejectBlock)reject)
69 | {
70 | if (@available(iOS 13.0, *)) {
71 | resolve(@(VNDocumentCameraViewController.isSupported));
72 | } else {
73 | resolve(@(NO));
74 | }
75 | }
76 |
77 | - (void) dismissViewController: (VNDocumentCameraViewController *)controller API_AVAILABLE(ios(13.0)){
78 | [controller dismissViewControllerAnimated:YES completion:nil];
79 | }
80 |
81 | - (NSString *) imagesToPDF: (NSMutableArray *)images {
82 | PDFDocument *pdfDocument = [PDFDocument new];
83 |
84 | for (int i = 0; i < images.count; i++) {
85 | PDFPage *pdfPage = [[PDFPage alloc] initWithImage:images[i]];
86 | [pdfDocument insertPage:pdfPage atIndex:i];
87 | }
88 | NSData *data = [pdfDocument dataRepresentation];
89 | NSString *dest = [NSString stringWithFormat:@"%@%@.%@", self.directory, [[NSUUID UUID] UUIDString], @"pdf"];
90 | if (![data writeToFile:dest atomically:YES]) {
91 | self.reject(@"ERROR", @"Can't write to file.", nil);
92 | return nil;
93 | }
94 | return dest;
95 | }
96 |
97 | #pragma mark - VNDocumentCameraViewControllerDelegate
98 |
99 | - (void)documentCameraViewController:(VNDocumentCameraViewController *)controller didFinishWithScan:(VNDocumentCameraScan *)scan API_AVAILABLE(ios(13.0)) API_AVAILABLE(ios(13.0)){
100 | NSString *typeStr = self.options[@"type"];
101 | RTKDocumentCameraResultType type = [RCTConvert RTKDocumentCameraResultType:typeStr];
102 |
103 | NSMutableArray *images = [NSMutableArray new];
104 | for (int i = 0; i < [scan pageCount]; i++) {
105 | UIImage* image = [scan imageOfPageAtIndex:i];
106 | [images addObject:image];
107 | }
108 |
109 | if (type == RTKResultImage) {
110 | NSMutableArray *source = [NSMutableArray new];
111 | NSNumber *quality = self.options[@"quality"];
112 |
113 | for (int i = 0; i < [images count]; i++) {
114 | NSString *dest = [NSString stringWithFormat:@"%@%@.%@", self.directory, [[NSUUID UUID] UUIDString], @"jpg"];
115 | NSData *data = UIImageJPEGRepresentation(images[i], [quality floatValue]);
116 | if (![data writeToFile:dest atomically:YES]) {
117 | self.reject(@"ERROR", @"Can't write to file.", nil);
118 | [self dismissViewController:controller];
119 | return;
120 | }
121 | [source addObject:dest];
122 | }
123 | self.resolve(@{
124 | @"type":self.options[@"type"],
125 | @"source":source
126 | });
127 | } else {
128 | NSString *pdfPath = [self imagesToPDF:images];
129 | if (pdfPath) {
130 | self.resolve(@{
131 | @"type":self.options[@"type"],
132 | @"source":pdfPath
133 | });
134 | }
135 | }
136 |
137 | [self dismissViewController:controller];
138 | }
139 |
140 | - (void)documentCameraViewControllerDidCancel:(VNDocumentCameraViewController *)controller API_AVAILABLE(ios(13.0)){
141 | [self dismissViewController:controller];
142 | }
143 |
144 | - (void)documentCameraViewController:(VNDocumentCameraViewController *)controller didFailWithError:(NSError *)error API_AVAILABLE(ios(13)){
145 | self.reject(@"ERROR", error.localizedDescription, error);
146 | [self dismissViewController:controller];
147 | }
148 |
149 | @end
150 |
--------------------------------------------------------------------------------
/ios/RTKMediaLibrary.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RTKMediaLibrary : NSObject
4 |
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/RTKMediaLibrary.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import "RTKMediaLibrary.h"
5 |
6 | static NSString* const OPTIONS_KEY_QUALITY = @"quality";
7 | static NSString* const OPTIONS_KEY_TIME = @"time";
8 | static NSString* const OPTIONS_KEY_INCLUDE_SIZE = @"includeSize";
9 | static NSString* const TMP_DIRECTORY = @"react-native-kit/";
10 | static NSString* const OPTIONS_KEY_HEADERS = @"headers";
11 |
12 | @interface RTKMediaLibrary()
13 |
14 | @property (nonatomic, copy) NSString *directory;
15 |
16 | @end
17 |
18 | @implementation RTKMediaLibrary
19 |
20 | -(id)init {
21 | self.directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
22 | return self;
23 | }
24 |
25 | RCT_EXPORT_MODULE(RTKMediaLibrary)
26 |
27 | RCT_EXPORT_METHOD(getVideoThumbnail:(NSString *)path
28 | options:( NSDictionary *)options
29 | resolver:(RCTPromiseResolveBlock)resolve
30 | rejecter:(RCTPromiseRejectBlock)reject)
31 | {
32 | NSURL *url = [NSURL URLWithString:path];
33 | long timeOption = [options[OPTIONS_KEY_TIME] integerValue] ?: 0;
34 | float quality = [options[OPTIONS_KEY_QUALITY] floatValue] ?: 0;
35 | BOOL includeSize = [options[OPTIONS_KEY_INCLUDE_SIZE] boolValue] ?: NO;
36 | NSDictionary *headers = options[OPTIONS_KEY_HEADERS] ?: @{};
37 |
38 | AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:@{@"AVURLAssetHTTPHeaderFieldsKey": headers}];
39 |
40 | AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
41 | generator.appliesPreferredTrackTransform = YES;
42 | generator.requestedTimeToleranceBefore = kCMTimeZero;
43 | generator.requestedTimeToleranceAfter = kCMTimeZero;
44 |
45 | NSError *err = NULL;
46 | CMTime time = CMTimeMake(timeOption, 1000);
47 |
48 | CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err];
49 | if (err) {
50 | reject(@"ERROR",err.localizedFailureReason,nil);
51 | }
52 |
53 | UIImage *thumbnail = [UIImage imageWithCGImage:imgRef];
54 | NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingString:@".jpg"];
55 | NSString *dest = [self.directory stringByAppendingString:fileName];
56 |
57 | NSData *data = UIImageJPEGRepresentation(thumbnail, quality);
58 |
59 | if (![data writeToFile:dest atomically:YES]) {
60 | reject(@"ERROR",@"Can't write to file.",nil);
61 | }
62 |
63 | NSNumber *fileSize = nil;
64 |
65 | if (includeSize) {
66 | [[NSURL fileURLWithPath:dest] getResourceValue:&fileSize
67 | forKey:NSURLFileSizeKey
68 | error:nil];
69 | }
70 |
71 | CGImageRelease(imgRef);
72 |
73 | resolve(@{
74 | @"uri": dest,
75 | @"width": @(thumbnail.size.width),
76 | @"height": @(thumbnail.size.height),
77 | @"size": (fileSize) ?: [NSNull null]
78 | });
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/ios/RTKQuickLookView/RTKQuickLookManager.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface RTKQuickLookManager : RCTViewManager
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/ios/RTKQuickLookView/RTKQuickLookManager.m:
--------------------------------------------------------------------------------
1 | #import "RTKQuickLookManager.h"
2 | #import "RTKQuickLookView.h"
3 | #import
4 |
5 | @implementation RTKQuickLookManager
6 |
7 | RCT_EXPORT_MODULE(RTKQuickLook)
8 |
9 | - (UIView *) view {
10 | return [[RTKQuickLookView alloc] init];
11 | }
12 |
13 | RCT_EXPORT_VIEW_PROPERTY(url, NSString)
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ios/RTKQuickLookView/RTKQuickLookView.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RTKQuickLookView : UIView
4 |
5 | @property (nonatomic, copy) NSString *url;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/ios/RTKQuickLookView/RTKQuickLookView.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "RTKQuickLookView.h"
3 |
4 | @interface RTKQuickLookView ()
5 |
6 | @property QLPreviewController* controller;
7 |
8 | @end
9 |
10 |
11 | @implementation RTKQuickLookView
12 |
13 | - (id)init {
14 | self = [super init];
15 | if (self) {
16 | [self initialize];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)initialize {
22 | self.controller = [[QLPreviewController alloc] init];
23 | self.controller.delegate = self;
24 | self.controller.dataSource = self;
25 | self.controller.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
26 | self.controller.view.backgroundColor = UIColor.blackColor;
27 | [self addSubview:self.controller.view];
28 | }
29 |
30 | - (id)initWithPreviewItemUrl:(NSString*)url {
31 | NSAssert(url != nil, @"Preview Item URL cannot be nil");
32 | self = [super init];
33 | if (self) {
34 | _url = url;
35 | [self initialize];
36 | }
37 | return self;
38 | }
39 |
40 | - (void)setUrl:(NSString *)urlString {
41 | _url = [urlString stringByRemovingPercentEncoding];
42 | [self.controller refreshCurrentPreviewItem];
43 | [self.controller reloadData];
44 | }
45 |
46 | #pragma mark - QLPreviewControllerDataSource
47 |
48 | - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
49 | return 1;
50 | }
51 |
52 | - (id )previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
53 | return [NSURL fileURLWithPath:_url];
54 | }
55 |
56 | #pragma mark - QLPreviewControllerDelegate
57 |
58 | - (BOOL)previewController:(QLPreviewController *)controller shouldOpenURL:(NSURL *)url forPreviewItem:(id )item {
59 | return YES;
60 | }
61 |
62 | - (void)didReceiveMemoryWarning {
63 | [self.controller didReceiveMemoryWarning];
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/ios/RTKThumbnailGenerator.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RTKThumbnailGenerator : NSObject
4 |
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/RTKThumbnailGenerator.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "RTKThumbnailGenerator.h"
4 | #import "RCTConvert+RNToolkit.h"
5 |
6 | static NSString* const TMP_DIRECTORY = @"react-native-kit/";
7 |
8 | @interface RTKThumbnailGenerator()
9 |
10 | @property (nonatomic, copy) NSString *directory;
11 |
12 | @end
13 |
14 |
15 | @implementation RTKThumbnailGenerator
16 |
17 | - (id)init {
18 | if ((self = [super init])) {
19 | self.directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
20 | }
21 | return self;
22 | }
23 |
24 | RCT_EXPORT_MODULE(RTKThumbnailGenerator)
25 |
26 | RCT_EXPORT_METHOD(generate:(NSDictionary *)options
27 | resolver:(RCTPromiseResolveBlock)resolve
28 | rejecter:(RCTPromiseRejectBlock)reject) {
29 | if (@available(iOS 14.0, *)) {
30 | NSURL *url = [NSURL fileURLWithPath:options[@"path"]];
31 | CGFloat scale = [options[@"scale"] floatValue] ?: UIScreen.mainScreen.scale;
32 | CGSize size = {[options[@"width"] floatValue], [options[@"height"] floatValue]};
33 | NSString *dest = [NSString stringWithFormat:@"%@%@.%@", self.directory, [[NSUUID UUID] UUIDString], @"jpg"];
34 | NSURL *toFileAtURL = [NSURL fileURLWithPath:options[@"toFileAtURL"] ?: dest ];
35 | BOOL iconMode = [options[@"iconMode"] boolValue] ?: NO;
36 | CGFloat minimumDimension = [options[@"minimumDimension"] floatValue] ?: 0;
37 |
38 | QLThumbnailGenerationRequestRepresentationTypes representationType = [RCTConvert QLThumbnailGenerationRequestRepresentationTypes:options[@"representationType"]];
39 |
40 |
41 | QLThumbnailGenerationRequest *request = [[QLThumbnailGenerationRequest alloc] initWithFileAtURL:url
42 | size:size
43 | scale:scale
44 | representationTypes:representationType];
45 | request.iconMode = iconMode;
46 | request.minimumDimension = minimumDimension;
47 |
48 | [QLThumbnailGenerator.sharedGenerator saveBestRepresentationForRequest:request
49 | toFileAtURL:toFileAtURL
50 | withContentType:UTTypeJPEG.identifier
51 | completionHandler:^(NSError * _Nullable error) {
52 | if (error) {
53 | reject(@"ERROR", error.localizedDescription, error);
54 | } else {
55 | resolve(@{
56 | @"path": [toFileAtURL absoluteString]
57 | });
58 | }
59 | }];
60 |
61 | } else {
62 | reject(@"ERROR", @"Only available on iOS 13.0 or newer", nil);
63 | }
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/ios/RTKVideoEditor.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RTKVideoEditor : NSObject
4 |
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/RTKVideoEditor.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import "RTKVideoEditor.h"
6 | #import "RCTConvert+RNToolkit.h"
7 |
8 | static NSString* const TMP_DIRECTORY = @"react-native-kit/";
9 |
10 | @interface RTKVideoEditor()
11 |
12 | @property (nonatomic, copy) NSString *directory;
13 | @property (nonatomic, copy) RCTPromiseResolveBlock resolve;
14 | @property (nonatomic, copy) RCTPromiseRejectBlock reject;
15 |
16 | @end
17 |
18 |
19 | @implementation RTKVideoEditor
20 |
21 | - (instancetype)init {
22 | if ((self = [super init])) {
23 | self.directory = [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
24 | }
25 | return self;
26 | }
27 |
28 | RCT_EXPORT_MODULE(RTKVideoEditor)
29 |
30 | RCT_EXPORT_METHOD(openVideoEditor:(NSDictionary *)options
31 | resolver:(RCTPromiseResolveBlock)resolve
32 | rejecter:(RCTPromiseRejectBlock)reject) {
33 | self.resolve = resolve;
34 | self.reject = reject;
35 | int maxDuration = [options[@"maxDuration"] intValue] ?: 1;
36 | NSString *path = options[@"source"];
37 | UIImagePickerControllerQualityType quality = [RCTConvert UIImagePickerControllerQualityType:options[@"quality"]];
38 | UIModalPresentationStyle presentationStyle = [RCTConvert UIModalPresentationStyle:options[@"presentationStyle"]];
39 | UIModalTransitionStyle transitionStyle = [RCTConvert UIModalTransitionStyle:options[@"transitionStyle"]];
40 |
41 | if (path == nil) {
42 | reject(@"ERROR", @"Source cannot be nil", nil);
43 | return;
44 | }
45 |
46 | dispatch_async(dispatch_get_main_queue(), ^{
47 | UIVideoEditorController *videoEditorController = [UIVideoEditorController new];
48 | videoEditorController.videoPath = path;
49 | videoEditorController.videoMaximumDuration = maxDuration;
50 | videoEditorController.videoQuality = quality;
51 | videoEditorController.modalPresentationStyle = presentationStyle;
52 | videoEditorController.modalTransitionStyle = transitionStyle;
53 | videoEditorController.delegate = self;
54 |
55 | UIViewController *rootViewController = RCTPresentedViewController();
56 | [rootViewController presentViewController:videoEditorController animated:YES completion:nil];
57 | });
58 | }
59 |
60 | RCT_EXPORT_METHOD(canEdit:(NSString *)path
61 | resolver:(RCTPromiseResolveBlock)resolve
62 | rejecter:(RCTPromiseRejectBlock)reject) {
63 | resolve(@([UIVideoEditorController canEditVideoAtPath:path]));
64 | }
65 |
66 | #pragma mark - UIVideoEditorControllerDelegate
67 |
68 | - (void)videoEditorController:(UIVideoEditorController *)editor didSaveEditedVideoToPath:(NSString *)editedVideoPath {
69 | self.resolve(@{ @"uri": editedVideoPath });
70 | [editor dismissViewControllerAnimated:YES completion:nil];
71 | }
72 |
73 | - (void)videoEditorController:(UIVideoEditorController *)editor didFailWithError:(NSError *)error {
74 | self.reject(@"ERROR", error.localizedDescription, nil);
75 | [editor dismissViewControllerAnimated:YES completion:nil];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-app-toolkit",
3 | "version": "1.0.0",
4 | "description": "High-quality toolkit for React Native using native code.",
5 | "main": "lib/commonjs/index",
6 | "module": "lib/module/index",
7 | "types": "lib/typescript/index.d.ts",
8 | "react-native": "src/index",
9 | "source": "src/index",
10 | "files": [
11 | "src",
12 | "lib",
13 | "android",
14 | "ios",
15 | "cpp",
16 | "react-native-app-toolkit.podspec",
17 | "!lib/typescript/example",
18 | "!android/build",
19 | "!ios/build",
20 | "!**/__tests__",
21 | "!**/__fixtures__",
22 | "!**/__mocks__"
23 | ],
24 | "scripts": {
25 | "test": "jest",
26 | "typescript": "tsc --noEmit",
27 | "lint": "eslint \"**/*.{js,ts,tsx}\"",
28 | "prepare": "bob build",
29 | "build": "bob build",
30 | "release": "release-it",
31 | "example": "yarn --cwd example",
32 | "pods": "cd example && pod-install --quiet",
33 | "bootstrap": "yarn example && yarn && yarn pods",
34 | "dev-sync": "yarn build && mr example/node_modules/@react-native-library/kit/ios && cp -r package.json *podspec lib android ios src example/node_modules/@react-native-library/kit/",
35 | "example:ios": "cd example && yarn ios",
36 | "example:install:pods": "cd example && yarn ios:pods",
37 | "example:start": "cd example && yarn start"
38 | },
39 | "keywords": [
40 | "react-native",
41 | "ios",
42 | "android",
43 | "toolkit"
44 | ],
45 | "repository": "https://github.com/luoxuhai/react-native-app-toolkit",
46 | "author": "luoxuhai (https://github.com/luoxuhai)",
47 | "license": "MIT",
48 | "bugs": {
49 | "url": "https://github.com/luoxuhai/react-native-app-toolkit/issues"
50 | },
51 | "homepage": "https://github.com/luoxuhai/react-native-app-toolkit#readme",
52 | "publishConfig": {
53 | "registry": "https://registry.npmjs.org/"
54 | },
55 | "devDependencies": {
56 | "@commitlint/config-conventional": "^11.0.0",
57 | "@react-native-community/eslint-config": "^2.0.0",
58 | "@release-it/conventional-changelog": "^2.0.0",
59 | "@types/jest": "^26.0.0",
60 | "@types/react": "^16.9.19",
61 | "@types/react-native": "0.62.13",
62 | "commitlint": "^11.0.0",
63 | "eslint": "^7.2.0",
64 | "eslint-config-prettier": "^7.0.0",
65 | "eslint-plugin-prettier": "^3.1.3",
66 | "husky": "^6.0.0",
67 | "jest": "^26.0.1",
68 | "pod-install": "^0.1.0",
69 | "prettier": "^2.0.5",
70 | "react": "16.13.1",
71 | "react-native": "0.63.4",
72 | "react-native-builder-bob": "^0.18.0",
73 | "release-it": "^14.2.2",
74 | "typescript": "^4.1.3"
75 | },
76 | "peerDependencies": {
77 | "react": "*",
78 | "react-native": "*"
79 | },
80 | "jest": {
81 | "preset": "react-native",
82 | "modulePathIgnorePatterns": [
83 | "/example/node_modules",
84 | "/lib/"
85 | ]
86 | },
87 | "commitlint": {
88 | "extends": [
89 | "@commitlint/config-conventional"
90 | ]
91 | },
92 | "release-it": {
93 | "git": {
94 | "commitMessage": "chore: release ${version}",
95 | "tagName": "v${version}"
96 | },
97 | "npm": {
98 | "publish": true
99 | },
100 | "github": {
101 | "release": true
102 | },
103 | "plugins": {
104 | "@release-it/conventional-changelog": {
105 | "preset": "angular"
106 | }
107 | }
108 | },
109 | "eslintConfig": {
110 | "root": true,
111 | "extends": [
112 | "@react-native-community",
113 | "prettier"
114 | ],
115 | "rules": {
116 | "prettier/prettier": [
117 | "error",
118 | {
119 | "quoteProps": "consistent",
120 | "singleQuote": true,
121 | "tabWidth": 2,
122 | "trailingComma": "es5",
123 | "useTabs": false
124 | }
125 | ]
126 | }
127 | },
128 | "eslintIgnore": [
129 | "node_modules/",
130 | "lib/"
131 | ],
132 | "prettier": {
133 | "quoteProps": "consistent",
134 | "singleQuote": true,
135 | "tabWidth": 2,
136 | "trailingComma": "es5",
137 | "useTabs": false
138 | },
139 | "react-native-builder-bob": {
140 | "source": "src",
141 | "output": "lib",
142 | "targets": [
143 | "commonjs",
144 | "module",
145 | [
146 | "typescript",
147 | {
148 | "project": "tsconfig.build.json"
149 | }
150 | ]
151 | ]
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/react-native-app-toolkit.podspec:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = "react-native-app-toolkit"
7 | s.version = package["version"]
8 | s.summary = package["description"]
9 | s.homepage = package["homepage"]
10 | s.license = package["license"]
11 | s.authors = package["author"]
12 |
13 | s.platforms = { :ios => "11.0" }
14 | s.source = { :git => "https://github.com/luoxuhai/react-native-app-toolkit.git", :tag => "#{s.version}" }
15 |
16 | s.source_files = "ios/**/*.{h,m,mm}"
17 |
18 | s.dependency "React-Core"
19 | end
20 |
--------------------------------------------------------------------------------
/scripts/bootstrap.js:
--------------------------------------------------------------------------------
1 | const os = require('os');
2 | const path = require('path');
3 | const child_process = require('child_process');
4 |
5 | const root = path.resolve(__dirname, '..');
6 | const args = process.argv.slice(2);
7 | const options = {
8 | cwd: process.cwd(),
9 | env: process.env,
10 | stdio: 'inherit',
11 | encoding: 'utf-8',
12 | };
13 |
14 | if (os.type() === 'Windows_NT') {
15 | options.shell = true
16 | }
17 |
18 | let result;
19 |
20 | if (process.cwd() !== root || args.length) {
21 | // We're not in the root of the project, or additional arguments were passed
22 | // In this case, forward the command to `yarn`
23 | result = child_process.spawnSync('yarn', args, options);
24 | } else {
25 | // If `yarn` is run without arguments, perform bootstrap
26 | result = child_process.spawnSync('yarn', ['bootstrap'], options);
27 | }
28 |
29 | process.exitCode = result.status;
30 |
--------------------------------------------------------------------------------
/src/__tests__/index.test.tsx:
--------------------------------------------------------------------------------
1 | it.todo('write a test');
2 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as QuickLook from './packages/QuickLook';
2 | import * as Appearance from './packages/Appearance';
3 | import * as DocumentCamera from './packages/DocumentCamera';
4 | import * as VideoEditor from './packages/VideoEditor';
5 | import * as VideoThumbnail from './packages/VideoThumbnail';
6 | import * as ThumbnailGenerator from './packages/ThumbnailGenerator';
7 |
8 | export {
9 | QuickLook,
10 | Appearance,
11 | DocumentCamera,
12 | VideoEditor,
13 | VideoThumbnail,
14 | ThumbnailGenerator,
15 | };
16 |
--------------------------------------------------------------------------------
/src/internal/nativeInterface.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules, Platform } from 'react-native';
2 |
3 | const LINKING_ERROR =
4 | `The package 'react-native-app-toolkit' doesn't seem to be linked. Make sure: \n\n` +
5 | Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6 | '- You rebuilt the app after installing the package\n' +
7 | '- You are not using Expo managed workflow\n';
8 |
9 | let {
10 | RNToolkit,
11 | RTKMediaLibrary,
12 | RTKVideoEditor,
13 | RTKAppearance,
14 | RTKDocumentCamera,
15 | RTKThumbnailGenerator,
16 | } = NativeModules;
17 |
18 | if (!RNToolkit) {
19 | RNToolkit = new Proxy(
20 | {},
21 | {
22 | get() {
23 | throw new Error(LINKING_ERROR);
24 | },
25 | }
26 | );
27 | }
28 |
29 | RNToolkit.init();
30 |
31 | export {
32 | RNToolkit,
33 | RTKMediaLibrary,
34 | RTKVideoEditor,
35 | RTKAppearance,
36 | RTKDocumentCamera,
37 | RTKThumbnailGenerator,
38 | };
39 |
--------------------------------------------------------------------------------
/src/packages/Appearance.tsx:
--------------------------------------------------------------------------------
1 | import type { ColorSchemeName } from 'react-native';
2 |
3 | import { RTKAppearance } from '../internal/nativeInterface';
4 |
5 | export function setAppearanceColorScheme(
6 | colorsSchemeName: ColorSchemeName
7 | ): Promise {
8 | return RTKAppearance.setAppearanceColorScheme(colorsSchemeName);
9 | }
10 |
--------------------------------------------------------------------------------
/src/packages/DocumentCamera.tsx:
--------------------------------------------------------------------------------
1 | import { RTKDocumentCamera } from '../internal/nativeInterface';
2 |
3 | /**
4 | * Shows what the document camera sees.
5 | * @returns Promise
6 | */
7 | export function open(
8 | options?: DocumentCameraOptions
9 | ): Promise {
10 | return RTKDocumentCamera.openDocumentCamera({
11 | type: 'pdf',
12 | quality: 1,
13 | ...options,
14 | });
15 | }
16 |
17 | export function isSupported() {
18 | return RTKDocumentCamera.isSupported();
19 | }
20 |
--------------------------------------------------------------------------------
/src/packages/QuickLook.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { requireNativeComponent, ViewProps } from 'react-native';
3 |
4 | interface QuickLookViewProps extends ViewProps {
5 | /**
6 | * An URI of the file, local or remote.
7 | */
8 | url?: string;
9 | }
10 |
11 | function QuickLookView(props: QuickLookViewProps) {
12 | return ;
13 | }
14 |
15 | export { QuickLookView as View };
16 |
17 | var RTKQuickLookView = requireNativeComponent('RTKQuickLook');
18 |
--------------------------------------------------------------------------------
/src/packages/ThumbnailGenerator.tsx:
--------------------------------------------------------------------------------
1 | import { RTKThumbnailGenerator } from '../internal/nativeInterface';
2 |
3 | /**
4 | * Generate thumbnails for common file types
5 | */
6 | export function generate(
7 | options?: ThumbnailGeneratorOptions
8 | ): Promise {
9 | return RTKThumbnailGenerator.generate(options);
10 | }
11 |
--------------------------------------------------------------------------------
/src/packages/VideoEditor.tsx:
--------------------------------------------------------------------------------
1 | import { RTKVideoEditor } from '../internal/nativeInterface';
2 |
3 | /**
4 | * Open a video editor for trimming video frames.
5 | * @returns Promise
6 | */
7 | export function open(
8 | source: string,
9 | options?: VideoEditorOptions
10 | ): Promise {
11 | return RTKVideoEditor.openVideoEditor({
12 | source,
13 | maxDuration: 600,
14 | quality: 'high',
15 | ...options,
16 | });
17 | }
18 |
19 | /**
20 | * Returns a Boolean value indicating whether a video file can be edited.
21 | * @returns Promise
22 | */
23 | export function canEdit(source: string): Promise {
24 | return RTKVideoEditor.canEdit(source);
25 | }
26 |
--------------------------------------------------------------------------------
/src/packages/VideoThumbnail.tsx:
--------------------------------------------------------------------------------
1 | import { RTKMediaLibrary } from '../internal/nativeInterface';
2 |
3 | export function getThumbnail(
4 | path: string,
5 | options?: VideoThumbnailOptions
6 | ): Promise {
7 | return RTKMediaLibrary.getVideoThumbnail(path, options);
8 | }
9 |
--------------------------------------------------------------------------------
/src/types.d.ts:
--------------------------------------------------------------------------------
1 | type TransitionStyle =
2 | | 'coverVertical'
3 | | 'flipHorizontal'
4 | | 'crossDissolve'
5 | | 'partialCurl';
6 |
7 | type PresentationStyle =
8 | | 'fullScreen'
9 | | 'pageSheet'
10 | | 'formSheet'
11 | | 'popover'
12 | | 'none'
13 | | 'currentContext'
14 | | 'overFullScreen'
15 | | 'overCurrentContext'
16 | | 'default';
17 |
18 | interface VideoThumbnailOptions {
19 | /**
20 | * 输出图像质量
21 | *
22 | * @default 1
23 | */
24 | quality?: number;
25 | /**
26 | * 截取时间点
27 | *
28 | * @default 0
29 | */
30 | time?: number;
31 | /**
32 | * 返回的结果中是否包含图像文件大小
33 | *
34 | * @default false
35 | */
36 | includeSize?: boolean;
37 | /**
38 | * 网络视频资源的请求头
39 | */
40 | headers?: Record;
41 | }
42 |
43 | interface VideoThumbnailResult {
44 | uri?: string;
45 | width?: number;
46 | height?: number;
47 | size?: number;
48 | }
49 |
50 | type DocumentCameraResultType = 'pdf' | 'image';
51 |
52 | interface DocumentCameraOptions {
53 | /**
54 | * @default 'pdf'
55 | */
56 | type?: DocumentCameraResultType;
57 | /**
58 | * @default 1
59 | */
60 | quality?: number;
61 | }
62 |
63 | interface DocumentCameraResult {
64 | type: DocumentCameraResultType;
65 | source: string | string[];
66 | }
67 |
68 | interface VideoEditorOptions {
69 | /**
70 | * The maximum duration, in seconds, permitted for trimmed movies saved by the video editor.
71 | * The system-enforced maximum duration for a video recording is 10 minutes; you can set this value to 10 minutes or less. The default value for this property is also 10 minutes.
72 | * @default 600
73 | */
74 | maxDuration?: number;
75 | /**
76 | * @default 'high'
77 | */
78 | quality?: 'high' | 'medium' | 'low';
79 | /**
80 | * @default 'overFullScreen'
81 | */
82 | transitionStyle?: TransitionStyle;
83 | /**
84 | * @default 'coverVertical'
85 | */
86 | presentationStyle?: PresentationStyle;
87 | }
88 |
89 | interface VideoEditorResult {
90 | uri: string;
91 | // width: number;
92 | // height: number;
93 | // duration: number;
94 | // size: number;
95 | }
96 |
97 | interface ThumbnailGeneratorOptions {
98 | path: string;
99 | width: number;
100 | height: number;
101 | scale?: number;
102 | /**
103 | * @default false
104 | */
105 | iconMode?: boolean;
106 | /**
107 | * @default 0
108 | */
109 | minimumDimension?: number;
110 | toFileAtURL?: string;
111 | /**
112 | * @default 'thumbnail'
113 | */
114 | representationType?: 'icon' | 'lowQualityThumbnail' | 'thumbnail';
115 | }
116 |
117 | interface ThumbnailGeneratorResult {
118 | path: string;
119 | }
120 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "exclude": ["example", "website"]
4 | }
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./",
4 | "paths": {
5 | "react-native-kit": ["./src/index"]
6 | },
7 | "allowUnreachableCode": false,
8 | "allowUnusedLabels": false,
9 | "esModuleInterop": true,
10 | "importsNotUsedAsValues": "error",
11 | "forceConsistentCasingInFileNames": true,
12 | "jsx": "react",
13 | "lib": ["esnext"],
14 | "module": "esnext",
15 | "moduleResolution": "node",
16 | "noFallthroughCasesInSwitch": true,
17 | "noImplicitReturns": true,
18 | "noImplicitUseStrict": false,
19 | "noStrictGenericChecks": false,
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | "resolveJsonModule": true,
23 | "skipLibCheck": true,
24 | "strict": true,
25 | "target": "esnext"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ### Installation
6 |
7 | ```
8 | $ yarn
9 | ```
10 |
11 | ### Local Development
12 |
13 | ```
14 | $ yarn start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ### Build
20 |
21 | ```
22 | $ yarn build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
27 | ### Deployment
28 |
29 | Using SSH:
30 |
31 | ```
32 | $ USE_SSH=true yarn deploy
33 | ```
34 |
35 | Not using SSH:
36 |
37 | ```
38 | $ GIT_USER= yarn deploy
39 | ```
40 |
41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
42 |
--------------------------------------------------------------------------------
/website/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/website/blog/2019-05-28-first-blog-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: first-blog-post
3 | title: First Blog Post
4 | authors:
5 | name: Gao Wei
6 | title: Docusaurus Core Team
7 | url: https://github.com/wgao19
8 | image_url: https://github.com/wgao19.png
9 | tags: [hola, docusaurus]
10 | ---
11 |
12 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
13 |
--------------------------------------------------------------------------------
/website/blog/2019-05-29-long-blog-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: long-blog-post
3 | title: Long Blog Post
4 | authors: endi
5 | tags: [hello, docusaurus]
6 | ---
7 |
8 | This is the summary of a very long blog post,
9 |
10 | Use a `` comment to limit blog post size in the list view.
11 |
12 |
13 |
14 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
15 |
16 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
17 |
18 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
19 |
20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
21 |
22 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
23 |
24 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
25 |
26 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
27 |
28 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
29 |
30 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
31 |
32 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
33 |
34 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
35 |
36 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
37 |
38 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
39 |
40 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
41 |
42 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
43 |
44 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
45 |
--------------------------------------------------------------------------------
/website/blog/2021-08-01-mdx-blog-post.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | slug: mdx-blog-post
3 | title: MDX Blog Post
4 | authors: [slorber]
5 | tags: [docusaurus]
6 | ---
7 |
8 | Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
9 |
10 | :::tip
11 |
12 | Use the power of React to create interactive blog posts.
13 |
14 | ```js
15 | alert('button clicked!')}>Click me!
16 | ```
17 |
18 | alert('button clicked!')}>Click me!
19 |
20 | :::
21 |
--------------------------------------------------------------------------------
/website/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg
--------------------------------------------------------------------------------
/website/blog/2021-08-26-welcome/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: welcome
3 | title: Welcome
4 | authors: [slorber, yangshun]
5 | tags: [facebook, hello, docusaurus]
6 | ---
7 |
8 | [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
9 |
10 | Simply add Markdown files (or folders) to the `blog` directory.
11 |
12 | Regular blog authors can be added to `authors.yml`.
13 |
14 | The blog post date can be extracted from filenames, such as:
15 |
16 | - `2019-05-30-welcome.md`
17 | - `2019-05-30-welcome/index.md`
18 |
19 | A blog post folder can be convenient to co-locate blog post images:
20 |
21 | 
22 |
23 | The blog supports tags as well!
24 |
25 | **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.
26 |
--------------------------------------------------------------------------------
/website/blog/authors.yml:
--------------------------------------------------------------------------------
1 | endi:
2 | name: Endilie Yacop Sucipto
3 | title: Maintainer of Docusaurus
4 | url: https://github.com/endiliey
5 | image_url: https://github.com/endiliey.png
6 |
7 | yangshun:
8 | name: Yangshun Tay
9 | title: Front End Engineer @ Facebook
10 | url: https://github.com/yangshun
11 | image_url: https://github.com/yangshun.png
12 |
13 | slorber:
14 | name: Sébastien Lorber
15 | title: Docusaurus maintainer
16 | url: https://sebastienlorber.com
17 | image_url: https://github.com/slorber.png
18 |
--------------------------------------------------------------------------------
/website/docs/api/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "API",
3 | "position": 4
4 | }
5 |
--------------------------------------------------------------------------------
/website/docs/api/appearance.md:
--------------------------------------------------------------------------------
1 | # Appearance
2 |
3 | Override the app's color scheme (light / dark / unspecified).
4 |
5 | ```typescript
6 | import { Appearance } from 'react-native-app-toolkit';
7 |
8 | Toolkit.setAppearanceColorScheme('dark'); // 'dark' | 'light' | 'unspecified' | null
9 | ```
10 |
--------------------------------------------------------------------------------
/website/docs/api/document-camera.md:
--------------------------------------------------------------------------------
1 | # DocumentCamera
2 |
3 | Scan documents with the camera.
4 |
5 | 
6 |
7 | ```typescript
8 | import { DocumentCamera } from 'react-native-app-toolkit';
9 |
10 | DocumentCamera.open({
11 | type: 'image',
12 | quality: 0.8,
13 | }).then((result) => {
14 | /*
15 | {
16 | type: 'image',
17 | source: ['/private/Application/tmp/react-native-kit/9DE1991A-EFA0-4507-AA2E-6FC9E4BE3ADB.jpg']
18 | }
19 | */
20 | });
21 |
22 | Toolkit.openDocumentCamera({
23 | type: 'pdf',
24 | }).then((result) => {
25 | /*
26 | {
27 | type: 'pdf',
28 | source: "/private/Application/tmp/react-native-kit/9DE1991A-EFA0-4507-AA2E-6FC9E4BE3ADB.pdf"
29 | }
30 | */
31 | });
32 | ```
33 |
--------------------------------------------------------------------------------
/website/docs/api/quick-look.md:
--------------------------------------------------------------------------------
1 | # QuickLook
2 |
3 | Preview files using QuickLook framework. Support for local and remote files.
4 | QuickLook can generate previews for common file types, including:
5 |
6 | - iWork and Microsoft Office documents
7 | - Images
8 | - Live Photos
9 | - Text files
10 | - PDFs
11 | - Audio and video files
12 | - Augmented reality objects that use the usdz file format (iOS and iPadOS only)
13 |
14 | ### Example:
15 |
16 | ```tsx
17 | import { QuickLook } from 'react-native-app-toolkit';
18 |
19 | function Home() {
20 | return (
21 |
26 | );
27 | }
28 | ```
29 |
--------------------------------------------------------------------------------
/website/docs/api/thumbnail-generator.md:
--------------------------------------------------------------------------------
1 | # ThumbnailGenerator
2 |
3 | Generate thumbnails for common file types, including:
4 |
5 | - iWork and Microsoft Office documents
6 | - Images
7 | - Live Photos
8 | - Text files
9 | - PDFs
10 | - Audio and video files
11 |
12 | ```typescript
13 | import { ThumbnailGenerator } from 'react-native-app-toolkit';
14 |
15 | ThumbnailGenerator.generate({
16 | path: '/private/var/Application/9DE1991A-EFA0-4507-AA2E-6FC9E4BE3ADB.pdf',
17 | width: 100,
18 | height: 100,
19 | }).then((res) => {
20 | /*
21 | {
22 | path: "/private/Application/tmp/react-native-kit/9DE1991A-EFA0-4507-AA2E-6FC9E4BE3ADB.jpg"
23 | }
24 | */
25 | });
26 | ```
27 |
--------------------------------------------------------------------------------
/website/docs/api/video-editor.md:
--------------------------------------------------------------------------------
1 | # VideoEditor
2 |
3 | Open a video editor for trimming video frames.
4 |
5 | ```typescript
6 | import { VideoEditor } from 'react-native-app-toolkit';
7 |
8 | VideoEditor.open(
9 | '/private/Application/tmp/react-native-kit/9DE1991A-EFA0-4507-AA2E-89C9E4BE3ADB.mp4',
10 | {
11 | maxDuration: 600,
12 | quality: 'high',
13 | }
14 | ).then((result) => {
15 | /*
16 | {
17 | uri: '/private/Application/tmp/react-native-kit/9DE1991A-EFA0-4507-ABCD-6FC9E4BE3ADB.mp4'
18 | }
19 | */
20 | });
21 | ```
22 |
--------------------------------------------------------------------------------
/website/docs/api/video-thumbnail.md:
--------------------------------------------------------------------------------
1 | # VideoThumbnail
2 |
3 | Allows you to generate images from video files to use as thumbnails
4 |
5 | ```typescript
6 | import { VideoThumbnail } from 'react-native-app-toolkit';
7 |
8 | VideoThumbnail.getThumbnail(
9 | 'https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4',
10 | {
11 | time: 1000, // ms
12 | quality: 0.8,
13 | }
14 | ).then((res) => {
15 | // VideoThumbnailsResult
16 | });
17 | ```
18 |
19 | #### `VideoThumbnailsOptions`
20 |
21 | | Name | Type | Description |
22 | | --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23 | | **quality** | number | A value in range 0.0 - 1.0 specifying quality level of the result image. 1 means no compression (highest quality) and 0 the highest compression (lowest quality). |
24 | | **time** | number | The time position where the image will be retrieved in ms. |
25 | | **includeSize** | boolean | Include image file size |
26 | | **headers** | object | In case sourceFilename is a remote URI, headers object is passed in a network request. |
27 | | |
28 |
29 | #### `VideoThumbnailsResult`
30 |
31 | | Name | Type | Description |
32 | | ---------- | ------ | ---------------------------- |
33 | | **uri** | string | uri to the created image. |
34 | | **width** | number | Width of the created image. |
35 | | **height** | number | Height of the created image. |
36 | | **size** | number | Size of the created image. |
37 |
--------------------------------------------------------------------------------
/website/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | ---
4 |
5 | # Installation
6 |
7 | If you are using `react-native >= 0.60` you just need to do a simple:
8 |
9 | ```shell
10 | yarn add react-native-app-toolkit
11 | ```
12 |
13 | Or if are using npm:
14 |
15 | ```shell
16 | npm i react-native-app-toolkit --save
17 | ```
18 |
19 | After that, we need to install the dependencies to use the project on iOS(you can skip this part, if you are using this on Android).
20 |
21 | Now run a simple: `npx pod-install` or `cd ios && pod install`. After that, you should be able to use the library on both Platforms, iOS and Android.
22 |
--------------------------------------------------------------------------------
/website/docs/troubleshooting.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 5
3 | ---
4 |
5 | # Troubleshooting
6 |
--------------------------------------------------------------------------------
/website/docs/usage.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | ---
4 |
5 | # Usage
6 |
7 | ## Example
8 |
9 | ```tsx
10 | import { ThumbnailGenerator } from 'react-native-app-toolkit';
11 |
12 | ThumbnailGenerator.generate({
13 | path: '/private/var/Application/9DE1991A-EFA0-4507-AA2E-6FC9E4BE3ADB.pdf',
14 | width: 100,
15 | height: 100,
16 | }).then((res) => {
17 | // ThumbnailGeneratorResult
18 | });
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docusaurus.config.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | // Note: type annotations allow type checking and IDEs autocompletion
3 |
4 | const lightCodeTheme = require('prism-react-renderer/themes/github');
5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula');
6 |
7 | /** @type {import('@docusaurus/types').Config} */
8 | const config = {
9 | title: 'React Native App Toolkit',
10 | tagline: 'High-quality toolkit for React Native using native code.',
11 | url: 'https://luoxuhai.github.com',
12 | baseUrl: '/react-native-app-toolkit/',
13 | onBrokenLinks: 'throw',
14 | onBrokenMarkdownLinks: 'warn',
15 | favicon: 'img/favicon.ico',
16 | organizationName: 'luoxuhai', // Usually your GitHub org/user name.
17 | projectName: 'react-native-app-toolkit', // Usually your repo name.
18 | trailingSlash: false,
19 |
20 | presets: [
21 | [
22 | 'classic',
23 | /** @type {import('@docusaurus/preset-classic').Options} */
24 | ({
25 | docs: {
26 | sidebarPath: require.resolve('./sidebars.js'),
27 | // Please change this to your repo.
28 | editUrl:
29 | 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
30 | },
31 | theme: {
32 | customCss: require.resolve('./src/css/custom.css'),
33 | },
34 | }),
35 | ],
36 | ],
37 |
38 | themeConfig:
39 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
40 | ({
41 | navbar: {
42 | title: 'react-native-app-toolkit',
43 | logo: {
44 | alt: 'Logo',
45 | src: 'img/logo.svg',
46 | },
47 | items: [
48 | {
49 | type: 'doc',
50 | docId: 'getting-started',
51 | position: 'left',
52 | label: 'Docs',
53 | },
54 | {
55 | href: 'https://github.com/luoxuhai/react-native-app-toolkit',
56 | label: 'GitHub',
57 | position: 'right',
58 | },
59 | ],
60 | },
61 | footer: {
62 | style: 'dark',
63 | links: [
64 | {
65 | title: 'Docs',
66 | items: [
67 | {
68 | label: 'Installation',
69 | to: '/docs/getting-started',
70 | },
71 | ],
72 | },
73 | {
74 | title: 'Community',
75 | items: [
76 | {
77 | label: 'Discussions',
78 | href: 'https://github.com/luoxuhai/react-native-app-toolkit/discussions',
79 | },
80 | {
81 | label: 'Issues',
82 | href: 'https://github.com/luoxuhai/react-native-app-toolkit/issues',
83 | },
84 | {
85 | label: 'Stack Overflow',
86 | href: 'https://stackoverflow.com/questions/tagged/react-native-app-toolkit',
87 | },
88 | ],
89 | },
90 | {
91 | title: 'More',
92 | items: [
93 | {
94 | label: 'GitHub',
95 | href: 'https://github.com/luoxuhai/react-native-app-toolkit',
96 | },
97 | {
98 | label: 'Twitter',
99 | href: 'https://twitter.com/LuoXuhai',
100 | },
101 | ],
102 | },
103 | ],
104 | copyright: `Copyright © ${new Date().getFullYear()} luoxuhai. Built with Docusaurus.`,
105 | },
106 | prism: {
107 | theme: lightCodeTheme,
108 | darkTheme: darkCodeTheme,
109 | },
110 | }),
111 | };
112 |
113 | module.exports = config;
114 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-app-toolkit-website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "docusaurus": "docusaurus",
7 | "start": "docusaurus start",
8 | "build": "docusaurus build",
9 | "swizzle": "docusaurus swizzle",
10 | "deploy": "docusaurus deploy",
11 | "clear": "docusaurus clear",
12 | "serve": "docusaurus serve",
13 | "write-translations": "docusaurus write-translations",
14 | "write-heading-ids": "docusaurus write-heading-ids"
15 | },
16 | "dependencies": {
17 | "@docusaurus/core": "2.0.0-beta.18",
18 | "@docusaurus/preset-classic": "2.0.0-beta.18",
19 | "@mdx-js/react": "^1.6.22",
20 | "clsx": "^1.1.1",
21 | "prism-react-renderer": "^1.3.1",
22 | "react": "^17.0.2",
23 | "react-dom": "^17.0.2"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.5%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | },
37 | "devDependencies": {
38 | "@docusaurus/module-type-aliases": "^2.0.0-beta.18",
39 | "@tsconfig/docusaurus": "^1.0.5",
40 | "typescript": "^4.6.3"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/website/sidebars.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creating a sidebar enables you to:
3 | - create an ordered group of docs
4 | - render a sidebar for each doc of that group
5 | - provide next/previous navigation
6 |
7 | The sidebars can be generated from the filesystem, or explicitly defined here.
8 |
9 | Create as many sidebars as you want.
10 | */
11 |
12 | // @ts-check
13 |
14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
15 | const sidebars = {
16 | // By default, Docusaurus generates a sidebar from the docs folder structure
17 | tutorialSidebar: [
18 | {
19 | type: 'autogenerated',
20 | dirName: '.',
21 | // items: ['getting-started'],
22 | },
23 | ],
24 | // componentsSidebar: [
25 | // {
26 | // type: 'category',
27 | // label: 'Components',
28 | // items: ['components'],
29 | // },
30 | // ],
31 | // apiSidebar: [
32 | // {
33 | // type: 'category',
34 | // label: 'API',
35 | // items: ['api'],
36 | // },
37 | // ],
38 | // hooksSidebar: [{}],
39 | // But you can create a sidebar manually
40 | /*
41 | tutorialSidebar: [
42 | {
43 | type: 'category',
44 | label: 'Tutorial',
45 | items: ['hello'],
46 | },
47 | ],
48 | */
49 | };
50 |
51 | module.exports = sidebars;
52 |
--------------------------------------------------------------------------------
/website/src/components/HomepageFeatures/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import clsx from 'clsx';
3 | import styles from './styles.module.css';
4 |
5 | const FeatureList = [
6 | {
7 | title: 'Easy to Use',
8 | Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
9 | description: (
10 | <>
11 | Docusaurus was designed from the ground up to be easily installed and
12 | used to get your website up and running quickly.
13 | >
14 | ),
15 | },
16 | {
17 | title: 'Focus on What Matters',
18 | Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
19 | description: (
20 | <>
21 | Docusaurus lets you focus on your docs, and we'll do the chores. Go
22 | ahead and move your docs into the docs
directory.
23 | >
24 | ),
25 | },
26 | {
27 | title: 'Powered by React',
28 | Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
29 | description: (
30 | <>
31 | Extend or customize your website layout by reusing React. Docusaurus can
32 | be extended while reusing the same header and footer.
33 | >
34 | ),
35 | },
36 | ];
37 |
38 | function Feature({ Svg, title, description }) {
39 | return (
40 |
41 |
42 |
43 |
44 |
45 |
{title}
46 |
{description}
47 |
48 |
49 | );
50 | }
51 |
52 | export default function HomepageFeatures() {
53 | return (
54 |
55 |
56 |
57 | {FeatureList.map((props, idx) => (
58 |
59 | ))}
60 |
61 |
62 |
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/website/src/components/HomepageFeatures/styles.module.css:
--------------------------------------------------------------------------------
1 | .features {
2 | display: flex;
3 | align-items: center;
4 | padding: 2rem 0;
5 | width: 100%;
6 | }
7 |
8 | .featureSvg {
9 | height: 200px;
10 | width: 200px;
11 | }
12 |
--------------------------------------------------------------------------------
/website/src/css/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 | /* You can override the default Infima variables here. */
8 | :root {
9 | --ifm-color-primary: #2e8555;
10 | --ifm-color-primary-dark: #29784c;
11 | --ifm-color-primary-darker: #277148;
12 | --ifm-color-primary-darkest: #205d3b;
13 | --ifm-color-primary-light: #33925d;
14 | --ifm-color-primary-lighter: #359962;
15 | --ifm-color-primary-lightest: #3cad6e;
16 | --ifm-code-font-size: 95%;
17 | }
18 |
19 | /* For readability concerns, you should choose a lighter palette in dark mode. */
20 | [data-theme='dark'] {
21 | --ifm-color-primary: #25c2a0;
22 | --ifm-color-primary-dark: #21af90;
23 | --ifm-color-primary-darker: #1fa588;
24 | --ifm-color-primary-darkest: #1a8870;
25 | --ifm-color-primary-light: #29d5b0;
26 | --ifm-color-primary-lighter: #32d8b4;
27 | --ifm-color-primary-lightest: #4fddbf;
28 | }
29 |
30 | .docusaurus-highlight-code-line {
31 | background-color: rgba(0, 0, 0, 0.1);
32 | display: block;
33 | margin: 0 calc(-1 * var(--ifm-pre-padding));
34 | padding: 0 var(--ifm-pre-padding);
35 | }
36 |
37 | [data-theme='dark'] .docusaurus-highlight-code-line {
38 | background-color: rgba(0, 0, 0, 0.3);
39 | }
40 |
--------------------------------------------------------------------------------
/website/src/pages/index.module.css:
--------------------------------------------------------------------------------
1 | /**
2 | * CSS files with the .module.css suffix will be treated as CSS modules
3 | * and scoped locally.
4 | */
5 |
6 | .heroBanner {
7 | padding: 4rem 0;
8 | text-align: center;
9 | position: relative;
10 | overflow: hidden;
11 | }
12 |
13 | @media screen and (max-width: 996px) {
14 | .heroBanner {
15 | padding: 2rem;
16 | }
17 | }
18 |
19 | .buttons {
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | }
24 |
--------------------------------------------------------------------------------
/website/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import clsx from 'clsx';
3 | import Layout from '@theme/Layout';
4 | import Link from '@docusaurus/Link';
5 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
6 | import styles from './index.module.css';
7 | import HomepageFeatures from '@site/src/components/HomepageFeatures';
8 |
9 | function HomepageHeader() {
10 | const { siteConfig } = useDocusaurusContext();
11 | return (
12 |
26 | );
27 | }
28 |
29 | export default function Home() {
30 | const { siteConfig } = useDocusaurusContext();
31 | return (
32 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/website/src/pages/markdown-page.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Markdown page example
3 | ---
4 |
5 | # Markdown page example
6 |
7 | You don't need React to write simple standalone pages.
8 |
--------------------------------------------------------------------------------
/website/static/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/.nojekyll
--------------------------------------------------------------------------------
/website/static/img/docusaurus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/img/docusaurus.png
--------------------------------------------------------------------------------
/website/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/img/favicon.ico
--------------------------------------------------------------------------------
/website/static/img/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/static/img/tutorial/docsVersionDropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/img/tutorial/docsVersionDropdown.png
--------------------------------------------------------------------------------
/website/static/img/tutorial/localeDropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/img/tutorial/localeDropdown.png
--------------------------------------------------------------------------------
/website/static/screenshot/IMG_2589.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoxuhai/react-native-app-toolkit/fdacdb36a434640c7878e0183e90183fc180d230/website/static/screenshot/IMG_2589.PNG
--------------------------------------------------------------------------------
/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/docusaurus/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------