├── .buckconfig
├── .editorconfig
├── .eslintrc.js
├── .gitattributes
├── .gitignore
├── .prettierrc.js
├── .watchmanconfig
├── App.tsx
├── LICENSE
├── README.md
├── __tests__
└── App-test.tsx
├── android
├── app
│ ├── _BUCK
│ ├── build.gradle
│ ├── build_defs.bzl
│ ├── debug.keystore
│ ├── proguard-rules.pro
│ ├── src
│ │ ├── debug
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── tomatox_mobile
│ │ │ │ └── ReactNativeFlipper.java
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── AntDesign.ttf
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── Feather.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── FontAwesome5_Brands.ttf
│ │ │ │ ├── FontAwesome5_Regular.ttf
│ │ │ │ ├── FontAwesome5_Solid.ttf
│ │ │ │ ├── Fontisto.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── MaterialCommunityIcons.ttf
│ │ │ │ ├── MaterialIcons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── SimpleLineIcons.ttf
│ │ │ │ ├── Zocial.ttf
│ │ │ │ ├── antfill.ttf
│ │ │ │ └── antoutline.ttf
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── tomatox_mobile
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── res
│ │ │ ├── drawable-xxhdpi
│ │ │ └── launch_screen.png
│ │ │ ├── layout
│ │ │ └── launch_screen.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ │ └── xml
│ │ │ └── network_strategy.xml
│ └── tomatox.keystore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── app.json
├── babel.config.js
├── docs
└── product
│ ├── TOMATOX_MOBILE_1.png
│ ├── TOMATOX_MOBILE_2.png
│ ├── TOMATOX_MOBILE_3.png
│ ├── TOMATOX_MOBILE_4.png
│ ├── TOMATOX_MOBILE_5.png
│ ├── TOMATOX_MOBILE_6.png
│ └── TOMATOX_MOBILE_7.png
├── index.js
├── ios
├── Podfile
├── Podfile.lock
├── TOMATOX_MOBILE.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── TOMATOX_MOBILE.xcscheme
├── TOMATOX_MOBILE.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── TOMATOX_MOBILE
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── main.m
├── TOMATOX_MOBILETests
│ ├── Info.plist
│ └── TOMATOX_MOBILETests.m
└── bundle
│ └── assets
│ ├── app.json
│ └── src
│ └── images
│ └── png
│ ├── loading.png
│ └── tomatox.png
├── metro.config.js
├── package-lock.json
├── package.json
├── react-native.config.js
├── src
├── components
│ ├── navigatior
│ │ ├── custom-container.tsx
│ │ ├── custom-stack.tsx
│ │ └── custom-tab.tsx
│ ├── tomatox-card
│ │ └── tomatox-card.tsx
│ ├── tomatox-developing
│ │ └── tomatox-developing.tsx
│ ├── tomatox-drawer
│ │ ├── resouce-info.tsx
│ │ └── tomatox-drawer.tsx
│ ├── tomatox-flat-list
│ │ └── tomatox-flat-list.tsx
│ ├── tomatox-header
│ │ └── tomatox-header.tsx
│ ├── tomatox-video
│ │ └── tomatox-video.tsx
│ └── tomatox-waterfall
│ │ └── tomatox-waterfall.tsx
├── images
│ └── png
│ │ ├── loading.png
│ │ └── tomatox.png
├── types
│ └── types.d.ts
├── utils
│ ├── constants.ts
│ ├── filterResources.ts
│ ├── request.ts
│ ├── storage
│ │ ├── data-converter.ts
│ │ ├── origins-storage.ts
│ │ ├── storage.ts
│ │ └── table-define.ts
│ ├── theme.ts
│ └── time-converter.ts
└── views
│ ├── collect
│ └── collect.tsx
│ ├── history
│ └── history.tsx
│ ├── live
│ └── live.tsx
│ ├── origins
│ └── origins.tsx
│ ├── player
│ └── player.tsx
│ ├── recommend
│ └── recommend.tsx
│ ├── search
│ └── search.tsx
│ └── setting
│ └── setting.tsx
└── tsconfig.json
/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Windows files
2 | [*.bat]
3 | end_of_line = crlf
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native-community',
4 | rules: {
5 | 'prettier/prettier': 0,
6 | 'react-hooks/rules-of-hooks': 0
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Windows files should use crlf line endings
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | *.bat text eol=crlf
4 |
--------------------------------------------------------------------------------
/.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 |
32 | # node.js
33 | #
34 | node_modules/
35 | npm-debug.log
36 | yarn-error.log
37 |
38 | # BUCK
39 | buck-out/
40 | \.buckd/
41 | *.keystore
42 | !debug.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # CocoaPods
59 | /ios/Pods/
60 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | bracketSpacing: false,
3 | jsxBracketSameLine: true,
4 | singleQuote: true,
5 | trailingComma: 'all',
6 | arrowParens: 'avoid',
7 | };
8 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import 'react-native-gesture-handler';
3 | import CustomContainer from './src/components/navigatior/custom-container';
4 | import Orientation from 'react-native-orientation-locker';
5 | import {StatusBar, View} from 'react-native';
6 | import {TOMATOX_THEME} from './src/utils/theme';
7 | import initStorage from './src/utils/storage/storage';
8 | import {querySearchIndex} from './src/utils/request';
9 |
10 | Orientation.lockToPortrait();
11 |
12 | const App = () => {
13 | const [isInit, setIsInit] = useState(false);
14 | useEffect(() => {
15 | querySearchIndex();
16 | initStorage().then(() => {
17 | setIsInit(true);
18 | });
19 | }, []);
20 |
21 | return isInit ?
22 |
23 |
27 |
28 |
29 |
30 | :
31 | <>>;
32 | };
33 |
34 | export default App;
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Freeless
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TOMATOX_MOBILE
2 | 在线免费视频播放软件-移动端,日剧、韩剧、美剧、泰剧、vip视频,资源丰富,欢迎使用!
3 |
4 | ### 软件截图
5 | 
6 | 
7 | 
8 | 
9 | 
10 | 
11 | 
12 |
--------------------------------------------------------------------------------
/__tests__/App-test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../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 |
--------------------------------------------------------------------------------
/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.tomatox_mobile",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.tomatox_mobile",
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 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 |
5 | /**
6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7 | * and bundleReleaseJsAndAssets).
8 | * These basically call `react-native bundle` with the correct arguments during the Android build
9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10 | * bundle directly from the development server. Below you can see all the possible configurations
11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
12 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
13 | *
14 | * project.ext.react = [
15 | * // the name of the generated asset file containing your JS bundle
16 | * bundleAssetName: "index.android.bundle",
17 | *
18 | * // the entry file for bundle generation. If none specified and
19 | * // "index.android.js" exists, it will be used. Otherwise "index.js" is
20 | * // default. Can be overridden with ENTRY_FILE environment variable.
21 | * entryFile: "index.android.js",
22 | *
23 | * // https://reactnative.dev/docs/performance#enable-the-ram-format
24 | * bundleCommand: "ram-bundle",
25 | *
26 | * // whether to bundle JS and assets in debug mode
27 | * bundleInDebug: false,
28 | *
29 | * // whether to bundle JS and assets in release mode
30 | * bundleInRelease: true,
31 | *
32 | * // whether to bundle JS and assets in another build variant (if configured).
33 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
34 | * // The configuration property can be in the following formats
35 | * // 'bundleIn${productFlavor}${buildType}'
36 | * // 'bundleIn${buildType}'
37 | * // bundleInFreeDebug: true,
38 | * // bundleInPaidRelease: true,
39 | * // bundleInBeta: true,
40 | *
41 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
42 | * // for example: to disable dev mode in the staging build type (if configured)
43 | * devDisabledInStaging: true,
44 | * // The configuration property can be in the following formats
45 | * // 'devDisabledIn${productFlavor}${buildType}'
46 | * // 'devDisabledIn${buildType}'
47 | *
48 | * // the root of your project, i.e. where "package.json" lives
49 | * root: "../../",
50 | *
51 | * // where to put the JS bundle asset in debug mode
52 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
53 | *
54 | * // where to put the JS bundle asset in release mode
55 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
56 | *
57 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
58 | * // require('./image.png')), in debug mode
59 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
60 | *
61 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
62 | * // require('./image.png')), in release mode
63 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
64 | *
65 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
66 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
67 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
68 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
69 | * // for example, you might want to remove it from here.
70 | * inputExcludes: ["android/**", "ios/**"],
71 | *
72 | * // override which node gets called and with what additional arguments
73 | * nodeExecutableAndArgs: ["node"],
74 | *
75 | * // supply additional arguments to the packager
76 | * extraPackagerArgs: []
77 | * ]
78 | */
79 |
80 | project.ext.react = [
81 | enableHermes: false, // clean and rebuild if changing
82 | ]
83 |
84 | apply from: "../../node_modules/react-native/react.gradle"
85 |
86 | /**
87 | * Set this to true to create two separate APKs instead of one:
88 | * - An APK that only works on ARM devices
89 | * - An APK that only works on x86 devices
90 | * The advantage is the size of the APK is reduced by about 4MB.
91 | * Upload all the APKs to the Play Store and people will download
92 | * the correct one based on the CPU architecture of their device.
93 | */
94 | def enableSeparateBuildPerCPUArchitecture = false
95 |
96 | /**
97 | * Run Proguard to shrink the Java bytecode in release builds.
98 | */
99 | def enableProguardInReleaseBuilds = false
100 |
101 | /**
102 | * The preferred build flavor of JavaScriptCore.
103 | *
104 | * For example, to use the international variant, you can use:
105 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
106 | *
107 | * The international variant includes ICU i18n library and necessary data
108 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
109 | * give correct results when using with locales other than en-US. Note that
110 | * this variant is about 6MiB larger per architecture than default.
111 | */
112 | def jscFlavor = 'org.webkit:android-jsc:+'
113 |
114 | /**
115 | * Whether to enable the Hermes VM.
116 | *
117 | * This should be set on project.ext.react and mirrored here. If it is not set
118 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
119 | * and the benefits of using Hermes will therefore be sharply reduced.
120 | */
121 | def enableHermes = project.ext.react.get("enableHermes", false);
122 |
123 | android {
124 | ndkVersion rootProject.ext.ndkVersion
125 |
126 | compileSdkVersion rootProject.ext.compileSdkVersion
127 |
128 | compileOptions {
129 | sourceCompatibility JavaVersion.VERSION_1_8
130 | targetCompatibility JavaVersion.VERSION_1_8
131 | }
132 |
133 | defaultConfig {
134 | applicationId "com.tomatox_mobile"
135 | minSdkVersion rootProject.ext.minSdkVersion
136 | targetSdkVersion rootProject.ext.targetSdkVersion
137 | versionCode 1
138 | versionName "1.0"
139 | }
140 | splits {
141 | abi {
142 | reset()
143 | enable enableSeparateBuildPerCPUArchitecture
144 | universalApk false // If true, also generate a universal APK
145 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
146 | }
147 | }
148 | signingConfigs {
149 | debug {
150 | storeFile file('debug.keystore')
151 | storePassword 'android'
152 | keyAlias 'androiddebugkey'
153 | keyPassword 'android'
154 | }
155 | release {
156 | if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
157 | storeFile file(MYAPP_RELEASE_STORE_FILE)
158 | storePassword MYAPP_RELEASE_STORE_PASSWORD
159 | keyAlias MYAPP_RELEASE_KEY_ALIAS
160 | keyPassword MYAPP_RELEASE_KEY_PASSWORD
161 | }
162 | }
163 | }
164 | buildTypes {
165 | debug {
166 | signingConfig signingConfigs.debug
167 | }
168 | release {
169 | // Caution! In production, you need to generate your own keystore file.
170 | // see https://reactnative.dev/docs/signed-apk-android.
171 | signingConfig signingConfigs.debug
172 | minifyEnabled enableProguardInReleaseBuilds
173 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
174 | signingConfig signingConfigs.release
175 | }
176 | }
177 |
178 | // applicationVariants are e.g. debug, release
179 | applicationVariants.all { variant ->
180 | variant.outputs.each { output ->
181 | // For each separate APK per architecture, set a unique version code as described here:
182 | // https://developer.android.com/studio/build/configure-apk-splits.html
183 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
184 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
185 | def abi = output.getFilter(OutputFile.ABI)
186 | if (abi != null) { // null for the universal-debug, universal-release variants
187 | output.versionCodeOverride =
188 | defaultConfig.versionCode * 1000 + versionCodes.get(abi)
189 | }
190 |
191 | }
192 | }
193 | lintOptions {
194 | checkReleaseBuilds false
195 | abortOnError false
196 | }
197 | dexOptions {
198 | javaMaxHeapSize "6g"
199 | }
200 | }
201 |
202 | dependencies {
203 | implementation fileTree(dir: "libs", include: ["*.jar"])
204 | //noinspection GradleDynamicVersion
205 | implementation "com.facebook.react:react-native:+" // From node_modules
206 | implementation "androidx.appcompat:appcompat:1.1.0-rc1"
207 |
208 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
209 |
210 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
211 | exclude group:'com.facebook.fbjni'
212 | }
213 |
214 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
215 | exclude group:'com.facebook.flipper'
216 | exclude group:'com.squareup.okhttp3', module:'okhttp'
217 | }
218 |
219 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
220 | exclude group:'com.facebook.flipper'
221 | }
222 |
223 | if (enableHermes) {
224 | def hermesPath = "../../node_modules/hermes-engine/android/";
225 | debugImplementation files(hermesPath + "hermes-debug.aar")
226 | releaseImplementation files(hermesPath + "hermes-release.aar")
227 | } else {
228 | implementation jscFlavor
229 | }
230 | }
231 |
232 | // Run this once to be able to run the application with BUCK
233 | // puts all compile dependencies into folder libs for BUCK to use
234 | task copyDownloadableDepsToLibs(type: Copy) {
235 | from configurations.compile
236 | into 'libs'
237 | }
238 |
239 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
240 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/debug.keystore
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/android/app/src/debug/java/com/tomatox_mobile/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its 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.tomatox_mobile;
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.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | public class ReactNativeFlipper {
28 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
29 | if (FlipperUtils.shouldEnableFlipper(context)) {
30 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
31 |
32 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
33 | client.addPlugin(new ReactFlipperPlugin());
34 | client.addPlugin(new DatabasesFlipperPlugin(context));
35 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
36 | client.addPlugin(CrashReporterPlugin.getInstance());
37 |
38 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
39 | NetworkingModule.setCustomClientBuilder(
40 | new NetworkingModule.CustomClientBuilder() {
41 | @Override
42 | public void apply(OkHttpClient.Builder builder) {
43 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
44 | }
45 | });
46 | client.addPlugin(networkFlipperPlugin);
47 | client.start();
48 |
49 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
50 | // Hence we run if after all native modules have been initialized
51 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
52 | if (reactContext == null) {
53 | reactInstanceManager.addReactInstanceEventListener(
54 | new ReactInstanceManager.ReactInstanceEventListener() {
55 | @Override
56 | public void onReactContextInitialized(ReactContext reactContext) {
57 | reactInstanceManager.removeReactInstanceEventListener(this);
58 | reactContext.runOnNativeModulesQueueThread(
59 | new Runnable() {
60 | @Override
61 | public void run() {
62 | client.addPlugin(new FrescoFlipperPlugin());
63 | }
64 | });
65 | }
66 | });
67 | } else {
68 | client.addPlugin(new FrescoFlipperPlugin());
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/AntDesign.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/AntDesign.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Feather.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Fontisto.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Fontisto.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/antfill.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/antfill.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/antoutline.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/assets/fonts/antoutline.ttf
--------------------------------------------------------------------------------
/android/app/src/main/java/com/tomatox_mobile/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.tomatox_mobile;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.ReactRootView;
6 | import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
7 | import android.os.Bundle;
8 | import org.devio.rn.splashscreen.SplashScreen;
9 |
10 | public class MainActivity extends ReactActivity {
11 |
12 | /**
13 | * Returns the name of the main component registered from JavaScript. This is used to schedule
14 | * rendering of the component.
15 | */
16 | @Override
17 | protected String getMainComponentName() {
18 | return "TOMATOX_MOBILE";
19 | }
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | SplashScreen.show(this); // program first screen
24 | super.onCreate(savedInstanceState);
25 | }
26 |
27 | @Override
28 | protected ReactActivityDelegate createReactActivityDelegate() {
29 | return new ReactActivityDelegate(this, getMainComponentName()) {
30 | @Override
31 | protected ReactRootView createRootView() {
32 | return new RNGestureHandlerEnabledRootView(MainActivity.this);
33 | }
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/tomatox_mobile/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.tomatox_mobile;
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.brentvatne.react.ReactVideoPackage;
8 | import com.BV.LinearGradient.LinearGradientPackage;
9 | import com.oblador.vectoricons.VectorIconsPackage;
10 | import com.facebook.react.ReactInstanceManager;
11 | import com.facebook.react.ReactNativeHost;
12 | import com.facebook.react.ReactPackage;
13 | import com.facebook.soloader.SoLoader;
14 | import java.lang.reflect.InvocationTargetException;
15 | import java.util.List;
16 |
17 | public class MainApplication extends Application implements ReactApplication {
18 |
19 | private final ReactNativeHost mReactNativeHost =
20 | new ReactNativeHost(this) {
21 | @Override
22 | public boolean getUseDeveloperSupport() {
23 | return BuildConfig.DEBUG;
24 | }
25 |
26 | @Override
27 | protected List getPackages() {
28 | @SuppressWarnings("UnnecessaryLocalVariable")
29 | List packages = new PackageList(this).getPackages();
30 | // Packages that cannot be autolinked yet can be added manually here, for example:
31 | // packages.add(new MyReactNativePackage());
32 | return packages;
33 | }
34 |
35 | @Override
36 | protected String getJSMainModuleName() {
37 | return "index";
38 | }
39 | };
40 |
41 | @Override
42 | public ReactNativeHost getReactNativeHost() {
43 | return mReactNativeHost;
44 | }
45 |
46 | @Override
47 | public void onCreate() {
48 | super.onCreate();
49 | SoLoader.init(this, /* native exopackage */ false);
50 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
51 | }
52 |
53 | /**
54 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like
55 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
56 | *
57 | * @param context
58 | * @param reactInstanceManager
59 | */
60 | private static void initializeFlipper(
61 | Context context, ReactInstanceManager reactInstanceManager) {
62 | if (BuildConfig.DEBUG) {
63 | try {
64 | /*
65 | We use reflection here to pick up the class that initializes Flipper,
66 | since Flipper library is not available in release mode
67 | */
68 | Class> aClass = Class.forName("com.tomatox_mobile.ReactNativeFlipper");
69 | aClass
70 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
71 | .invoke(null, context, reactInstanceManager);
72 | } catch (ClassNotFoundException e) {
73 | e.printStackTrace();
74 | } catch (NoSuchMethodException e) {
75 | e.printStackTrace();
76 | } catch (IllegalAccessException e) {
77 | e.printStackTrace();
78 | } catch (InvocationTargetException e) {
79 | e.printStackTrace();
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/launch_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/drawable-xxhdpi/launch_screen.png
--------------------------------------------------------------------------------
/android/app/src/main/res/layout/launch_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TOMATOX_MOBILE
3 |
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/network_strategy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/tomatox.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/app/tomatox.keystore
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "29.0.3"
6 | minSdkVersion = 21
7 | compileSdkVersion = 29
8 | targetSdkVersion = 29
9 | ndkVersion = "20.1.5948944"
10 | }
11 | repositories {
12 | google()
13 | jcenter()
14 | }
15 | dependencies {
16 | classpath("com.android.tools.build:gradle:4.1.0")
17 | // NOTE: Do not place your application dependencies here; they belong
18 | // in the individual module build.gradle files
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | mavenLocal()
25 | maven {
26 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
27 | url("$rootDir/../node_modules/react-native/android")
28 | }
29 | maven {
30 | // Android JSC is installed from npm
31 | url("$rootDir/../node_modules/jsc-android/dist")
32 | }
33 |
34 | google()
35 | jcenter()
36 | maven { url 'https://www.jitpack.io' }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/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: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
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.75.1
29 |
30 | # Package options
31 | MYAPP_RELEASE_STORE_FILE=tomatox.keystore
32 | MYAPP_RELEASE_KEY_ALIAS=tomatox
33 | MYAPP_RELEASE_STORE_PASSWORD=tomatox
34 | MYAPP_RELEASE_KEY_PASSWORD=tomatox
35 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or 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 UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'TOMATOX_MOBILE'
2 | include ':react-native-linear-gradient'
3 | project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
4 | include ':react-native-vector-icons'
5 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
6 | include ':@react-native-community_async-storage'
7 | project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
8 | include ':@react-native-community_cameraroll'
9 | project(':@react-native-community_cameraroll').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/cameraroll/android')
10 | include ':@react-native-community_slider'
11 | project(':@react-native-community_slider').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/slider/android')
12 | include ':react-native-pager-view'
13 | project(':react-native-pager-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-pager-view/android')
14 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
15 | include ':app'
16 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TOMATOX_MOBILE",
3 | "displayName": "TOMATOX_MOBILE"
4 | }
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_1.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_2.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_3.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_4.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_5.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_6.png
--------------------------------------------------------------------------------
/docs/product/TOMATOX_MOBILE_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/docs/product/TOMATOX_MOBILE_7.png
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import {AppRegistry} from 'react-native';
6 | import App from './App';
7 | import {name as appName} from './app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/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, '10.0'
5 |
6 | target 'TOMATOX_MOBILE' do
7 | config = use_native_modules!
8 |
9 | use_react_native!(
10 | :path => config[:reactNativePath],
11 | # to enable hermes on iOS, change `false` to `true` and then install pods
12 | :hermes_enabled => false
13 | )
14 |
15 | pod 'react-native-pager-view', :path => '../node_modules/react-native-pager-view'
16 |
17 | pod 'react-native-slider', :path => '../node_modules/@react-native-community/slider'
18 |
19 | pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
20 |
21 | pod 'BVLinearGradient', :path => '../node_modules/react-native-linear-gradient'
22 |
23 | # pod 'react-native-video-new', :path => '../node_modules/react-native-video-new'
24 |
25 | target 'TOMATOX_MOBILETests' do
26 | inherit! :complete
27 | # Pods for testing
28 | end
29 |
30 | # Enables Flipper.
31 | #
32 | # Note that if you have use_frameworks! enabled, Flipper will not work and
33 | # you should disable the next line.
34 | use_flipper!()
35 |
36 | post_install do |installer|
37 | react_native_post_install(installer)
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - boost-for-react-native (1.63.0)
3 | - BVLinearGradient (2.5.6):
4 | - React
5 | - CocoaAsyncSocket (7.6.5)
6 | - DoubleConversion (1.1.6)
7 | - FBLazyVector (0.64.1)
8 | - FBReactNativeSpec (0.64.1):
9 | - RCT-Folly (= 2020.01.13.00)
10 | - RCTRequired (= 0.64.1)
11 | - RCTTypeSafety (= 0.64.1)
12 | - React-Core (= 0.64.1)
13 | - React-jsi (= 0.64.1)
14 | - ReactCommon/turbomodule/core (= 0.64.1)
15 | - Flipper (0.75.1):
16 | - Flipper-Folly (~> 2.5)
17 | - Flipper-RSocket (~> 1.3)
18 | - Flipper-DoubleConversion (1.1.7)
19 | - Flipper-Folly (2.5.3):
20 | - boost-for-react-native
21 | - Flipper-DoubleConversion
22 | - Flipper-Glog
23 | - libevent (~> 2.1.12)
24 | - OpenSSL-Universal (= 1.1.180)
25 | - Flipper-Glog (0.3.6)
26 | - Flipper-PeerTalk (0.0.4)
27 | - Flipper-RSocket (1.3.1):
28 | - Flipper-Folly (~> 2.5)
29 | - FlipperKit (0.75.1):
30 | - FlipperKit/Core (= 0.75.1)
31 | - FlipperKit/Core (0.75.1):
32 | - Flipper (~> 0.75.1)
33 | - FlipperKit/CppBridge
34 | - FlipperKit/FBCxxFollyDynamicConvert
35 | - FlipperKit/FBDefines
36 | - FlipperKit/FKPortForwarding
37 | - FlipperKit/CppBridge (0.75.1):
38 | - Flipper (~> 0.75.1)
39 | - FlipperKit/FBCxxFollyDynamicConvert (0.75.1):
40 | - Flipper-Folly (~> 2.5)
41 | - FlipperKit/FBDefines (0.75.1)
42 | - FlipperKit/FKPortForwarding (0.75.1):
43 | - CocoaAsyncSocket (~> 7.6)
44 | - Flipper-PeerTalk (~> 0.0.4)
45 | - FlipperKit/FlipperKitHighlightOverlay (0.75.1)
46 | - FlipperKit/FlipperKitLayoutPlugin (0.75.1):
47 | - FlipperKit/Core
48 | - FlipperKit/FlipperKitHighlightOverlay
49 | - FlipperKit/FlipperKitLayoutTextSearchable
50 | - YogaKit (~> 1.18)
51 | - FlipperKit/FlipperKitLayoutTextSearchable (0.75.1)
52 | - FlipperKit/FlipperKitNetworkPlugin (0.75.1):
53 | - FlipperKit/Core
54 | - FlipperKit/FlipperKitReactPlugin (0.75.1):
55 | - FlipperKit/Core
56 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.75.1):
57 | - FlipperKit/Core
58 | - FlipperKit/SKIOSNetworkPlugin (0.75.1):
59 | - FlipperKit/Core
60 | - FlipperKit/FlipperKitNetworkPlugin
61 | - GCDWebServer (3.5.4):
62 | - GCDWebServer/Core (= 3.5.4)
63 | - GCDWebServer/Core (3.5.4)
64 | - glog (0.3.5)
65 | - libevent (2.1.12)
66 | - OpenSSL-Universal (1.1.180)
67 | - RCT-Folly (2020.01.13.00):
68 | - boost-for-react-native
69 | - DoubleConversion
70 | - glog
71 | - RCT-Folly/Default (= 2020.01.13.00)
72 | - RCT-Folly/Default (2020.01.13.00):
73 | - boost-for-react-native
74 | - DoubleConversion
75 | - glog
76 | - RCTRequired (0.64.1)
77 | - RCTSystemSetting (1.7.6):
78 | - React
79 | - RCTTypeSafety (0.64.1):
80 | - FBLazyVector (= 0.64.1)
81 | - RCT-Folly (= 2020.01.13.00)
82 | - RCTRequired (= 0.64.1)
83 | - React-Core (= 0.64.1)
84 | - React (0.64.1):
85 | - React-Core (= 0.64.1)
86 | - React-Core/DevSupport (= 0.64.1)
87 | - React-Core/RCTWebSocket (= 0.64.1)
88 | - React-RCTActionSheet (= 0.64.1)
89 | - React-RCTAnimation (= 0.64.1)
90 | - React-RCTBlob (= 0.64.1)
91 | - React-RCTImage (= 0.64.1)
92 | - React-RCTLinking (= 0.64.1)
93 | - React-RCTNetwork (= 0.64.1)
94 | - React-RCTSettings (= 0.64.1)
95 | - React-RCTText (= 0.64.1)
96 | - React-RCTVibration (= 0.64.1)
97 | - React-callinvoker (0.64.1)
98 | - React-Core (0.64.1):
99 | - glog
100 | - RCT-Folly (= 2020.01.13.00)
101 | - React-Core/Default (= 0.64.1)
102 | - React-cxxreact (= 0.64.1)
103 | - React-jsi (= 0.64.1)
104 | - React-jsiexecutor (= 0.64.1)
105 | - React-perflogger (= 0.64.1)
106 | - Yoga
107 | - React-Core/CoreModulesHeaders (0.64.1):
108 | - glog
109 | - RCT-Folly (= 2020.01.13.00)
110 | - React-Core/Default
111 | - React-cxxreact (= 0.64.1)
112 | - React-jsi (= 0.64.1)
113 | - React-jsiexecutor (= 0.64.1)
114 | - React-perflogger (= 0.64.1)
115 | - Yoga
116 | - React-Core/Default (0.64.1):
117 | - glog
118 | - RCT-Folly (= 2020.01.13.00)
119 | - React-cxxreact (= 0.64.1)
120 | - React-jsi (= 0.64.1)
121 | - React-jsiexecutor (= 0.64.1)
122 | - React-perflogger (= 0.64.1)
123 | - Yoga
124 | - React-Core/DevSupport (0.64.1):
125 | - glog
126 | - RCT-Folly (= 2020.01.13.00)
127 | - React-Core/Default (= 0.64.1)
128 | - React-Core/RCTWebSocket (= 0.64.1)
129 | - React-cxxreact (= 0.64.1)
130 | - React-jsi (= 0.64.1)
131 | - React-jsiexecutor (= 0.64.1)
132 | - React-jsinspector (= 0.64.1)
133 | - React-perflogger (= 0.64.1)
134 | - Yoga
135 | - React-Core/RCTActionSheetHeaders (0.64.1):
136 | - glog
137 | - RCT-Folly (= 2020.01.13.00)
138 | - React-Core/Default
139 | - React-cxxreact (= 0.64.1)
140 | - React-jsi (= 0.64.1)
141 | - React-jsiexecutor (= 0.64.1)
142 | - React-perflogger (= 0.64.1)
143 | - Yoga
144 | - React-Core/RCTAnimationHeaders (0.64.1):
145 | - glog
146 | - RCT-Folly (= 2020.01.13.00)
147 | - React-Core/Default
148 | - React-cxxreact (= 0.64.1)
149 | - React-jsi (= 0.64.1)
150 | - React-jsiexecutor (= 0.64.1)
151 | - React-perflogger (= 0.64.1)
152 | - Yoga
153 | - React-Core/RCTBlobHeaders (0.64.1):
154 | - glog
155 | - RCT-Folly (= 2020.01.13.00)
156 | - React-Core/Default
157 | - React-cxxreact (= 0.64.1)
158 | - React-jsi (= 0.64.1)
159 | - React-jsiexecutor (= 0.64.1)
160 | - React-perflogger (= 0.64.1)
161 | - Yoga
162 | - React-Core/RCTImageHeaders (0.64.1):
163 | - glog
164 | - RCT-Folly (= 2020.01.13.00)
165 | - React-Core/Default
166 | - React-cxxreact (= 0.64.1)
167 | - React-jsi (= 0.64.1)
168 | - React-jsiexecutor (= 0.64.1)
169 | - React-perflogger (= 0.64.1)
170 | - Yoga
171 | - React-Core/RCTLinkingHeaders (0.64.1):
172 | - glog
173 | - RCT-Folly (= 2020.01.13.00)
174 | - React-Core/Default
175 | - React-cxxreact (= 0.64.1)
176 | - React-jsi (= 0.64.1)
177 | - React-jsiexecutor (= 0.64.1)
178 | - React-perflogger (= 0.64.1)
179 | - Yoga
180 | - React-Core/RCTNetworkHeaders (0.64.1):
181 | - glog
182 | - RCT-Folly (= 2020.01.13.00)
183 | - React-Core/Default
184 | - React-cxxreact (= 0.64.1)
185 | - React-jsi (= 0.64.1)
186 | - React-jsiexecutor (= 0.64.1)
187 | - React-perflogger (= 0.64.1)
188 | - Yoga
189 | - React-Core/RCTSettingsHeaders (0.64.1):
190 | - glog
191 | - RCT-Folly (= 2020.01.13.00)
192 | - React-Core/Default
193 | - React-cxxreact (= 0.64.1)
194 | - React-jsi (= 0.64.1)
195 | - React-jsiexecutor (= 0.64.1)
196 | - React-perflogger (= 0.64.1)
197 | - Yoga
198 | - React-Core/RCTTextHeaders (0.64.1):
199 | - glog
200 | - RCT-Folly (= 2020.01.13.00)
201 | - React-Core/Default
202 | - React-cxxreact (= 0.64.1)
203 | - React-jsi (= 0.64.1)
204 | - React-jsiexecutor (= 0.64.1)
205 | - React-perflogger (= 0.64.1)
206 | - Yoga
207 | - React-Core/RCTVibrationHeaders (0.64.1):
208 | - glog
209 | - RCT-Folly (= 2020.01.13.00)
210 | - React-Core/Default
211 | - React-cxxreact (= 0.64.1)
212 | - React-jsi (= 0.64.1)
213 | - React-jsiexecutor (= 0.64.1)
214 | - React-perflogger (= 0.64.1)
215 | - Yoga
216 | - React-Core/RCTWebSocket (0.64.1):
217 | - glog
218 | - RCT-Folly (= 2020.01.13.00)
219 | - React-Core/Default (= 0.64.1)
220 | - React-cxxreact (= 0.64.1)
221 | - React-jsi (= 0.64.1)
222 | - React-jsiexecutor (= 0.64.1)
223 | - React-perflogger (= 0.64.1)
224 | - Yoga
225 | - React-CoreModules (0.64.1):
226 | - FBReactNativeSpec (= 0.64.1)
227 | - RCT-Folly (= 2020.01.13.00)
228 | - RCTTypeSafety (= 0.64.1)
229 | - React-Core/CoreModulesHeaders (= 0.64.1)
230 | - React-jsi (= 0.64.1)
231 | - React-RCTImage (= 0.64.1)
232 | - ReactCommon/turbomodule/core (= 0.64.1)
233 | - React-cxxreact (0.64.1):
234 | - boost-for-react-native (= 1.63.0)
235 | - DoubleConversion
236 | - glog
237 | - RCT-Folly (= 2020.01.13.00)
238 | - React-callinvoker (= 0.64.1)
239 | - React-jsi (= 0.64.1)
240 | - React-jsinspector (= 0.64.1)
241 | - React-perflogger (= 0.64.1)
242 | - React-runtimeexecutor (= 0.64.1)
243 | - React-jsi (0.64.1):
244 | - boost-for-react-native (= 1.63.0)
245 | - DoubleConversion
246 | - glog
247 | - RCT-Folly (= 2020.01.13.00)
248 | - React-jsi/Default (= 0.64.1)
249 | - React-jsi/Default (0.64.1):
250 | - boost-for-react-native (= 1.63.0)
251 | - DoubleConversion
252 | - glog
253 | - RCT-Folly (= 2020.01.13.00)
254 | - React-jsiexecutor (0.64.1):
255 | - DoubleConversion
256 | - glog
257 | - RCT-Folly (= 2020.01.13.00)
258 | - React-cxxreact (= 0.64.1)
259 | - React-jsi (= 0.64.1)
260 | - React-perflogger (= 0.64.1)
261 | - React-jsinspector (0.64.1)
262 | - react-native-orientation-locker (1.3.1):
263 | - React-Core
264 | - react-native-pager-view (5.2.0):
265 | - React-Core
266 | - react-native-safe-area-context (3.2.0):
267 | - React-Core
268 | - react-native-slider (3.0.3):
269 | - React
270 | - react-native-splash-screen (3.2.0):
271 | - React
272 | - react-native-video (1.1.0):
273 | - React-Core
274 | - react-native-video/Video (= 1.1.0)
275 | - react-native-video/Video (1.1.0):
276 | - React-Core
277 | - React-perflogger (0.64.1)
278 | - React-RCTActionSheet (0.64.1):
279 | - React-Core/RCTActionSheetHeaders (= 0.64.1)
280 | - React-RCTAnimation (0.64.1):
281 | - FBReactNativeSpec (= 0.64.1)
282 | - RCT-Folly (= 2020.01.13.00)
283 | - RCTTypeSafety (= 0.64.1)
284 | - React-Core/RCTAnimationHeaders (= 0.64.1)
285 | - React-jsi (= 0.64.1)
286 | - ReactCommon/turbomodule/core (= 0.64.1)
287 | - React-RCTBlob (0.64.1):
288 | - FBReactNativeSpec (= 0.64.1)
289 | - RCT-Folly (= 2020.01.13.00)
290 | - React-Core/RCTBlobHeaders (= 0.64.1)
291 | - React-Core/RCTWebSocket (= 0.64.1)
292 | - React-jsi (= 0.64.1)
293 | - React-RCTNetwork (= 0.64.1)
294 | - ReactCommon/turbomodule/core (= 0.64.1)
295 | - React-RCTImage (0.64.1):
296 | - FBReactNativeSpec (= 0.64.1)
297 | - RCT-Folly (= 2020.01.13.00)
298 | - RCTTypeSafety (= 0.64.1)
299 | - React-Core/RCTImageHeaders (= 0.64.1)
300 | - React-jsi (= 0.64.1)
301 | - React-RCTNetwork (= 0.64.1)
302 | - ReactCommon/turbomodule/core (= 0.64.1)
303 | - React-RCTLinking (0.64.1):
304 | - FBReactNativeSpec (= 0.64.1)
305 | - React-Core/RCTLinkingHeaders (= 0.64.1)
306 | - React-jsi (= 0.64.1)
307 | - ReactCommon/turbomodule/core (= 0.64.1)
308 | - React-RCTNetwork (0.64.1):
309 | - FBReactNativeSpec (= 0.64.1)
310 | - RCT-Folly (= 2020.01.13.00)
311 | - RCTTypeSafety (= 0.64.1)
312 | - React-Core/RCTNetworkHeaders (= 0.64.1)
313 | - React-jsi (= 0.64.1)
314 | - ReactCommon/turbomodule/core (= 0.64.1)
315 | - React-RCTSettings (0.64.1):
316 | - FBReactNativeSpec (= 0.64.1)
317 | - RCT-Folly (= 2020.01.13.00)
318 | - RCTTypeSafety (= 0.64.1)
319 | - React-Core/RCTSettingsHeaders (= 0.64.1)
320 | - React-jsi (= 0.64.1)
321 | - ReactCommon/turbomodule/core (= 0.64.1)
322 | - React-RCTText (0.64.1):
323 | - React-Core/RCTTextHeaders (= 0.64.1)
324 | - React-RCTVibration (0.64.1):
325 | - FBReactNativeSpec (= 0.64.1)
326 | - RCT-Folly (= 2020.01.13.00)
327 | - React-Core/RCTVibrationHeaders (= 0.64.1)
328 | - React-jsi (= 0.64.1)
329 | - ReactCommon/turbomodule/core (= 0.64.1)
330 | - React-runtimeexecutor (0.64.1):
331 | - React-jsi (= 0.64.1)
332 | - ReactCommon/turbomodule/core (0.64.1):
333 | - DoubleConversion
334 | - glog
335 | - RCT-Folly (= 2020.01.13.00)
336 | - React-callinvoker (= 0.64.1)
337 | - React-Core (= 0.64.1)
338 | - React-cxxreact (= 0.64.1)
339 | - React-jsi (= 0.64.1)
340 | - React-perflogger (= 0.64.1)
341 | - RealmJS (10.4.2):
342 | - GCDWebServer
343 | - React
344 | - RNCMaskedView (0.1.11):
345 | - React
346 | - RNGestureHandler (1.10.3):
347 | - React-Core
348 | - RNReanimated (2.2.0):
349 | - DoubleConversion
350 | - FBLazyVector
351 | - FBReactNativeSpec
352 | - glog
353 | - RCT-Folly
354 | - RCTRequired
355 | - RCTTypeSafety
356 | - React
357 | - React-callinvoker
358 | - React-Core
359 | - React-Core/DevSupport
360 | - React-Core/RCTWebSocket
361 | - React-CoreModules
362 | - React-cxxreact
363 | - React-jsi
364 | - React-jsiexecutor
365 | - React-jsinspector
366 | - React-RCTActionSheet
367 | - React-RCTAnimation
368 | - React-RCTBlob
369 | - React-RCTImage
370 | - React-RCTLinking
371 | - React-RCTNetwork
372 | - React-RCTSettings
373 | - React-RCTText
374 | - React-RCTVibration
375 | - ReactCommon/turbomodule/core
376 | - Yoga
377 | - RNScreens (3.3.0):
378 | - React-Core
379 | - React-RCTImage
380 | - RNVectorIcons (8.1.0):
381 | - React-Core
382 | - Yoga (1.14.0)
383 | - YogaKit (1.18.1):
384 | - Yoga (~> 1.14)
385 |
386 | DEPENDENCIES:
387 | - BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
388 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
389 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
390 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
391 | - Flipper (~> 0.75.1)
392 | - Flipper-DoubleConversion (= 1.1.7)
393 | - Flipper-Folly (~> 2.5.3)
394 | - Flipper-Glog (= 0.3.6)
395 | - Flipper-PeerTalk (~> 0.0.4)
396 | - Flipper-RSocket (~> 1.3)
397 | - FlipperKit (~> 0.75.1)
398 | - FlipperKit/Core (~> 0.75.1)
399 | - FlipperKit/CppBridge (~> 0.75.1)
400 | - FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1)
401 | - FlipperKit/FBDefines (~> 0.75.1)
402 | - FlipperKit/FKPortForwarding (~> 0.75.1)
403 | - FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1)
404 | - FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1)
405 | - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1)
406 | - FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1)
407 | - FlipperKit/FlipperKitReactPlugin (~> 0.75.1)
408 | - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1)
409 | - FlipperKit/SKIOSNetworkPlugin (~> 0.75.1)
410 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
411 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
412 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
413 | - RCTSystemSetting (from `../node_modules/react-native-system-setting`)
414 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
415 | - React (from `../node_modules/react-native/`)
416 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
417 | - React-Core (from `../node_modules/react-native/`)
418 | - React-Core/DevSupport (from `../node_modules/react-native/`)
419 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
420 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
421 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
422 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
423 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
424 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
425 | - react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
426 | - react-native-pager-view (from `../node_modules/react-native-pager-view`)
427 | - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
428 | - "react-native-slider (from `../node_modules/@react-native-community/slider`)"
429 | - react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
430 | - react-native-video (from `../node_modules/react-native-video-new`)
431 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
432 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
433 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
434 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
435 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
436 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
437 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
438 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
439 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
440 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
441 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
442 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
443 | - RealmJS (from `../node_modules/realm`)
444 | - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
445 | - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
446 | - RNReanimated (from `../node_modules/react-native-reanimated`)
447 | - RNScreens (from `../node_modules/react-native-screens`)
448 | - RNVectorIcons (from `../node_modules/react-native-vector-icons`)
449 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
450 |
451 | SPEC REPOS:
452 | trunk:
453 | - boost-for-react-native
454 | - CocoaAsyncSocket
455 | - Flipper
456 | - Flipper-DoubleConversion
457 | - Flipper-Folly
458 | - Flipper-Glog
459 | - Flipper-PeerTalk
460 | - Flipper-RSocket
461 | - FlipperKit
462 | - GCDWebServer
463 | - libevent
464 | - OpenSSL-Universal
465 | - YogaKit
466 |
467 | EXTERNAL SOURCES:
468 | BVLinearGradient:
469 | :path: "../node_modules/react-native-linear-gradient"
470 | DoubleConversion:
471 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
472 | FBLazyVector:
473 | :path: "../node_modules/react-native/Libraries/FBLazyVector"
474 | FBReactNativeSpec:
475 | :path: "../node_modules/react-native/React/FBReactNativeSpec"
476 | glog:
477 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
478 | RCT-Folly:
479 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
480 | RCTRequired:
481 | :path: "../node_modules/react-native/Libraries/RCTRequired"
482 | RCTSystemSetting:
483 | :path: "../node_modules/react-native-system-setting"
484 | RCTTypeSafety:
485 | :path: "../node_modules/react-native/Libraries/TypeSafety"
486 | React:
487 | :path: "../node_modules/react-native/"
488 | React-callinvoker:
489 | :path: "../node_modules/react-native/ReactCommon/callinvoker"
490 | React-Core:
491 | :path: "../node_modules/react-native/"
492 | React-CoreModules:
493 | :path: "../node_modules/react-native/React/CoreModules"
494 | React-cxxreact:
495 | :path: "../node_modules/react-native/ReactCommon/cxxreact"
496 | React-jsi:
497 | :path: "../node_modules/react-native/ReactCommon/jsi"
498 | React-jsiexecutor:
499 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
500 | React-jsinspector:
501 | :path: "../node_modules/react-native/ReactCommon/jsinspector"
502 | react-native-orientation-locker:
503 | :path: "../node_modules/react-native-orientation-locker"
504 | react-native-pager-view:
505 | :path: "../node_modules/react-native-pager-view"
506 | react-native-safe-area-context:
507 | :path: "../node_modules/react-native-safe-area-context"
508 | react-native-slider:
509 | :path: "../node_modules/@react-native-community/slider"
510 | react-native-splash-screen:
511 | :path: "../node_modules/react-native-splash-screen"
512 | react-native-video:
513 | :path: "../node_modules/react-native-video-new"
514 | React-perflogger:
515 | :path: "../node_modules/react-native/ReactCommon/reactperflogger"
516 | React-RCTActionSheet:
517 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
518 | React-RCTAnimation:
519 | :path: "../node_modules/react-native/Libraries/NativeAnimation"
520 | React-RCTBlob:
521 | :path: "../node_modules/react-native/Libraries/Blob"
522 | React-RCTImage:
523 | :path: "../node_modules/react-native/Libraries/Image"
524 | React-RCTLinking:
525 | :path: "../node_modules/react-native/Libraries/LinkingIOS"
526 | React-RCTNetwork:
527 | :path: "../node_modules/react-native/Libraries/Network"
528 | React-RCTSettings:
529 | :path: "../node_modules/react-native/Libraries/Settings"
530 | React-RCTText:
531 | :path: "../node_modules/react-native/Libraries/Text"
532 | React-RCTVibration:
533 | :path: "../node_modules/react-native/Libraries/Vibration"
534 | React-runtimeexecutor:
535 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
536 | ReactCommon:
537 | :path: "../node_modules/react-native/ReactCommon"
538 | RealmJS:
539 | :path: "../node_modules/realm"
540 | RNCMaskedView:
541 | :path: "../node_modules/@react-native-community/masked-view"
542 | RNGestureHandler:
543 | :path: "../node_modules/react-native-gesture-handler"
544 | RNReanimated:
545 | :path: "../node_modules/react-native-reanimated"
546 | RNScreens:
547 | :path: "../node_modules/react-native-screens"
548 | RNVectorIcons:
549 | :path: "../node_modules/react-native-vector-icons"
550 | Yoga:
551 | :path: "../node_modules/react-native/ReactCommon/yoga"
552 |
553 | SPEC CHECKSUMS:
554 | boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
555 | BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
556 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
557 | DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
558 | FBLazyVector: 7b423f9e248eae65987838148c36eec1dbfe0b53
559 | FBReactNativeSpec: 7f49e028c153801e0c071010ef74789bce80bb85
560 | Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
561 | Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
562 | Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
563 | Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
564 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
565 | Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154
566 | FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00
567 | GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
568 | glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
569 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
570 | OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
571 | RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
572 | RCTRequired: ec2ebc96b7bfba3ca5c32740f5a0c6a014a274d2
573 | RCTSystemSetting: 5107b7350d63b3f7b42a1277d07e4e5d9df879be
574 | RCTTypeSafety: 22567f31e67c3e088c7ac23ea46ab6d4779c0ea5
575 | React: a241e3dbb1e91d06332f1dbd2b3ab26e1a4c4b9d
576 | React-callinvoker: da4d1c6141696a00163960906bc8a55b985e4ce4
577 | React-Core: 46ba164c437d7dac607b470c83c8308b05799748
578 | React-CoreModules: 217bd14904491c7b9940ff8b34a3fe08013c2f14
579 | React-cxxreact: 0090588ae6660c4615d3629fdd5c768d0983add4
580 | React-jsi: 5de8204706bd872b78ea646aee5d2561ca1214b6
581 | React-jsiexecutor: 124e8f99992490d0d13e0649d950d3e1aae06fe9
582 | React-jsinspector: 500a59626037be5b3b3d89c5151bc3baa9abf1a9
583 | react-native-orientation-locker: 998c0744e26624407dac068c04c605b4af7304a2
584 | react-native-pager-view: b72d689fb81435f2cab3d556136c83ed124426b0
585 | react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
586 | react-native-slider: e99fc201cefe81270fc9d81714a7a0f5e566b168
587 | react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
588 | react-native-video: 127a000e71aaa2dc944efb918ce03c4f709849e9
589 | React-perflogger: aad6d4b4a267936b3667260d1f649b6f6069a675
590 | React-RCTActionSheet: fc376be462c9c8d6ad82c0905442fd77f82a9d2a
591 | React-RCTAnimation: ba0a1c3a2738be224a08092fa7f1b444ab77d309
592 | React-RCTBlob: f758d4403fc5828a326dc69e27b41e1a92f34947
593 | React-RCTImage: ce57088705f4a8d03f6594b066a59c29143ba73e
594 | React-RCTLinking: 852a3a95c65fa63f657a4b4e2d3d83a815e00a7c
595 | React-RCTNetwork: 9d7ccb8a08d522d71700b4fb677d9fa28cccd118
596 | React-RCTSettings: d8aaf4389ff06114dee8c42ef5f0f2915946011e
597 | React-RCTText: 809c12ed6b261796ba056c04fcd20d8b90bcc81d
598 | React-RCTVibration: 4b99a7f5c6c0abbc5256410cc5425fb8531986e1
599 | React-runtimeexecutor: ff951a0c241bfaefc4940a3f1f1a229e7cb32fa6
600 | ReactCommon: bedc99ed4dae329c4fcf128d0c31b9115e5365ca
601 | RealmJS: 90f2a558fdda19ebb9fcbc0a52c7b1d1b049fb88
602 | RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
603 | RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
604 | RNReanimated: 9c13c86454bfd54dab7505c1a054470bfecd2563
605 | RNScreens: bf59f17fbf001f1025243eeed5f19419d3c11ef2
606 | RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
607 | Yoga: a7de31c64fe738607e7a3803e3f591a4b1df7393
608 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
609 |
610 | PODFILE CHECKSUM: 14dbfcaa32d70ed9352e1060532d873c88f99434
611 |
612 | COCOAPODS: 1.10.1
613 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE.xcodeproj/xcshareddata/xcschemes/TOMATOX_MOBILE.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 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : UIResponder
5 |
6 | @property (nonatomic, strong) UIWindow *window;
7 |
8 | @end
9 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 | #import
6 | #import "Orientation.h"
7 |
8 | #ifdef FB_SONARKIT_ENABLED
9 | #import
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 |
16 | static void InitializeFlipper(UIApplication *application) {
17 | FlipperClient *client = [FlipperClient sharedClient];
18 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
19 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
20 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
21 | [client addPlugin:[FlipperKitReactPlugin new]];
22 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
23 | [client start];
24 | }
25 | #endif
26 |
27 | @implementation AppDelegate
28 |
29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
30 | {
31 | #ifdef FB_SONARKIT_ENABLED
32 | InitializeFlipper(application);
33 | #endif
34 |
35 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
36 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
37 | moduleName:@"TOMATOX_MOBILE"
38 | initialProperties:nil];
39 |
40 | if (@available(iOS 13.0, *)) {
41 | rootView.backgroundColor = [UIColor systemBackgroundColor];
42 | } else {
43 | rootView.backgroundColor = [UIColor whiteColor];
44 | }
45 |
46 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
47 | UIViewController *rootViewController = [UIViewController new];
48 | rootViewController.view = rootView;
49 | self.window.rootViewController = rootViewController;
50 | [self.window makeKeyAndVisible];
51 | return YES;
52 | }
53 |
54 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
55 | {
56 | NSURL *jsCodeLocation;
57 | #if DEBUG
58 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
59 | #else
60 | jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
61 | #endif
62 | return jsCodeLocation;
63 | }
64 |
65 | - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
66 | return [Orientation getOrientation];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | TOMATOX_MOBILE
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 | UIAppFonts
55 |
56 | antfill.ttf
57 | antoutline.ttf
58 | AntDesign.ttf
59 | Entypo.ttf
60 | EvilIcons.ttf
61 | Feather.ttf
62 | FontAwesome.ttf
63 | FontAwesome5_Brands.ttf
64 | FontAwesome5_Regular.ttf
65 | FontAwesome5_Solid.ttf
66 | Fontisto.ttf
67 | Foundation.ttf
68 | Ionicons.ttf
69 | MaterialCommunityIcons.ttf
70 | MaterialIcons.ttf
71 | Octicons.ttf
72 | SimpleLineIcons.ttf
73 | Zocial.ttf
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILE/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILETests/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 |
--------------------------------------------------------------------------------
/ios/TOMATOX_MOBILETests/TOMATOX_MOBILETests.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 TOMATOX_MOBILETests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation TOMATOX_MOBILETests
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(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
38 | if (level >= RCTLogLevelError) {
39 | redboxError = message;
40 | }
41 | });
42 | #endif
43 |
44 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
45 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 |
48 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
49 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
50 | return YES;
51 | }
52 | return NO;
53 | }];
54 | }
55 |
56 | #ifdef DEBUG
57 | RCTSetLogFunction(RCTDefaultLogFunction);
58 | #endif
59 |
60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
62 | }
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/ios/bundle/assets/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TOMATOX_MOBILE",
3 | "displayName": "TOMATOX_MOBILE"
4 | }
--------------------------------------------------------------------------------
/ios/bundle/assets/src/images/png/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/ios/bundle/assets/src/images/png/loading.png
--------------------------------------------------------------------------------
/ios/bundle/assets/src/images/png/tomatox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/ios/bundle/assets/src/images/png/tomatox.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tomatox_mobile",
3 | "description": "A online video player for mobile",
4 | "version": "1.0.0",
5 | "private": false,
6 | "homepage": "https://github.com/yanjiaxuan/TOMATOX_MOBILE",
7 | "repository": "git@github.com:yanjiaxuan/TOMATOX_MOBILE.git",
8 | "author": {
9 | "name": "jiaxuan.yan",
10 | "email": "yanjiaxuan330544968@gmail.com"
11 | },
12 | "bugs": "https://github.com/yanjiaxuan/TOMATOX_MOBILE/issues",
13 | "license": "MIT",
14 | "scripts": {
15 | "android": "react-native run-android",
16 | "ios": "react-native run-ios",
17 | "start": "react-native start",
18 | "pack:android": "cd ./android && gradlew assembleRelease",
19 | "pack:ios": "node node_modules/react-native/local-cli/cli.js bundle --entry-file index.js --platform ios --dev false --bundle-output ./ios/bundle/index.ios.jsbundle --assets-dest ./ios/bundle",
20 | "test": "jest",
21 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
22 | },
23 | "dependencies": {
24 | "@react-native-community/masked-view": "^0.1.11",
25 | "@react-native-community/slider": "^3.0.3",
26 | "@react-navigation/bottom-tabs": "^5.11.11",
27 | "@react-navigation/drawer": "^5.12.5",
28 | "@react-navigation/material-top-tabs": "^5.3.15",
29 | "@react-navigation/native": "^5.9.4",
30 | "@react-navigation/stack": "^5.14.5",
31 | "react": "17.0.1",
32 | "react-native": "0.64.1",
33 | "react-native-drawer": "^2.5.1",
34 | "react-native-gesture-handler": "^1.10.3",
35 | "react-native-linear-gradient": "^2.5.6",
36 | "react-native-orientation-locker": "^1.3.1",
37 | "react-native-pager-view": "^5.2.0",
38 | "react-native-reanimated": "^2.2.0",
39 | "react-native-safe-area-context": "^3.2.0",
40 | "react-native-screens": "^3.3.0",
41 | "react-native-splash-screen": "^3.2.0",
42 | "react-native-system-setting": "^1.7.6",
43 | "react-native-tab-view": "^3.0.1",
44 | "react-native-vector-icons": "^8.1.0",
45 | "react-native-video-new": "^1.1.0",
46 | "react-native-xml2js": "^1.0.3",
47 | "realm": "^10.4.2"
48 | },
49 | "devDependencies": {
50 | "@babel/core": "^7.12.9",
51 | "@babel/runtime": "^7.12.5",
52 | "@react-native-community/eslint-config": "^2.0.0",
53 | "@types/jest": "^26.0.23",
54 | "@types/react-native": "^0.64.5",
55 | "@types/react-native-drawer": "^2.5.3",
56 | "@types/react-native-linear-gradient": "^2.4.0",
57 | "@types/react-native-vector-icons": "^6.4.6",
58 | "@types/react-test-renderer": "^16.9.2",
59 | "babel-jest": "^26.6.3",
60 | "eslint": "^7.14.0",
61 | "jest": "^26.6.3",
62 | "metro-react-native-babel-preset": "^0.64.0",
63 | "react-test-renderer": "17.0.1",
64 | "typescript": "^3.8.3"
65 | },
66 | "keywords": [
67 | "react",
68 | "react native",
69 | "video",
70 | "video player",
71 | "player",
72 | "online video player",
73 | "韩剧",
74 | "美剧",
75 | "日剧",
76 | "VIP视频"
77 | ],
78 | "resolutions": {
79 | "@types/react": "^17"
80 | },
81 | "jest": {
82 | "preset": "react-native",
83 | "moduleFileExtensions": [
84 | "ts",
85 | "tsx",
86 | "js",
87 | "jsx",
88 | "json",
89 | "node"
90 | ]
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | // fix onBuffer in react-native-video not work
2 | module.exports = {
3 | dependencies: {
4 | 'react-native-video-new': {
5 | platforms: {
6 | android: {
7 | sourceDir: '../node_modules/react-native-video-new/android-exoplayer',
8 | },
9 | },
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/navigatior/custom-container.tsx:
--------------------------------------------------------------------------------
1 | import CustomStack from './custom-stack'
2 |
3 | export default CustomStack
4 |
--------------------------------------------------------------------------------
/src/components/navigatior/custom-stack.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import CustomTab from './custom-tab';
3 | import Player from '../../views/player/player';
4 | import Search from '../../views/search/search';
5 | import Live from '../../views/live/live';
6 | import Origins from '../../views/origins/origins';
7 | import {NavigationContainer} from '@react-navigation/native';
8 | import {createStackNavigator} from '@react-navigation/stack';
9 |
10 | const Stack = createStackNavigator();
11 |
12 | export default function customStack() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/navigatior/custom-tab.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Recommend from '../../views/recommend/recommend';
3 | import History from '../../views/history/history';
4 | import Collect from '../../views/collect/collect';
5 | import Setting from '../../views/setting/setting';
6 | import {StyleSheet} from 'react-native';
7 | import Icon from 'react-native-vector-icons/FontAwesome5';
8 | import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
9 | import {TOMATOX_THEME} from '../../utils/theme';
10 | import {SafeAreaView} from 'react-native-safe-area-context';
11 |
12 | const Tab = createBottomTabNavigator();
13 |
14 | const style = StyleSheet.create({
15 | tabBar: {
16 | paddingTop: 7,
17 | paddingBottom: 8,
18 | height: 55,
19 | borderTopWidth: 1,
20 | borderTopColor: TOMATOX_THEME.SPLIT_LINE_COLOR,
21 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
22 | },
23 | tabBarLabel: {
24 | fontSize: 10
25 | }
26 | });
27 |
28 | export default function customTab() {
29 | return (
30 |
31 |
40 | ,
43 | }} />
44 | ,
47 | }} />
48 | ,
51 | }} />
52 | ,
55 | }} />
56 |
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/src/components/tomatox-card/tomatox-card.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
3 | import {useNavigation} from '@react-navigation/native';
4 | import {TOMATOX_THEME} from "../../utils/theme";
5 |
6 | export default function tomatoxCard(props: { data: IPlayResource }) {
7 | const {navigate} = useNavigation();
8 | return (
9 | navigate('Player', props.data)}>
10 |
15 | {props.data.name}
16 | {props.data.actor || '未知'}
17 |
18 | );
19 | }
20 |
21 | const style = StyleSheet.create({
22 | card: {
23 | width: '33.333%',
24 | height: 160,
25 | padding: 7,
26 | },
27 | cardImg: {
28 | width: '100%',
29 | height: 110,
30 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
31 | borderRadius: 5,
32 | },
33 | cardName: {
34 | color: TOMATOX_THEME.FONT_COLOR,
35 | fontSize: 12,
36 | marginTop: 4,
37 | marginBottom: 2,
38 | },
39 | cardDesc: {
40 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
41 | fontSize: 10,
42 | width: '100%',
43 | },
44 | });
45 |
--------------------------------------------------------------------------------
/src/components/tomatox-developing/tomatox-developing.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Image, Text, View} from 'react-native';
3 | import {TOMATOX_THEME} from "../../utils/theme";
4 |
5 | export default function (props: any) {
6 | return (
7 |
16 |
24 |
29 | 功能正在开发中...
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/tomatox-drawer/resouce-info.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Image, ScrollView, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
3 | import Icon from 'react-native-vector-icons/Feather';
4 | import {TOMATOX_THEME} from "../../utils/theme";
5 |
6 | export default function resourceInfo(props: {resource: IPlayResource, close: () => void}) {
7 | return (
8 |
9 |
10 | 简介
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | 剧名:
23 | {props.resource.name}
24 |
25 |
26 | 评分:
27 | {props.resource.doubanScore}
28 |
29 |
30 | 分类:
31 | {props.resource.class}
32 |
33 |
34 | 语言:
35 | {props.resource.lang}
36 |
37 |
38 | 地区:
39 | {props.resource.area}
40 |
41 |
42 | 年份:
43 | {props.resource.year}
44 |
45 |
46 | 更新时间:
47 | {props.resource.updateTime}
48 |
49 |
50 | 导演:
51 | {props.resource.director}
52 |
53 |
54 | 演员:
55 | {props.resource.actor}
56 |
57 |
58 | 标签:
59 | {props.resource.tag}
60 |
61 |
62 | {props.resource.describe}
63 |
64 |
65 |
66 |
67 | );
68 | }
69 |
70 | const style = StyleSheet.create({
71 | infoWrapper: {
72 | padding: 10,
73 | },
74 | infoTitle: {
75 | flexDirection: 'row',
76 | justifyContent: 'space-between',
77 | marginBottom: 10,
78 | },
79 | infoTitleText: {
80 | fontSize: 15,
81 | color: TOMATOX_THEME.FONT_COLOR,
82 | },
83 | infoTitleBtnWrapper: {
84 | paddingLeft: 50
85 | },
86 | infoTitleBtn: {
87 | fontSize: 20,
88 | color: TOMATOX_THEME.FONT_COLOR
89 | },
90 | infoImg: {
91 | width: 100,
92 | height: 140,
93 | position: 'absolute',
94 | right: 0,
95 | },
96 | infoItem: {
97 | color: TOMATOX_THEME.FONT_COLOR,
98 | marginBottom: 5,
99 | fontSize: 13,
100 | },
101 | infoItemTitle: {
102 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
103 | },
104 | infoDesc: {
105 | marginTop: 10,
106 | padding: 1,
107 | color: TOMATOX_THEME.FONT_COLOR
108 | },
109 | });
110 |
--------------------------------------------------------------------------------
/src/components/tomatox-drawer/tomatox-drawer.tsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import {Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
3 | import Drawer from 'react-native-drawer';
4 | import ResourceInfo from './resouce-info';
5 | import Icon from 'react-native-vector-icons/Feather';
6 | import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';
7 | import {TOMATOX_THEME} from '../../utils/theme';
8 | import {deleteData, insertOrUpdateData, queryData} from '../../utils/storage/storage';
9 | import {TABLE_NAME} from '../../utils/storage/table-define';
10 |
11 | export default function tomatoxDrawer(props: { resource: IPlayResource, curPlay: string, changePlay: (key: string) => void }) {
12 | const [showDrawer, setShowDrawer] = useState(false);
13 | const [isCollect, updateCollect] = useState(Boolean(queryData(TABLE_NAME.TOMATOX_COLLECT, props.resource.id)));
14 |
15 | function showDetailDrawer() {
16 | setShowDrawer(!showDrawer);
17 | }
18 | function developing() {
19 | Alert.alert('Developing', '功能正在开发中...');
20 | }
21 |
22 | function collectResource() {
23 | updateCollect(!isCollect);
24 | if (isCollect) {
25 | deleteData(TABLE_NAME.TOMATOX_COLLECT, props.resource.id);
26 | } else {
27 | insertOrUpdateData(TABLE_NAME.TOMATOX_COLLECT, {
28 | ...props.resource,
29 | historyPlayKey: undefined,
30 | historyPlayTime: undefined,
31 | historyPlayDesc: undefined,
32 | historyPlayDate: undefined,
33 | collectDate: Date.now(),
34 | });
35 | }
36 | }
37 |
38 | return (
39 | }
45 | styles={{
46 | drawer: { backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR },
47 | }}
48 | >
49 |
50 | {props.resource.name}
51 |
52 | {props.resource.type}
53 | {' · '}
54 | {props.resource.doubanScore}
55 |
56 |
57 |
58 |
59 |
60 | 简介
61 |
62 |
63 |
64 |
65 |
69 | 收藏
70 |
71 |
72 |
73 |
74 |
75 | 缓存
76 |
77 |
78 |
79 |
80 |
81 | 分享
82 |
83 |
84 |
85 | 选集
86 |
91 |
92 | {props.resource.playList.index.map(key => (
93 | props.changePlay(key)}>
94 |
98 | {key}
99 |
100 |
101 | ))}
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | );
110 | }
111 |
112 | const style = StyleSheet.create({
113 | playerInfoWrapper: {
114 | padding: 10,
115 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
116 | },
117 | playInfoTitle: {
118 | fontWeight: 'bold',
119 | fontSize: 15,
120 | color: TOMATOX_THEME.FONT_COLOR,
121 | },
122 | playInfoTitle2: {
123 | fontSize: 14,
124 | color: TOMATOX_THEME.FONT_COLOR,
125 | marginBottom: 10,
126 | },
127 | playInfoDesc: {
128 | fontSize: 10,
129 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
130 | marginTop: 5,
131 | marginBottom: 5,
132 | },
133 | playOptionWrapper: {
134 | flexDirection: 'row',
135 | justifyContent: 'space-around',
136 | alignItems: 'center',
137 | marginTop: 20,
138 | marginBottom: 20,
139 | },
140 | playOption: {
141 | flexDirection: 'column',
142 | alignItems: 'center',
143 | },
144 | playerOptionIcon: {
145 | fontSize: 22,
146 | color: TOMATOX_THEME.FONT_COLOR,
147 | marginBottom: 5,
148 | },
149 | playerOptionIconActive: {
150 | fontSize: 22,
151 | color: TOMATOX_THEME.THEME_COLOR,
152 | marginBottom: 5,
153 | },
154 | playerOptionTitle: {
155 | fontSize: 12,
156 | color: TOMATOX_THEME.FONT_COLOR,
157 | },
158 | playItemWrapper: {
159 | flexDirection: 'row',
160 | flexWrap: 'wrap',
161 | justifyContent: 'space-around',
162 | },
163 | playItem: {
164 | fontSize: 11,
165 | width: 75,
166 | height: 30,
167 | lineHeight: 30,
168 | textAlign: 'center',
169 | color: TOMATOX_THEME.FONT_COLOR,
170 | marginTop: 4,
171 | marginBottom: 4,
172 | marginLeft: 3,
173 | marginRight: 3,
174 | backgroundColor: TOMATOX_THEME.COMPONENT_LIGHT_BACKGROUND,
175 | borderRadius: 2,
176 | },
177 | nonePlayItem: {
178 | width: 75,
179 | height: 30,
180 | marginTop: 4,
181 | marginBottom: 4,
182 | marginLeft: 3,
183 | marginRight: 3,
184 | },
185 | activePlayItem: {
186 | backgroundColor: TOMATOX_THEME.THEME_COLOR,
187 | },
188 | });
189 |
--------------------------------------------------------------------------------
/src/components/tomatox-flat-list/tomatox-flat-list.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TomatoxCard from '../tomatox-card/tomatox-card';
3 | import {FlatList, StyleSheet, Text} from 'react-native';
4 | import {TOMATOX_THEME} from "../../utils/theme";
5 |
6 | const style = StyleSheet.create({
7 | contentList: {
8 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
9 | flex: 1,
10 | padding: 7,
11 | },
12 | contentFooter: {
13 | textAlign: 'center',
14 | color: TOMATOX_THEME.FONT_COLOR,
15 | height: 50,
16 | lineHeight: 40,
17 | },
18 | });
19 |
20 | export default function tomatoxFlatList(props: {loadMore: any, data: any, haveMoreData: boolean}) {
21 | return }
29 | ListFooterComponent={(
30 | {props.haveMoreData ? '正在加载数据...' : '到底啦~'}
31 | )} />;
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/tomatox-header/tomatox-header.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
3 | import {TOMATOX_THEME} from '../../utils/theme';
4 | import Icon from 'react-native-vector-icons/Feather';
5 |
6 | export default function TomatoxHeader(props: {
7 | title: string,
8 | leftBtn?: {
9 | name: string,
10 | onPress: () => any
11 | },
12 | rightBtn?: {
13 | name: string,
14 | onPress: () => any
15 | }
16 | }) {
17 | return (
18 |
19 | {
20 | props.leftBtn &&
21 |
22 |
23 |
24 | }
25 | {props.title}
26 | {
27 | props.rightBtn &&
28 |
29 |
30 |
31 | }
32 |
33 | );
34 | }
35 |
36 | const style = StyleSheet.create({
37 | header: {
38 | height: 50,
39 | justifyContent: 'center',
40 | alignItems: 'center',
41 | borderBottomWidth: 1,
42 | borderColor: TOMATOX_THEME.SPLIT_LINE_COLOR,
43 | },
44 | headerText: {
45 | color: TOMATOX_THEME.FONT_COLOR,
46 | fontSize: 16,
47 | fontWeight: 'bold',
48 | },
49 | leftIcon: {
50 | position: 'absolute',
51 | left: 15,
52 | top: 13,
53 | },
54 | rightIcon: {
55 | position: 'absolute',
56 | right: 15,
57 | top: 13,
58 | },
59 | });
60 |
--------------------------------------------------------------------------------
/src/components/tomatox-video/tomatox-video.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Video, {OnLoadData} from 'react-native-video-new';
3 | import Orientation, {OrientationType} from 'react-native-orientation-locker';
4 | import {Animated, BackHandler, GestureResponderEvent, StatusBar, StyleSheet, Text, View} from 'react-native';
5 | import constants from '../../utils/constants';
6 | import {convertSecondToTime} from '../../utils/time-converter';
7 | import SystemSetting from 'react-native-system-setting';
8 | import {TOMATOX_THEME} from '../../utils/theme';
9 | import LinearGradient from 'react-native-linear-gradient';
10 | import {TouchableOpacity} from 'react-native-gesture-handler';
11 | import Icon from 'react-native-vector-icons/Feather';
12 | import Slider from '@react-native-community/slider';
13 | import { Platform } from 'react-native';
14 |
15 | let screenBrightness = 1;
16 |
17 | export default class TomatoxVideo extends React.Component<{
18 | src: string,
19 | paused?: boolean,
20 | lastSeek?: number,
21 | playNext: (cb: () => void) => void,
22 | onBack?: (playPosition: number) => any,
23 | navigation: any
24 | }, any> {
25 | private videoInstance: Video|undefined
26 | private seeking = false
27 | private curTimeCache = 0
28 | private defaultVideoHeight = constants.WINDOW_WIDTH / 16 * 9
29 | private fullScreenVideoHeight = constants.WINDOW_WIDTH as number
30 | private touchStartTime = 0
31 | private videoControlHideTaskId: any
32 | private touchScreenTaskId: any
33 | private longPressTaskId: any
34 | private initPosX: any
35 | private initPosY: any
36 | private posX: any
37 | private posY: any
38 | private touchType = -1
39 | private curShowVideoControl = false
40 | private selfIsAlive = true
41 | private locationInfoAnimatedLeft = new Animated.Value(-200)
42 |
43 | constructor(props: any) {
44 | super(props);
45 | this.state = {
46 | playing: true,
47 | playPosition: 0,
48 | videoFullTime: 0,
49 | playRate: 1,
50 | volume: 1,
51 | isFullScreen: false,
52 | showVideoControl: false,
53 | noticeInfo: '',
54 | videoHeight: this.defaultVideoHeight,
55 | bufferingInfo: '',
56 | locationInfo: '',
57 | };
58 | }
59 |
60 | private setLifecycleTimeout = (callBack: Function, delay: number) => {
61 | return setTimeout(() => {
62 | if (this.selfIsAlive) {
63 | callBack();
64 | }
65 | }, delay);
66 | }
67 |
68 | private handlePlayEnd = () => {
69 | this.setState({
70 | playing: false,
71 | palyPosition: 0,
72 | });
73 | this.videoInstance?.seek(0);
74 | }
75 |
76 | private switchControl = () => {
77 | if (this.state.showVideoControl) {
78 | this.hideControlImmediate()
79 | } else {
80 | this.showControlImmediate()
81 | }
82 | }
83 |
84 | private hideControlImmediate() {
85 | this.setState({showVideoControl: false})
86 | this.videoControlHideTaskId && clearTimeout(this.videoControlHideTaskId);
87 | this.videoControlHideTaskId = undefined
88 | }
89 |
90 | private showControlImmediate = () => {
91 | this.setState({showVideoControl: true})
92 | this.videoControlHideTaskId && clearTimeout(this.videoControlHideTaskId);
93 | this.videoControlHideTaskId = this.setLifecycleTimeout(() => {
94 | this.hideControlImmediate()
95 | }, 5000);
96 | }
97 |
98 | private switchScreenState = () => {
99 | if (this.state.isFullScreen) {
100 | StatusBar.setHidden(false);
101 | Orientation.lockToPortrait();
102 | } else {
103 | StatusBar.setHidden(true);
104 | Orientation.lockToLandscape();
105 | }
106 | this.setState({
107 | videoHeight: this.state.isFullScreen ? this.defaultVideoHeight : this.fullScreenVideoHeight,
108 | isFullScreen: !this.state.isFullScreen,
109 | });
110 | }
111 |
112 | private processGoBack = () => {
113 | if (this.state.isFullScreen) {
114 | // when swipe gesture to back, control view's touch end event will not be called
115 | this.touchHandler.onTouchEnd()
116 | this.switchScreenState();
117 | } else {
118 | this.props.navigation.goBack();
119 | }
120 | return true;
121 | }
122 |
123 | private touchHandler = {
124 | onTouchMove: (event: GestureResponderEvent) => {
125 | if (event.nativeEvent.touches.length > 1) {return;}
126 | const {pageX, pageY} = event.nativeEvent;
127 | const xOffset = pageX - this.posX
128 | const yOffset = pageY - this.posY
129 | if (this.touchType === -1) {
130 | // 判定操作类型
131 | const xOffsetAbs = Math.abs(pageX - this.initPosX)
132 | const yOffsetAbs = Math.abs(pageY - this.initPosY)
133 | if (xOffsetAbs > 5 || yOffsetAbs > 5) {
134 | clearTimeout(this.longPressTaskId)
135 | if (xOffsetAbs * 2 > yOffsetAbs) {
136 | // 横向,播放进度
137 | this.touchType = 1;
138 | } else {
139 | const screenWidth = this.state.isFullScreen ? constants.WINDOW_HEIGHT : constants.WINDOW_WIDTH;
140 | // 纵向,控制音量和亮度
141 | if (pageX < screenWidth / 2) {
142 | this.touchType = 2; // 亮度
143 | } else {
144 | this.touchType = 3; // 音量
145 | }
146 | }
147 | this.posX = pageX;
148 | this.posY = pageY;
149 | }
150 | return
151 | } else {
152 | // 响应
153 | switch (this.touchType) {
154 | case 1:
155 | this.showControlImmediate();
156 | this.seeking = true;
157 | const playPos = xOffset > 0 ? Math.min(this.state.videoFullTime, this.state.playPosition + xOffset) :
158 | Math.max(0, this.state.playPosition + xOffset);
159 | this.setState({
160 | playPosition: playPos,
161 | noticeInfo: `${convertSecondToTime(playPos, this.state.videoFullTime)} / ${convertSecondToTime(this.state.videoFullTime, this.state.videoFullTime)}`,
162 | });
163 | break;
164 | case 2:
165 | this.showControlImmediate();
166 | if (yOffset > 0) {
167 | screenBrightness = Math.max(0, screenBrightness - yOffset * 0.1);
168 | } else {
169 | screenBrightness = Math.min(10, screenBrightness - yOffset * 0.1);
170 | }
171 | this.setState({
172 | noticeInfo: `亮度:${Math.floor(screenBrightness * 10)}%`,
173 | });
174 | SystemSetting.setBrightnessForce(screenBrightness);
175 | break;
176 | case 3:
177 | this.showControlImmediate();
178 | if (yOffset > 0) {
179 | // 音量-
180 | this.setState({
181 | volume: Math.max(0, this.state.volume - yOffset * 0.008),
182 | noticeInfo: `音量:${Math.floor(this.state.volume * 100)}%`,
183 | });
184 | } else {
185 | // 音量+
186 | this.setState({
187 | volume: Math.min(1, this.state.volume - yOffset * 0.008),
188 | noticeInfo: `音量:${Math.floor(this.state.volume * 100)}%`,
189 | });
190 | }
191 | break;
192 | case 4:
193 | break;
194 | default:
195 | break;
196 | }
197 | }
198 | this.posX = pageX;
199 | this.posY = pageY;
200 | },
201 | onTouchStart: (event: GestureResponderEvent) => {
202 | if (event.nativeEvent.touches.length > 1) {return;}
203 | this.curShowVideoControl = this.state.showVideoControl;
204 | const {locationX, locationY} = event.nativeEvent;
205 | this.posX = this.initPosX = locationX;
206 | // control组件下偏移量45
207 | const offset = this.state.isFullScreen ? 65 : 45;
208 | this.posY = this.initPosY = locationY + offset;
209 | this.touchStartTime = Date.now();
210 | this.longPressTaskId = this.setLifecycleTimeout(() => {
211 | if (this.touchType === -1) {
212 | this.touchType = 4
213 | this.setState({ noticeInfo: '倍速播放中', playRate: 3 })
214 | this.hideControlImmediate()
215 | this.longPressTaskId = undefined
216 | }
217 | }, 1000)
218 | },
219 | onTouchEnd: (event?: GestureResponderEvent) => {
220 | if (event && event.nativeEvent.touches.length > 1) {return;}
221 | this.posX = this.initPosX = this.posY = this.initPosY = undefined;
222 | this.setState({noticeInfo: ''});
223 | this.longPressTaskId && clearTimeout(this.longPressTaskId)
224 | this.longPressTaskId = undefined
225 | switch (this.touchType) {
226 | case 1:
227 | this.videoInstance?.seek(this.state.playPosition);
228 | this.setLifecycleTimeout(() => this.seeking = false, 1000);
229 | break;
230 | case 2:
231 | break;
232 | case 3:
233 | break;
234 | case 4:
235 | //长按
236 | this.setState({ playRate: 1 })
237 | break;
238 | default:
239 | // 点击
240 | this.showControlImmediate();
241 | if (this.touchScreenTaskId) {
242 | // 双击 播放/暂停
243 | this.setState({
244 | playing: !this.state.playing,
245 | });
246 | clearTimeout(this.touchScreenTaskId);
247 | this.touchScreenTaskId = undefined;
248 | } else {
249 | // 单击,切换控制层状态
250 | this.touchScreenTaskId = this.setLifecycleTimeout(() => {
251 | this.curShowVideoControl === this.state.showVideoControl && this.switchControl();
252 | this.touchScreenTaskId = undefined;
253 | },300);
254 | }
255 | break;
256 | }
257 |
258 | this.touchType = -1;
259 | },
260 | }
261 |
262 | private orientationListener = (type: OrientationType) => {
263 | if (type === 'PORTRAIT') {
264 | this.setState({
265 | isFullScreen: false,
266 | videoHeight: this.defaultVideoHeight,
267 | });
268 | StatusBar.setHidden(false);
269 | }
270 | }
271 |
272 | private onVideoLoad = (data: OnLoadData) => {
273 | this.setState({videoFullTime: data.duration}, () => {
274 | if (this.props.lastSeek) {
275 | this.videoInstance?.seek(this.props.lastSeek)
276 | this.setState({locationInfo: `已为您定位至${convertSecondToTime(this.props.lastSeek, this.props.lastSeek)}`})
277 | Animated.timing(this.locationInfoAnimatedLeft, {
278 | toValue: 0,
279 | duration: 500,
280 | useNativeDriver: false
281 | }).start()
282 | this.setLifecycleTimeout(() => Animated.timing(this.locationInfoAnimatedLeft, {
283 | toValue: -200,
284 | duration: 500,
285 | useNativeDriver: false
286 | }).start(), 2500)
287 | }
288 | });
289 | }
290 |
291 | componentDidMount(): void {
292 | BackHandler.addEventListener('hardwareBackPress', this.processGoBack);
293 | Orientation.addLockListener(this.orientationListener);
294 | }
295 | componentWillUnmount(): void {
296 | this.selfIsAlive = false;
297 | BackHandler.removeEventListener('hardwareBackPress', this.processGoBack);
298 | Orientation.removeLockListener(this.orientationListener);
299 | this.props.onBack && this.props.onBack(this.state.playPosition);
300 | }
301 |
302 |
303 | render(): React.ReactNode {
304 | const style = StyleSheet.create({
305 | videoWrapper: {
306 | width: '100%',
307 | height: this.state.videoHeight,
308 | backgroundColor: '#000',
309 | marginTop: constants.IS_IOS && !this.state.isFullScreen ? 44 : 0
310 | },
311 | video: {
312 | width: '100%',
313 | height: '100%',
314 | },
315 | videoControl: {
316 | position: 'absolute',
317 | width: '100%',
318 | height: this.state.videoHeight,
319 | zIndex: 1,
320 | },
321 | videoControlTop: {
322 | paddingLeft: this.state.isFullScreen ? (constants.IS_IOS ? 40 : 15) : 5,
323 | paddingRight: this.state.isFullScreen ? (constants.IS_IOS ? 50 : 25) : 15,
324 | paddingTop: this.state.isFullScreen ? 5 : 0,
325 | height: this.state.isFullScreen ? 65 : 45,
326 | justifyContent: 'space-between',
327 | alignItems: 'center',
328 | flexDirection: 'row',
329 | },
330 | topBtn: {
331 | color: TOMATOX_THEME.FONT_COLOR,
332 | fontSize: this.state.isFullScreen ? 30 : 27,
333 | },
334 | topBtnRight: {
335 | color: TOMATOX_THEME.FONT_COLOR,
336 | fontSize: this.state.isFullScreen ? 23 : 20,
337 | },
338 | videoControlCenter: {
339 | width: '100%',
340 | height: this.state.videoHeight - (this.state.isFullScreen ? 130 : 90),
341 | zIndex: 10,
342 | top: this.state.isFullScreen ? 65 : 45,
343 | position: 'absolute',
344 | justifyContent: 'center',
345 | alignItems: 'center',
346 | },
347 | videoControlCenterContent: {
348 | fontSize: 13,
349 | color: TOMATOX_THEME.FONT_COLOR,
350 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
351 | paddingTop: 7,
352 | paddingBottom: 7,
353 | paddingLeft: 15,
354 | paddingRight: 15,
355 | borderRadius: 5,
356 | },
357 | locationInfoContent: {
358 | fontSize: 13,
359 | color: TOMATOX_THEME.FONT_COLOR,
360 | position: 'absolute',
361 | top: this.state.videoHeight - 80,
362 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
363 | paddingTop: 7,
364 | paddingBottom: 7,
365 | paddingLeft: 15,
366 | paddingRight: 15,
367 | borderRadius: 4,
368 | left: 15,
369 | zIndex: 10,
370 | },
371 | videoControlBottom: {
372 | top: this.state.videoHeight - (this.state.isFullScreen ? 130 : 90),
373 | height: this.state.isFullScreen ? 65 : 45,
374 | width: '100%',
375 | flexDirection: 'row',
376 | flexWrap: 'nowrap',
377 | alignItems: 'center',
378 | paddingLeft: this.state.isFullScreen ? (constants.IS_IOS ? 45 : 20) : 10,
379 | paddingRight: this.state.isFullScreen ? (constants.IS_IOS ? 50 : 25) : 15,
380 | },
381 | videoPlayPause: {
382 | color: TOMATOX_THEME.FONT_COLOR,
383 | fontSize: this.state.isFullScreen ? 23 : 20,
384 | },
385 | videoSlider: {
386 | flex: 1,
387 | height: 30,
388 | },
389 | videoProcess: {
390 | color: TOMATOX_THEME.FONT_COLOR,
391 | fontSize: 10,
392 | fontWeight: 'bold',
393 | },
394 | videoFullScreen: {
395 | color: TOMATOX_THEME.FONT_COLOR,
396 | fontSize: this.state.isFullScreen ? 21 : 18,
397 | marginLeft: 10,
398 | },
399 | });
400 |
401 | if (!this.props.src) {
402 | return
403 | }
404 | return (
405 |
406 | {
407 | this.state.showVideoControl &&
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
419 | {this.showControlImmediate(); this.setState({ playing: !this.state.playing });}}>
420 |
421 |
422 | this.seeking = true}
431 | onSlidingComplete={() => {this.videoInstance?.seek(this.curTimeCache); this.setLifecycleTimeout(() => this.seeking = false, 1000);}}
432 | onValueChange={value => {this.curTimeCache = value; this.setState({playPosition: value}); this.showControlImmediate();}}
433 | />
434 |
435 | {`${convertSecondToTime(this.state.playPosition, this.state.videoFullTime)}/${convertSecondToTime(this.state.videoFullTime, this.state.videoFullTime)}`}
436 |
437 |
438 |
439 |
440 |
441 |
442 | }
443 |
447 | {
448 | Boolean(this.state.noticeInfo || this.state.bufferingInfo) &&
449 | {this.state.noticeInfo || this.state.bufferingInfo}
450 | }
451 |
452 |
453 | {this.state.locationInfo}
454 |
455 |
474 | );
475 | }
476 | }
477 |
--------------------------------------------------------------------------------
/src/components/tomatox-waterfall/tomatox-waterfall.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useRef, useState} from 'react';
2 | import TomatoxFlatList from '../../components/tomatox-flat-list/tomatox-flat-list';
3 | import {queryResources, querySearchRes} from '../../utils/request';
4 |
5 | export default function tomatoxWaterfall(props: {type?: number, keyword?: string}) {
6 | const [resourceList, setResourceList] = useState([]);
7 | const [haveMoreData, setHaveMoreData] = useState(true);
8 | const curPageRef = useRef(0)
9 | const pageCountRef = useRef(10)
10 | const curKeywordRef = useRef(props.keyword)
11 |
12 | /**
13 | * @param init
14 | * record a problem about useState here
15 | * I try to use state hook create curPage,pageCount in previous version
16 | * when father component change keyword, this component will rerender
17 | * and I use curKeywordRef to judge whether keyword is changed and reset this component's state then invoke getMoreData()
18 | * but when I setState and sync invoke getMoreDate(), I find setState not success when i judge in getMoreData
19 | * that means setState is an async function and it no callback or promise, what the hell!
20 | * So I use refHook instead stateHook to make update sync.
21 | * You can also use effectHook just like vue watch param to watch state change,
22 | * but it's not a good idea in this scene, because this component's state may be updated by more than one function,
23 | * that means very easy to make this component infinite rerender.
24 | * So, if a param will not used to update view, you shouldn't define it by stateHook
25 | * if you need param cross component, use refHook define it, otherwise, just define a normal parameter
26 | */
27 | const getMoreData = (init: boolean) => {
28 | if (init) {
29 | setHaveMoreData(true)
30 | curPageRef.current = 0
31 | pageCountRef.current = 10
32 | setResourceList([])
33 | }
34 | let prom;
35 | curPageRef.current = curPageRef.current + 1
36 | if (curPageRef.current >= pageCountRef.current) {
37 | setHaveMoreData(false);
38 | return;
39 | }
40 | if (props.type != null) {
41 | if (props.type === -1) {
42 | prom = queryResources(curPageRef.current, undefined, undefined, 24);
43 | } else {
44 | prom = queryResources(curPageRef.current, props.type);
45 | }
46 | } else if (curKeywordRef.current) {
47 | prom = querySearchRes(curPageRef.current, curKeywordRef.current as unknown as string);
48 | } else {
49 | setHaveMoreData(false)
50 | setResourceList([])
51 | return;
52 | }
53 |
54 | prom.then((res: any) => {
55 | const {pagecount, list} = res;
56 | if (curPageRef.current >= pagecount) {
57 | setHaveMoreData(false);
58 | }
59 | pageCountRef.current = pagecount
60 | setResourceList(init ?
61 | [...list] :
62 | [...resourceList, ...list]
63 | );
64 | });
65 | };
66 |
67 | useEffect(() => {
68 | getMoreData(true)
69 | }, []);
70 |
71 | if (curKeywordRef.current !== props.keyword) {
72 | curKeywordRef.current = props.keyword
73 | getMoreData(true)
74 | }
75 |
76 | return (
77 | getMoreData(false)}
79 | data={resourceList}
80 | haveMoreData={haveMoreData}
81 | />
82 | );
83 | }
84 |
--------------------------------------------------------------------------------
/src/images/png/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/src/images/png/loading.png
--------------------------------------------------------------------------------
/src/images/png/tomatox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeIess/TOMATOX_MOBILE/6fe1dca229c2cc9070670fab676b517946eb4178/src/images/png/tomatox.png
--------------------------------------------------------------------------------
/src/types/types.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png'
2 | declare module '*.json'
3 |
4 | declare interface IPlayResource {
5 | id: number
6 | type: string
7 | picture: string
8 | lang: string
9 | name: string
10 | director: string
11 | describe: string
12 | area: string
13 | actor: string
14 | class: string
15 | doubanId: number
16 | doubanScore: string
17 | origin: string
18 | remark: string
19 | tag: string
20 | year: string
21 | updateTime: string
22 | playList: { index: string[], mapper: Record }
23 | }
24 |
25 | declare interface IPlayHistoryResource extends IPlayResource{
26 | historyPlayKey: string
27 | historyPlayTime: number
28 | historyPlayDate: number
29 | historyPlayDesc: string
30 | }
31 |
32 | declare interface IPlayCollectResource extends IPlayResource {
33 | collectDate: number
34 | }
35 |
36 | declare interface ILiveResource {
37 | sourceName: string
38 | src: string
39 | }
40 |
41 | declare interface IOrigin {
42 | id: string,
43 | url: string,
44 | timestamp: number,
45 | active: boolean
46 | }
47 |
--------------------------------------------------------------------------------
/src/utils/constants.ts:
--------------------------------------------------------------------------------
1 | import {Dimensions, Platform} from 'react-native';
2 |
3 | const constants = {
4 | DEFAULT_ORIGIN: 'https://www.kuaibozy.com/api.php/provide/vod/from/kbm3u8/at/xml',
5 | DEFAULT_SEARCH_INDEX: 'https://gitee.com/yanjiaxuan/TOMATOX_RES/raw/main/result.json',
6 | IPTV_ORIGIN: 'https://gitee.com/yanjiaxuan/TOMATOX_RES/raw/main/zhibo.json',
7 | WINDOW_WIDTH: Dimensions.get('window').width,
8 | WINDOW_HEIGHT: Dimensions.get('window').height,
9 | IS_IOS: Platform.OS === 'ios'
10 | };
11 |
12 | export default constants
13 |
--------------------------------------------------------------------------------
/src/utils/filterResources.ts:
--------------------------------------------------------------------------------
1 | export function filterResources(resources: any[]) {
2 | return resources.map(res => filterResource(res));
3 | }
4 |
5 | export function filterResource(resource: any): IPlayResource {
6 | let listStr = ''
7 | if (resource.dl && resource.dl[0] && resource.dl[0].dd && resource.dl[0].dd[0]) {
8 | const dd = resource.dl[0].dd[0]
9 | if (dd instanceof Array) {
10 | const videoList = dd.filter(item => item.$.flag && (item.$.flag.includes('m3u8') || item.$.flag.includes('mp4')))
11 | videoList.length && (listStr = videoList[0]._)
12 | } else {
13 | listStr = dd._
14 | }
15 | }
16 | return {
17 | id: +resource.id[0],
18 | type: resource.type[0],
19 | picture: resource.pic[0],
20 | lang: resource.lang[0],
21 | name: resource.name[0],
22 | director: resource.director[0],
23 | describe: resource.des[0],
24 | area: resource.area[0],
25 | actor: resource.actor[0],
26 | class: '',
27 | doubanId: 0,
28 | doubanScore: '0.0',
29 | origin: '',
30 | remark: resource.note[0],
31 | tag: '',
32 | year: resource.year[0],
33 | updateTime: resource.last[0],
34 | playList: filterPlayList(listStr),
35 | };
36 | }
37 |
38 | function filterPlayList(listStr: string) {
39 | const res: { index: string[], mapper: Record } = {
40 | index: [],
41 | mapper: {},
42 | };
43 | const splitLists = listStr.split('$$$').filter(val => val.includes('.m3u') || val.includes('.mp4'));
44 | if (splitLists.length) {
45 | splitLists[0].split('#').forEach(item => {
46 | const [key, val] = item.split('$');
47 | if (key && val) {
48 | res.index.push(key);
49 | res.mapper[key] = val;
50 | }
51 | });
52 | }
53 | return res;
54 | }
55 |
56 | // export function cleanResourceData(dataType: string, data: IplayResource): IplayResource {
57 | // const optData: IplayResource = {
58 | // id: data.id,
59 | // type: data.type,
60 | // picture: data.picture,
61 | // lang: data.lang,
62 | // name: data.name,
63 | // director: data.director,
64 | // describe: data.describe,
65 | // area: data.area,
66 | // actor: data.actor,
67 | // class: data.class,
68 | // doubanId: data.doubanId,
69 | // doubanScore: data.doubanScore,
70 | // origin: data.origin,
71 | // remark: data.remark,
72 | // tag: data.tag,
73 | // year: data.year,
74 | // updateTime: data.updateTime,
75 | // playList: data.playList
76 | // };
77 | // if (dataType === TABLES.TABLE_HISTORY) {
78 | // optData.historyOption = data.historyOption;
79 | // } else if (dataType === TABLES.TABLE_COLLECT) {
80 | // optData.collectOption = data.collectOption;
81 | // }
82 | // return optData;
83 | // }
84 |
--------------------------------------------------------------------------------
/src/utils/request.ts:
--------------------------------------------------------------------------------
1 | // ac:模式(videolist或detail详细模式),为空=列表标准模式
2 | // ids: 影片id,多个使用,隔开
3 | // t: 类型
4 | // h:最近多少小时内
5 | // pg: 页数
6 | // wd:搜索like
7 | // at:输出格式,可选xml
8 |
9 | import constants from './constants';
10 | import {filterResources} from './filterResources';
11 | const parseXML = require('react-native-xml2js').parseString;
12 | let SEARCH_INDEX: Record = {};
13 | const ua = {
14 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66'
15 | }
16 | const customFetch = function(input: RequestInfo, init?: RequestInit): Promise {
17 | if (typeof input === 'string') {
18 | if (init) {
19 | init.headers = ua
20 | return fetch(input, init)
21 | } else {
22 | return fetch(input, { headers: ua })
23 | }
24 | } else {
25 | return fetch(input, { headers: ua })
26 | }
27 | }
28 |
29 | export function querySearchIndex() {
30 | customFetch(constants.DEFAULT_SEARCH_INDEX).then(res => {
31 | return res.json()
32 | }).then(res => {
33 | SEARCH_INDEX = res as any;
34 | });
35 | }
36 |
37 | export function querySearchRes(curPage: number, keyword: string) {
38 | return new Promise((resolve) => {
39 | const result: {pagecount: number, list: IPlayResource[]} = { pagecount: 1, list: [] };
40 | const targetIds: number[] = [];
41 | for (let key in SEARCH_INDEX) {
42 | if (key.indexOf(keyword) >= 0) {
43 | targetIds.push(SEARCH_INDEX[key]);
44 | }
45 | }
46 | if (targetIds.length === 0) {
47 | resolve(result);
48 | }
49 | customFetch(`${constants.DEFAULT_ORIGIN}?ac=videolist&pg=${curPage}&ids=${targetIds.join(',')}`).then(res => res.text()).then(res => {
50 | parseXML(res, (err: Error, data:any) => {
51 | const jsonData = data.rss || data;
52 | if (jsonData.list && jsonData.list[0] && jsonData.list[0].video) {
53 | const { pagecount } = jsonData.list[0].$;
54 | result.pagecount = pagecount;
55 | const videoList =
56 | jsonData.list[0].video instanceof Array
57 | ? jsonData.list[0].video
58 | : [jsonData.list[0].video];
59 | result.list.push(...filterResources(videoList));
60 | }
61 | resolve(result);
62 | });
63 | });
64 | });
65 | }
66 |
67 | export function queryResources(
68 | curPage: number,
69 | type?: number,
70 | keyWord?: string,
71 | lastUpdate?: number
72 | ): any {
73 | return new Promise(resolve => {
74 | try {
75 | customFetch(`${constants.DEFAULT_ORIGIN}?ac=videolist${curPage ? '&pg=' + curPage : ''}${type ? '&t=' + type : ''}${keyWord ? '&wd=' + keyWord : ''}${lastUpdate ? '&h=' + lastUpdate : ''}`)
76 | .then(res => res.text())
77 | .then(res => {
78 | parseXML(res, (err: Error, data:any) => {
79 | const jsonData = data.rss || data;
80 | if (jsonData.list && jsonData.list[0] && jsonData.list[0].video) {
81 | const { pagecount } = jsonData.list[0].$;
82 | const videoList =
83 | jsonData.list[0].video instanceof Array
84 | ? jsonData.list[0].video
85 | : [jsonData.list[0].video];
86 | resolve({ pagecount, list: filterResources(videoList) });
87 | }
88 | resolve({pagecount: 0, list: []});
89 | });
90 | resolve({pagecount: 0, list: []});
91 | }, () => {resolve({pagecount: 0, list: []});})
92 | .catch(() => resolve({pagecount: 0, list: []}));
93 | } catch (e) {
94 | resolve({pagecount: 0, list: []});
95 | }
96 | });
97 |
98 | }
99 |
100 | export function queryTypes() {
101 | return new Promise<{id: number, name: string}[]>(resolve => {
102 | try {
103 | customFetch(constants.DEFAULT_ORIGIN)
104 | .then(res => res.text())
105 | .then(res => {
106 | parseXML(res, (err: Error, data: any) => {
107 | const jsonData = data.rss || data;
108 | const result: any = [];
109 | jsonData.class[0].ty.forEach((item: any) => {
110 | result.push({id: item.$.id, name: item._});
111 | });
112 | resolve(result);
113 | });
114 | }, () => {resolve([]);})
115 | .catch(() => resolve([]));
116 | } catch (e) {
117 | resolve([]);
118 | }
119 | });
120 | }
121 |
122 | export function queryLive() {
123 | return new Promise(resolve => {
124 | try {
125 | customFetch(constants.IPTV_ORIGIN, )
126 | .then(res => res.json())
127 | .then(res => {
128 | const keys = new Set();
129 | const result: ILiveResource[] = [];
130 | (res as ILiveResource[]).forEach(item =>{
131 | if (!keys.has(item.sourceName)) {
132 | result.push(item);
133 | keys.add(item.sourceName);
134 | }
135 | });
136 | resolve(result);
137 | }, () => resolve([]))
138 | .catch(() => resolve([]));
139 | } catch (e) {
140 | resolve([]);
141 | }
142 | });
143 | }
144 |
--------------------------------------------------------------------------------
/src/utils/storage/data-converter.ts:
--------------------------------------------------------------------------------
1 | export function convertDataFromDB(realmObj: Realm.Object|undefined): IPlayCollectResource|IPlayHistoryResource|undefined {
2 | if (!realmObj) return
3 | const data = {};
4 | realmObj.keys().forEach(key => {
5 | if (key === 'playList') {
6 | // @ts-ignore
7 | data[key] = JSON.parse(realmObj[key]);
8 | } else {
9 | // @ts-ignore
10 | data[key] = realmObj[key];
11 | }
12 | });
13 | return data as any;
14 | }
15 |
16 | export function convertDataToDB(data: IPlayCollectResource|IPlayHistoryResource) {
17 | return {
18 | ...data,
19 | playList: JSON.stringify(data.playList),
20 | };
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/utils/storage/origins-storage.ts:
--------------------------------------------------------------------------------
1 | import {realm} from './storage';
2 | import {TABLE_NAME} from './table-define';
3 |
4 | export function addOrigin(origin: IOrigin) {
5 | realm?.write(() => {
6 | realm?.create(TABLE_NAME.TOMATOX_ORIGINS, origin);
7 | });
8 | }
9 |
10 | export function deleteOrigin(id: string) {
11 | realm?.delete(realm?.objectForPrimaryKey(TABLE_NAME.TOMATOX_ORIGINS, id));
12 | }
13 |
14 | export function changeActiveOrigin(id: string) {
15 | realm?.write(() => {
16 | realm?.objects(TABLE_NAME.TOMATOX_ORIGINS).forEach(i => {
17 | const item = i as unknown as IOrigin;
18 | item.active = item.id === id
19 | })
20 | })
21 | }
22 |
23 | export function queryAllOrigins(): IOrigin[] {
24 | const res = realm?.objects(TABLE_NAME.TOMATOX_ORIGINS).map(i => {
25 | const item = i as unknown as IOrigin;
26 | return {
27 | id: item.id,
28 | url: item.url,
29 | active: item.active,
30 | timestamp: item.timestamp
31 | };
32 | }) as IOrigin[];
33 | return res || []
34 | }
35 |
--------------------------------------------------------------------------------
/src/utils/storage/storage.ts:
--------------------------------------------------------------------------------
1 | import Realm from 'realm';
2 | import {TABLE_DEFINE, TABLE_NAME} from './table-define';
3 | import {convertDataFromDB, convertDataToDB} from "./data-converter";
4 |
5 | const ONE_WEEK = 7 * 24 * 3600 * 1000
6 | export let realm: Realm | undefined;
7 |
8 | export default async function initStorage() {
9 | realm = await Realm.open({
10 | path: 'tomatox',
11 | schemaVersion: 1,
12 | schema: [TABLE_DEFINE.TOMATOX_COLLECT, TABLE_DEFINE.TOMATOX_HISTORY, TABLE_DEFINE.TOMATOX_ORIGINS],
13 | });
14 | cleanOutdateData()
15 | }
16 |
17 | export function cleanOutdateData() {
18 | const now = Date.now()
19 | realm?.write(() => {
20 | // @ts-ignore
21 | const needDeleted = realm?.objects(TABLE_NAME.TOMATOX_HISTORY).filter(item => now - item.historyPlayDate > ONE_WEEK)
22 | realm?.delete(needDeleted)
23 | })
24 | }
25 |
26 | export function insertOrUpdateData(tableName: string, data: IPlayHistoryResource|IPlayCollectResource) {
27 | const storeConvertData = convertDataToDB(data)
28 | realm?.write(() => {
29 | const object = realm?.objectForPrimaryKey(tableName, storeConvertData.id);
30 | if (!object) {
31 | realm?.create(tableName, storeConvertData);
32 | } else {
33 | Object.keys(storeConvertData).forEach(key => {
34 | // @ts-ignore
35 | key !== 'id' && (object[key] = storeConvertData[key]);
36 | });
37 | }
38 | });
39 | }
40 |
41 | export function queryData(tableName: string, id: number): IPlayHistoryResource|IPlayCollectResource|undefined {
42 | const res = realm?.objectForPrimaryKey(tableName, id);
43 | return convertDataFromDB(res);
44 | }
45 |
46 | export function queryAll(tableName:string): (IPlayHistoryResource | IPlayCollectResource | undefined)[] | undefined {
47 | return realm?.objects(tableName).map(item => convertDataFromDB(item));
48 | }
49 |
50 | export function deleteData(tableName: string, id: number) {
51 | realm?.write(() => {
52 | realm?.delete(realm?.objectForPrimaryKey(tableName, id));
53 | });
54 | }
55 |
--------------------------------------------------------------------------------
/src/utils/storage/table-define.ts:
--------------------------------------------------------------------------------
1 | const abstractTableDefine = {
2 | id: 'int',
3 | type: 'string',
4 | picture: 'string',
5 | lang: 'string',
6 | name: 'string',
7 | director: 'string',
8 | describe: 'string',
9 | area: 'string',
10 | actor: 'string',
11 | class: 'string',
12 | doubanId: 'int',
13 | doubanScore: 'string',
14 | origin: 'string',
15 | remark: 'string',
16 | tag: 'string',
17 | year: 'string',
18 | updateTime: 'string',
19 | playList: 'string'
20 | }
21 |
22 | export const TABLE_NAME = {
23 | TOMATOX_HISTORY: 'TOMATOX_HISTORY',
24 | TOMATOX_COLLECT: 'TOMATOX_COLLECT',
25 | TOMATOX_ORIGINS: 'TOMATOX_ORIGINS'
26 | }
27 |
28 | export const TABLE_DEFINE = {
29 | TOMATOX_HISTORY: {
30 | name: TABLE_NAME.TOMATOX_HISTORY,
31 | primaryKey: 'id',
32 | properties: {
33 | ...abstractTableDefine,
34 | historyPlayKey: 'string',
35 | historyPlayTime: 'int',
36 | historyPlayDate: {type: 'int', indexed: true},
37 | historyPlayDesc: 'string'
38 | }
39 | },
40 | TOMATOX_COLLECT: {
41 | name: TABLE_NAME.TOMATOX_COLLECT,
42 | primaryKey: 'id',
43 | properties: {
44 | ...abstractTableDefine,
45 | collectDate: 'int'
46 | }
47 | },
48 | TOMATOX_ORIGINS: {
49 | name: TABLE_NAME.TOMATOX_ORIGINS,
50 | primaryKey: 'id',
51 | properties: {
52 | id: 'string',
53 | url: 'string',
54 | timestamp: 'int',
55 | active: 'bool'
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/utils/theme.ts:
--------------------------------------------------------------------------------
1 | export const TOMATOX_THEME = {
2 | THEME_COLOR: '#ff5c49',
3 | BACKGROUND_COLOR: '#2b2b2b',
4 | HIGHLIGTH_BACKGROUND_COLOR: '#323232',
5 | FONT_COLOR: '#f1f1f1',
6 | UNIMPORTANT_FONT_COLOR: '#bbbbbb',
7 | DISABLED_FONT_COLOR: '#a1a1a1',
8 | COMPONENT_DARK_BACKGROUND: 'rgba(0,0,0,0.2)',
9 | COMPONENT_LIGHT_BACKGROUND: 'rgba(111,111,111,0.1)',
10 | SPLIT_LINE_COLOR: '#343434'
11 | }
12 |
--------------------------------------------------------------------------------
/src/utils/time-converter.ts:
--------------------------------------------------------------------------------
1 | function fix2(num: number) {
2 | return (num < 10 ? '0' : '') + num
3 | }
4 |
5 | export function convertSecondToTime(date: number, full: number) {
6 | const useHours = full > 3600
7 | let handleTime = date;
8 | let target = '';
9 | if (useHours) {
10 | const hours = Math.floor(handleTime / 3600);
11 | target += hours < 10 ? `0${hours}:` : `${hours}:`;
12 | handleTime = handleTime % 3600;
13 | }
14 | const minutes = Math.floor(handleTime / 60);
15 | target += minutes < 10 ? `0${minutes}:` : `${minutes}:`;
16 | handleTime = Math.floor(handleTime % 60);
17 | target += handleTime < 10 ? `0${handleTime}` : `${handleTime}`;
18 |
19 | return target;
20 | }
21 |
22 | export function convertTimestampToDate(timestamp: number) {
23 | const date = new Date(timestamp)
24 |
25 | return `${date.getFullYear()}-${fix2(date.getMonth() + 1)}-${fix2(date.getDate())} ${fix2(date.getHours())}:${fix2(date.getMinutes())}`
26 | }
27 |
--------------------------------------------------------------------------------
/src/views/collect/collect.tsx:
--------------------------------------------------------------------------------
1 | import React, {useCallback, useState} from 'react';
2 | import {TABLE_NAME} from '../../utils/storage/table-define';
3 | import {queryAll} from '../../utils/storage/storage';
4 | import TomatoxFlatList from '../../components/tomatox-flat-list/tomatox-flat-list';
5 | import {StyleSheet, View, Text} from 'react-native';
6 | import {TOMATOX_THEME} from '../../utils/theme';
7 | import {useFocusEffect} from '@react-navigation/native';
8 | import TomatoxHeader from '../../components/tomatox-header/tomatox-header';
9 |
10 | export default function Collect() {
11 | const [collectRes, setCollectRes] = useState([]);
12 |
13 | const queryResource = useCallback(() => {
14 | setCollectRes((queryAll(TABLE_NAME.TOMATOX_COLLECT) as IPlayCollectResource[])
15 | .sort((a, b) => b.collectDate - a.collectDate));
16 | }, []);
17 | useFocusEffect(queryResource);
18 |
19 | return (
20 |
21 |
22 | {}} data={collectRes} haveMoreData={false} />
23 |
24 | );
25 | }
26 |
27 | const style = StyleSheet.create({
28 | fullWrapper: {
29 | flex: 1,
30 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
31 | },
32 | });
33 |
--------------------------------------------------------------------------------
/src/views/history/history.tsx:
--------------------------------------------------------------------------------
1 | import React, {useCallback, useState} from 'react';
2 | import {
3 | Image,
4 | SectionList,
5 | SectionListData,
6 | StyleSheet,
7 | Text,
8 | View,
9 | } from 'react-native';
10 | import {TOMATOX_THEME} from '../../utils/theme';
11 | import {useFocusEffect} from '@react-navigation/native';
12 | import {queryAll} from '../../utils/storage/storage';
13 | import {TABLE_NAME} from '../../utils/storage/table-define';
14 | import {TouchableOpacity} from 'react-native-gesture-handler';
15 | import {useNavigation} from '@react-navigation/native';
16 | import {convertTimestampToDate} from '../../utils/time-converter';
17 | import TomatoxHeader from '../../components/tomatox-header/tomatox-header';
18 |
19 | const ONE_DAY = 24 * 3600 * 1000;
20 | export default function History() {
21 | const [resourceSections, setResourceSections] = useState[]>([]);
22 | const {navigate} = useNavigation();
23 | const queryResource = useCallback(() => {
24 | const historyResources = queryAll(TABLE_NAME.TOMATOX_HISTORY) as IPlayHistoryResource[];
25 | historyResources.sort((a, b) => b.historyPlayDate - a.historyPlayDate);
26 | const now = Date.now();
27 | const today = now - now % ONE_DAY;
28 | const yesterday = today - ONE_DAY;
29 | setResourceSections([
30 | {title: '今天', data: historyResources.filter(item => item.historyPlayDate >= today)},
31 | {title: '昨天', data: historyResources.filter(item => item.historyPlayDate >= yesterday && item.historyPlayDate < today)},
32 | {title: '更早', data: historyResources.filter(item => item.historyPlayDate < yesterday)},
33 | ]);
34 | }, []);
35 | useFocusEffect(queryResource);
36 |
37 | return (
38 |
39 |
40 | (
47 |
48 |
49 | {title}
50 |
51 |
52 | )}
53 | renderItem={({item}) => (
54 | navigate('Player', item)}>
55 |
56 |
57 |
58 |
59 | {item.name}
60 |
61 |
62 | {convertTimestampToDate(item.historyPlayDate)}
63 |
64 |
65 | {item.historyPlayDesc}
66 |
67 |
68 |
69 |
70 | )}
71 | />
72 |
73 | );
74 | }
75 |
76 | const style = StyleSheet.create({
77 | fullWrapper: {
78 | flex: 1,
79 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
80 | },
81 | content: {
82 | flex: 1,
83 | paddingLeft: 10,
84 | paddingRight: 10,
85 | },
86 | contentTitleWrapper: {
87 | height: 30,
88 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
89 | },
90 | contentTitle: {
91 | lineHeight: 30,
92 | fontSize: 14,
93 | color: TOMATOX_THEME.FONT_COLOR,
94 | },
95 | historyItem: {
96 | height: 75,
97 | flexDirection: 'row',
98 | alignItems: 'center',
99 | paddingTop: 8,
100 | paddingBottom: 8,
101 | },
102 | image: {
103 | width: 100,
104 | height: '100%',
105 | borderRadius: 4,
106 | marginRight: 10,
107 | },
108 | historyItemTextWrapper: {
109 | flex: 1,
110 | height: '100%',
111 | flexDirection: 'column',
112 | justifyContent: 'space-between',
113 | },
114 | historyItemTitle: {
115 | fontSize: 13,
116 | color: TOMATOX_THEME.FONT_COLOR,
117 | },
118 | historyItemDesc: {
119 | fontSize: 11,
120 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
121 | },
122 | });
123 |
--------------------------------------------------------------------------------
/src/views/live/live.tsx:
--------------------------------------------------------------------------------
1 | import React, {useCallback, useEffect, useRef, useState} from 'react';
2 | import {
3 | NativeSyntheticEvent,
4 | ScrollView,
5 | StyleSheet,
6 | Text,
7 | TextInput,
8 | TextInputSubmitEditingEventData,
9 | View
10 | } from 'react-native';
11 | import {TOMATOX_THEME} from '../../utils/theme';
12 | import {queryLive} from '../../utils/request';
13 | import TomatoxVideo from '../../components/tomatox-video/tomatox-video';
14 | import {useFocusEffect, useNavigation} from '@react-navigation/native'
15 |
16 | export default function Live() {
17 | const liveResAll = useRef([])
18 | const [liveRes, setLiveRes] = useState([]);
19 | const [src, setSrc] = useState('');
20 | const [sourceLoaded, setSourceLoaded] = useState(false)
21 | const navigation = useNavigation()
22 |
23 | useEffect(() => {
24 | queryLive().then(res => {
25 | const result = res as ILiveResource[]
26 | liveResAll.current = result;
27 | setLiveRes(result)
28 | setSourceLoaded(true)
29 | });
30 | }, []);
31 |
32 | const searchLiveRes = (e: NativeSyntheticEvent) => {
33 | setLiveRes(liveResAll.current.filter(item => item.sourceName.toLowerCase().includes(e.nativeEvent.text.toLowerCase())))
34 | }
35 |
36 | return (
37 |
38 | {}} navigation={navigation} />
39 |
40 |
47 | {
48 | sourceLoaded ?
49 |
50 |
51 | {liveRes.map(item => (
52 | setSrc(item.src)}
54 | numberOfLines={1}
55 | ellipsizeMode={'tail'}
56 | style={[style.liveItem, item.src === src ? style.liveItemActive : undefined]}
57 | key={item.sourceName}
58 | >
59 | {item.sourceName}
60 |
61 | ))}
62 |
65 |
66 |
67 | :
68 | 正在加载数据...
69 | }
70 |
71 |
72 | );
73 | }
74 |
75 | const style = StyleSheet.create({
76 | fullWrapper: {
77 | flex: 1,
78 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
79 | },
80 | contentWrapper: {
81 | flex: 1,
82 | padding: 15,
83 | },
84 | searchBar: {
85 | width: '100%',
86 | height: 35,
87 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
88 | borderRadius: 30,
89 | fontSize: 14,
90 | paddingTop: 0,
91 | paddingBottom: 0,
92 | paddingLeft: 15,
93 | paddingRight: 15,
94 | marginBottom: 15,
95 | color: TOMATOX_THEME.FONT_COLOR,
96 | },
97 | liveList: {
98 | flex: 1,
99 | flexDirection: 'row',
100 | flexWrap: 'wrap',
101 | justifyContent: 'space-around',
102 | },
103 | liveItem: {
104 | width: '45%',
105 | marginBottom: 10,
106 | borderLeftWidth: 4,
107 | borderLeftColor: TOMATOX_THEME.FONT_COLOR,
108 | color: TOMATOX_THEME.FONT_COLOR,
109 | paddingLeft: 15,
110 | },
111 | liveItemActive: {
112 | color: TOMATOX_THEME.THEME_COLOR,
113 | borderLeftColor: TOMATOX_THEME.THEME_COLOR,
114 | },
115 | liveItemEmpty: {
116 | width: '45%',
117 | marginBottom: 10,
118 | },
119 | loadingText: {
120 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
121 | width: '100%',
122 | textAlign: "center"
123 | }
124 | });
125 |
--------------------------------------------------------------------------------
/src/views/origins/origins.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import {ScrollView, StyleSheet, Text, View} from 'react-native';
3 | import {TOMATOX_THEME} from '../../utils/theme';
4 | import TomatoxHeader from '../../components/tomatox-header/tomatox-header';
5 | import {useNavigation} from '@react-navigation/native';
6 | import LinearGradient from 'react-native-linear-gradient';
7 | import Icon from 'react-native-vector-icons/Feather';
8 | import constants from '../../utils/constants';
9 | import {TouchableOpacity} from 'react-native-gesture-handler';
10 | import {changeActiveOrigin, deleteOrigin, queryAllOrigins} from "../../utils/storage/origins-storage";
11 |
12 | export default function Origins() {
13 | const navigation = useNavigation();
14 | const [originList, setOriginList] = useState([]);
15 | const [showAddOpt, setShowAddOpt] = useState(false)
16 |
17 | useEffect(() => {
18 | setOriginList([
19 | {id: '默认', url: constants.DEFAULT_ORIGIN, active: true, timestamp: 0},
20 | ...queryAllOrigins()
21 | ]);
22 | }, []);
23 |
24 | const delOrigin = (id: string) => {
25 | setOriginList(originList.filter(item => item.id !== id));
26 | deleteOrigin(id)
27 | };
28 |
29 | const chooseOrigin = (id: string) => {
30 | setOriginList(originList.map(item => { return {...item, active: item.id === id}}))
31 | changeActiveOrigin(id)
32 | };
33 |
34 | return (
35 |
36 | setShowAddOpt(!showAddOpt)}}
40 | />
41 |
45 | {
46 | originList.map(item => (
47 |
54 | chooseOrigin(item.id)}>
55 | {item.id}
56 | {item.url}
57 |
58 |
59 | !item.active && delOrigin(item.id)}/>
62 |
63 |
64 | ))
65 | }
66 |
67 |
68 | );
69 | }
70 |
71 | const style = StyleSheet.create({
72 | fullWrapper: {
73 | flex: 1,
74 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
75 | },
76 | contentWrapper: {
77 | flex: 1,
78 | paddingTop: 10,
79 | },
80 | originItem: {
81 | height: 40,
82 | width: '100%',
83 | marginBottom: 10,
84 | alignItems: 'center',
85 | flexWrap: 'nowrap',
86 | flexDirection: 'row',
87 | },
88 | floatBottom: {
89 | left: '5%',
90 | width: '90%',
91 | borderRadius: 4,
92 | height: 35,
93 | backgroundColor: TOMATOX_THEME.THEME_COLOR,
94 | justifyContent: 'center',
95 | alignItems: 'center',
96 | },
97 | bottomText: {
98 | color: TOMATOX_THEME.FONT_COLOR,
99 | fontSize: 13,
100 | },
101 | itemTextWrapper: {
102 | flex: 1,
103 | flexDirection:'row',
104 | flexWrap: 'nowrap',
105 | height: '100%',
106 | alignItems: 'center',
107 | },
108 | itemId: {
109 | width: '20%',
110 | fontSize: 14,
111 | paddingLeft: 15,
112 | },
113 | itemUrl: {
114 | flex: 1,
115 | fontSize: 14,
116 | paddingLeft: 15,
117 | paddingRight: 15,
118 | },
119 | });
120 |
--------------------------------------------------------------------------------
/src/views/player/player.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useRef, useState} from 'react';
2 | import {StyleSheet, View} from 'react-native';
3 | import TomatoxVideo from '../../components/tomatox-video/tomatox-video';
4 | import TomatoxDrawer from '../../components/tomatox-drawer/tomatox-drawer';
5 | import {useRoute} from '@react-navigation/native';
6 | import {TOMATOX_THEME} from '../../utils/theme';
7 | import {useNavigation} from '@react-navigation/native';
8 | import {insertOrUpdateData, queryData} from '../../utils/storage/storage';
9 | import {TABLE_NAME} from '../../utils/storage/table-define';
10 | import {convertSecondToTime} from '../../utils/time-converter';
11 |
12 | const style = StyleSheet.create({
13 | playerWrapper: {
14 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
15 | height: '100%',
16 | display: 'flex',
17 | flexDirection: 'column',
18 | },
19 | });
20 |
21 | export default function Player() {
22 | const navigation = useNavigation();
23 | const {params} = useRoute();
24 | const [resource, setResource] = useState(params as any);
25 | const [curPlay, setCurPlay] = useState(resource.playList.index[0]);
26 | const init = useRef(true)
27 |
28 | useEffect(() => {
29 | const historyResource = queryData(TABLE_NAME.TOMATOX_HISTORY, resource.id) as IPlayHistoryResource|undefined
30 | if (historyResource) {
31 | setCurPlay(historyResource.historyPlayKey)
32 | setResource(historyResource)
33 | }
34 | }, [])
35 |
36 | const playNext = (noNext: () => void) => {
37 | init.current = false
38 | const idx = resource.playList.index.indexOf(curPlay);
39 | if ( idx < resource.playList.index.length - 1) {
40 | setCurPlay(resource.playList.index[idx + 1]);
41 | } else {
42 | noNext();
43 | }
44 | };
45 |
46 | const generateHistoryDesc = (date: number, key: string) => {
47 | return `播放至 ${key} ${convertSecondToTime(date, date)}`;
48 | };
49 |
50 | const writeHistoryRecord = (playPos: number) => {
51 | insertOrUpdateData(TABLE_NAME.TOMATOX_HISTORY, {
52 | ...resource,
53 | collectDate: undefined,
54 | historyPlayDate: Date.now(),
55 | historyPlayDesc: generateHistoryDesc(playPos, curPlay),
56 | historyPlayKey: curPlay,
57 | historyPlayTime: Math.floor(playPos),
58 | });
59 | };
60 |
61 | return (
62 |
63 |
71 | {init.current = false; setCurPlay(key)}}/>
72 |
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/src/views/recommend/recommend.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Image,
4 | StyleSheet,
5 | Text,
6 | View,
7 | } from 'react-native';
8 | import TIcon from '../../images/png/tomatox.png';
9 | import {queryTypes} from '../../utils/request';
10 | import TomatoxWaterfall from '../../components/tomatox-waterfall/tomatox-waterfall';
11 | import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
12 | import SplashScreen from 'react-native-splash-screen';
13 | import {TOMATOX_THEME} from '../../utils/theme';
14 | import Icon from 'react-native-vector-icons/Feather';
15 |
16 | let TabViewCache: any;
17 | const TopTab = createMaterialTopTabNavigator();
18 |
19 | function topTabScreen(type: number) {
20 | return () => ;
21 | }
22 | export default class Recommend extends React.Component{
23 |
24 | constructor(props: any) {
25 | super(props);
26 | this.state = {
27 | classifyList: [],
28 | selectedTabIdx: -1,
29 | };
30 | }
31 |
32 | private createTabView() {
33 | if (this.state.classifyList.length === 0) {
34 | return <>>;
35 | }
36 | if (TabViewCache) {
37 | return TabViewCache;
38 | }
39 | TabViewCache = (
40 |
60 | {this.state.classifyList.map((item: any) => (
61 |
66 | ))}
67 |
68 | );
69 |
70 | return TabViewCache;
71 | }
72 |
73 | componentDidMount(): void {
74 | queryTypes().then(res => {
75 | res.unshift({id: -1, name: '最新'});
76 | this.setState({
77 | classifyList: res,
78 | });
79 | SplashScreen.hide();
80 | });
81 | }
82 | render(): React.ReactNode {
83 | return (
84 |
85 |
86 |
87 |
88 | this.props.navigation.navigate('Search')}>
89 | 电影、电视剧、综艺...
90 |
91 | this.props.navigation.navigate('Live')} style={style.titleIcon} />
92 |
93 |
94 | { this.createTabView() }
95 |
96 | );
97 | }
98 |
99 | private switchTab(id: any) {
100 | this.setState({
101 | selectedTabIdx: id,
102 | });
103 | }
104 | }
105 |
106 | const style = StyleSheet.create({
107 | fullWrapper: {
108 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
109 | flex: 1,
110 | },
111 | titleBar: {
112 | height: 60,
113 | flexDirection: 'row',
114 | alignItems: 'center',
115 | justifyContent: 'space-between',
116 | paddingLeft: 10,
117 | paddingRight: 10,
118 | },
119 | titleImg: {
120 | width: 40,
121 | height: 40,
122 | marginRight: 20,
123 | },
124 | titleInput: {
125 | flex: 1,
126 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
127 | height: 30,
128 | paddingTop: 0,
129 | paddingBottom: 0,
130 | borderRadius: 30,
131 | paddingLeft: 15,
132 | paddingRight: 15,
133 | marginRight: 15,
134 | justifyContent: 'center',
135 | },
136 | titleInputText: {
137 | color: TOMATOX_THEME.DISABLED_FONT_COLOR,
138 | },
139 | titleIcon: {
140 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
141 | fontSize: 20,
142 | },
143 | tabLabel: {
144 | color: TOMATOX_THEME.FONT_COLOR,
145 | marginLeft: 20,
146 | textAlign: 'center',
147 | paddingBottom: 5,
148 | },
149 | tabLabelActive: {
150 | color: TOMATOX_THEME.THEME_COLOR,
151 | borderBottomWidth: 4,
152 | borderBottomColor: TOMATOX_THEME.THEME_COLOR,
153 | },
154 | });
155 |
--------------------------------------------------------------------------------
/src/views/search/search.tsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import {View, Text, StyleSheet, TextInput, NativeSyntheticEvent, TextInputSubmitEditingEventData} from 'react-native';
3 | import {TouchableOpacity} from 'react-native-gesture-handler';
4 | import {useNavigation} from '@react-navigation/native';
5 | import TomatoxWaterfall from '../../components/tomatox-waterfall/tomatox-waterfall';
6 | import {TOMATOX_THEME} from '../../utils/theme';
7 | import {SafeAreaView} from 'react-native-safe-area-context';
8 |
9 | export default function Search() {
10 | const navigation = useNavigation();
11 | const [keyword, setKeyword] = useState('');
12 |
13 | const searchByKeyword = (event: NativeSyntheticEvent) => {
14 | setKeyword(event.nativeEvent.text);
15 | };
16 |
17 | return (
18 |
19 |
20 |
21 |
29 | navigation.goBack()}>
30 | 取消
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | );
39 | }
40 |
41 | const style = StyleSheet.create({
42 | wrapper: {
43 | flex: 1,
44 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
45 | },
46 | searchWrapper: {
47 | margin: 10,
48 | flexDirection: 'row',
49 | alignItems: 'center',
50 | flexWrap: 'nowrap',
51 | height: 40,
52 | },
53 | searchInput: {
54 | flex: 1,
55 | color: TOMATOX_THEME.FONT_COLOR,
56 | backgroundColor: TOMATOX_THEME.COMPONENT_DARK_BACKGROUND,
57 | height: 35,
58 | paddingTop: 0,
59 | paddingBottom: 0,
60 | paddingLeft: 20,
61 | paddingRight: 20,
62 | borderRadius: 35,
63 | },
64 | searchText: {
65 | color: TOMATOX_THEME.FONT_COLOR,
66 | fontSize: 15,
67 | paddingLeft: 20,
68 | paddingRight: 5,
69 | },
70 | contentWrapper: {
71 | flex: 1,
72 | },
73 | });
74 |
--------------------------------------------------------------------------------
/src/views/setting/setting.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Image, Linking, ScrollView, StyleSheet, Text, View} from 'react-native';
3 | import {TOMATOX_THEME} from '../../utils/theme';
4 | import {version, homepage, bugs} from '../../../package.json';
5 | import Icon from 'react-native-vector-icons/Feather';
6 | import {TouchableHighlight} from 'react-native-gesture-handler';
7 | import {useNavigation} from '@react-navigation/native'
8 |
9 | function SettingItem(props: {name: string, value?: string, onPress: () => any}) {
10 | return (
11 |
12 |
13 | {props.name}
14 |
15 | {props.value || ''}{' '}
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | export default function Setting() {
24 | const {navigate} = useNavigation()
25 | return (
26 |
27 |
28 |
29 | TOMATOX
30 | Version {version}
31 |
32 |
33 |
34 | {navigate('Origins')}} />
35 | {}} />
36 | Linking.openURL(homepage)} />
37 | Linking.openURL(bugs)} />
38 | {}} />
39 |
40 |
41 | );
42 | }
43 |
44 | const style = StyleSheet.create({
45 | fullWrapper: {
46 | flex: 1,
47 | backgroundColor: TOMATOX_THEME.BACKGROUND_COLOR,
48 | },
49 | settingTitle: {
50 | height: 300,
51 | justifyContent: 'center',
52 | alignItems: 'center',
53 | },
54 | icon: {
55 | width: 70,
56 | height: 70,
57 | },
58 | settingTitleName: {
59 | color: TOMATOX_THEME.FONT_COLOR,
60 | fontSize: 20,
61 | marginTop: 30,
62 | marginBottom: 5,
63 | fontWeight: '600',
64 | },
65 | settingTitleVersion: {
66 | color: TOMATOX_THEME.FONT_COLOR,
67 | fontSize: 14,
68 | fontWeight: '500',
69 | },
70 | settingContent: {
71 | },
72 | settingContentWrapper: {
73 | paddingLeft: 25,
74 | paddingRight: 25,
75 | },
76 | settingContentItem: {
77 | height: 50,
78 | borderColor: TOMATOX_THEME.SPLIT_LINE_COLOR,
79 | borderBottomWidth: 1,
80 | flexDirection: 'row',
81 | justifyContent: 'space-between',
82 | flexWrap: 'nowrap',
83 | alignItems: 'center',
84 | },
85 | settingContentItemEmpty: {
86 | height: 0,
87 | borderColor: TOMATOX_THEME.SPLIT_LINE_COLOR,
88 | borderBottomWidth: 1,
89 | marginLeft: 22,
90 | marginRight: 22,
91 | },
92 | settingContentText: {
93 | fontSize: 15,
94 | color: TOMATOX_THEME.FONT_COLOR,
95 | },
96 | settingContentTextC: {
97 | fontSize: 15,
98 | color: TOMATOX_THEME.UNIMPORTANT_FONT_COLOR,
99 | }
100 | });
101 |
--------------------------------------------------------------------------------
/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": false /* Skip type checking of declaration files. */
49 |
50 | /* Source Map Options */
51 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
52 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
53 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
54 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
55 |
56 | /* Experimental Options */
57 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
58 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
59 | },
60 | "exclude": [
61 | "node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------