initial
This commit is contained in:
commit
b9cf44cc13
44 changed files with 19887 additions and 0 deletions
15
.eslintrc.js
Normal file
15
.eslintrc.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: [
|
||||
"@typescript-eslint",
|
||||
],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
],
|
||||
rules: {
|
||||
"indent": ["error", 2],
|
||||
"quotes": ["error", "double"],
|
||||
}
|
||||
};
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
17
App.tsx
Normal file
17
App.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from "react";
|
||||
import { SafeAreaView, View, Text } from "react-native";
|
||||
import Home from "./pages/Home";
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<View styles={{ backgroundColor: "#00ff00" }}>
|
||||
<Text styles={{ color: "white" }}>Poggers Fish</Text>
|
||||
|
||||
<Home />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
2
android/.gitignore
vendored
Normal file
2
android/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.gradle
|
||||
app/build
|
36
android/app/build.gradle
Normal file
36
android/app/build.gradle
Normal file
|
@ -0,0 +1,36 @@
|
|||
apply plugin: "com.android.application"
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
|
||||
android {
|
||||
compileSdkVersion = rootProject.ext.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "io.mzhang.iqeats"
|
||||
targetSdkVersion = rootProject.ext.targetSdkVersion
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
versionCode = 1
|
||||
versionName = "0.1"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "com.facebook.react:react-native:+"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
}
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
implementation jscFlavor
|
||||
}
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
17
android/app/src/main/AndroidManifest.xml
Normal file
17
android/app/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.mzhang.iqeats">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:theme="@style/AppTheme"
|
||||
android:usesCleartextTraffic="true">
|
||||
<!-- TODO: don't leave usesCleartextTraffic in -->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
BIN
android/app/src/main/assets/fonts/AntDesign.ttf
Normal file
BIN
android/app/src/main/assets/fonts/AntDesign.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Entypo.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Entypo.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/EvilIcons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/EvilIcons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Feather.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Feather.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/FontAwesome.ttf
Normal file
BIN
android/app/src/main/assets/fonts/FontAwesome.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf
Normal file
BIN
android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf
Normal file
BIN
android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf
Normal file
BIN
android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Fontisto.ttf
Executable file
BIN
android/app/src/main/assets/fonts/Fontisto.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Foundation.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Foundation.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Ionicons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Ionicons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/MaterialIcons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/MaterialIcons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Octicons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Octicons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/SimpleLineIcons.ttf
Normal file
BIN
android/app/src/main/assets/fonts/SimpleLineIcons.ttf
Normal file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/Zocial.ttf
Normal file
BIN
android/app/src/main/assets/fonts/Zocial.ttf
Normal file
Binary file not shown.
16
android/app/src/main/java/io/mzhang/iqeats/MainActivity.java
Normal file
16
android/app/src/main/java/io/mzhang/iqeats/MainActivity.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package io.mzhang.iqeats;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.facebook.react.ReactActivity;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "iqeats";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package io.mzhang.iqeats;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new ReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
// initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("io.mzhang.iqeats.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
android/app/src/main/res/values/strings.xml
Normal file
3
android/app/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">iQeats</string>
|
||||
</resources>
|
5
android/app/src/main/res/values/styles.xml
Normal file
5
android/app/src/main/res/values/styles.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:textColor">#000000</item>
|
||||
</style>
|
||||
</resources>
|
27
android/build.gradle
Normal file
27
android/build.gradle
Normal file
|
@ -0,0 +1,27 @@
|
|||
buildscript {
|
||||
ext {
|
||||
compileSdkVersion = 29
|
||||
targetSdkVersion = 29
|
||||
minSdkVersion = 21
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:4.1.0")
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
maven { url("$rootDir/../node_modules/react-native/android") }
|
||||
maven { url("$rootDir/../node_modules/jsc-android/dist") }
|
||||
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url "https://www.jitpack.io" }
|
||||
}
|
||||
}
|
3
android/gradle.properties
Normal file
3
android/gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
FLIPPER_VERSION=0.75.1
|
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
185
android/gradlew
vendored
Executable file
185
android/gradlew
vendored
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
89
android/gradlew.bat
vendored
Normal file
89
android/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
3
android/settings.gradle
Normal file
3
android/settings.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
rootProject.name = "iqeats"
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ":app"
|
4
app.json
Normal file
4
app.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "iqeats",
|
||||
"displayName": "iQeats"
|
||||
}
|
6
assets/data/demo.js
Normal file
6
assets/data/demo.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = [
|
||||
{ name: "osu!" },
|
||||
{ name: "Taco Bell" },
|
||||
{ name: "McDonalds" },
|
||||
{ name: "Five Guys" },
|
||||
];
|
14
assets/styles/index.js
Normal file
14
assets/styles/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { StyleSheet, Dimensions } from "react-native";
|
||||
|
||||
const WHITE = "#FFFFFF";
|
||||
|
||||
const DIMENSION_WIDTH = Dimensions.get("window").width;
|
||||
const DIMENSION_HEIGHT = Dimensions.get("window").height;
|
||||
|
||||
export default StyleSheet.create({
|
||||
suggestionsCard: {
|
||||
backgroundColor: WHITE,
|
||||
margin: 10,
|
||||
padding: 10,
|
||||
}
|
||||
});
|
30
components/Card.tsx
Normal file
30
components/Card.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {
|
||||
View,
|
||||
Animated,
|
||||
Text,
|
||||
} from "react-native";
|
||||
|
||||
const Card = ({ style, children }) => <View style={style}>{children}</View>;
|
||||
|
||||
Card.propTypes = {
|
||||
children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,
|
||||
style: PropTypes.oneOfType([PropTypes.number, PropTypes.object, PropTypes.array]),
|
||||
onSwipedLeft: PropTypes.func,
|
||||
onSwipedRight:PropTypes.func,
|
||||
onSwipedTop: PropTypes.func,
|
||||
onSwipedBottom: PropTypes.func,
|
||||
onSwiped: PropTypes.func,
|
||||
}
|
||||
|
||||
Card.defaultProps = {
|
||||
style:{},
|
||||
onSwiped: () => {},
|
||||
onSwipedLeft: () => {},
|
||||
onSwipedRight: () => {},
|
||||
onSwipedTop: () => {},
|
||||
onSwipedBottom: () => {},
|
||||
}
|
||||
|
||||
export default Card;
|
528
components/CardStack.tsx
Normal file
528
components/CardStack.tsx
Normal file
|
@ -0,0 +1,528 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types"
|
||||
import {
|
||||
View,
|
||||
Animated,
|
||||
PanResponder,
|
||||
Dimensions,
|
||||
Text,
|
||||
Platform
|
||||
} from "react-native";
|
||||
|
||||
const { height, width } = Dimensions.get("window");
|
||||
|
||||
class CardStack extends Component {
|
||||
static distance(x, y) {
|
||||
return Math.hypot(x, y);
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
drag: new Animated.ValueXY({ x: 0, y: 0 }),
|
||||
dragDistance: new Animated.Value(0),
|
||||
sindex: 0, // index to the next card to be renderd mod card.length
|
||||
cardA: null,
|
||||
cardB: null,
|
||||
topCard: "cardA",
|
||||
cards: [],
|
||||
touchStart: 0,
|
||||
};
|
||||
this.distance = this.constructor.distance;
|
||||
this._panResponder = PanResponder.create({
|
||||
onStartShouldSetPanResponder: (evt, gestureState) => false,
|
||||
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
|
||||
onMoveShouldSetPanResponder: (evt, gestureState) => {
|
||||
const isVerticalSwipe = Math.sqrt(
|
||||
Math.pow(gestureState.dx, 2) < Math.pow(gestureState.dy, 2)
|
||||
)
|
||||
if (!this.props.verticalSwipe && isVerticalSwipe) {
|
||||
return false
|
||||
}
|
||||
return Math.sqrt(Math.pow(gestureState.dx, 2) + Math.pow(gestureState.dy, 2)) > 10
|
||||
},
|
||||
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
|
||||
const isVerticalSwipe = Math.sqrt(
|
||||
Math.pow(gestureState.dx, 2) < Math.pow(gestureState.dy, 2)
|
||||
)
|
||||
if (!this.props.verticalSwipe && isVerticalSwipe) {
|
||||
return false
|
||||
}
|
||||
return Math.sqrt(Math.pow(gestureState.dx, 2) + Math.pow(gestureState.dy, 2)) > 10
|
||||
},
|
||||
onPanResponderGrant: (evt, gestureState) => {
|
||||
this.props.onSwipeStart();
|
||||
this.setState({ touchStart: new Date().getTime() });
|
||||
},
|
||||
onPanResponderMove: (evt, gestureState) => {
|
||||
const movedX = gestureState.moveX - gestureState.x0;
|
||||
const movedY = gestureState.moveY - gestureState.y0;
|
||||
this.props.onSwipe(movedX, movedY);
|
||||
const { verticalSwipe, horizontalSwipe } = this.props;
|
||||
const dragDistance = this.distance((horizontalSwipe) ? gestureState.dx : 0, (verticalSwipe) ? gestureState.dy : 0);
|
||||
this.state.dragDistance.setValue(dragDistance);
|
||||
this.state.drag.setValue({ x: (horizontalSwipe) ? gestureState.dx : 0, y: (verticalSwipe) ? gestureState.dy : 0 });
|
||||
},
|
||||
onPanResponderTerminationRequest: (evt, gestureState) => true,
|
||||
onPanResponderRelease: (evt, gestureState) => {
|
||||
this.props.onSwipeEnd();
|
||||
const currentTime = new Date().getTime();
|
||||
const swipeDuration = currentTime - this.state.touchStart;
|
||||
const {
|
||||
verticalThreshold,
|
||||
horizontalThreshold,
|
||||
disableTopSwipe,
|
||||
disableLeftSwipe,
|
||||
disableRightSwipe,
|
||||
disableBottomSwipe,
|
||||
} = this.props;
|
||||
|
||||
if (((Math.abs(gestureState.dx) > horizontalThreshold) ||
|
||||
(Math.abs(gestureState.dx) > horizontalThreshold * 0.6 &&
|
||||
swipeDuration < 150)
|
||||
) && this.props.horizontalSwipe) {
|
||||
|
||||
const swipeDirection = (gestureState.dx < 0) ? width * -1.5 : width * 1.5;
|
||||
if (swipeDirection < 0 && !disableLeftSwipe) {
|
||||
this._nextCard("left", swipeDirection, gestureState.dy, this.props.duration);
|
||||
}
|
||||
else if (swipeDirection > 0 && !disableRightSwipe) {
|
||||
this._nextCard("right", swipeDirection, gestureState.dy, this.props.duration);
|
||||
}
|
||||
else {
|
||||
this._resetCard();
|
||||
}
|
||||
} else if (((Math.abs(gestureState.dy) > verticalThreshold) ||
|
||||
(Math.abs(gestureState.dy) > verticalThreshold * 0.8 &&
|
||||
swipeDuration < 150)
|
||||
) && this.props.verticalSwipe) {
|
||||
|
||||
const swipeDirection = (gestureState.dy < 0) ? height * -1 : height;
|
||||
if (swipeDirection < 0 && !disableTopSwipe) {
|
||||
|
||||
this._nextCard("top", gestureState.dx, swipeDirection, this.props.duration);
|
||||
}
|
||||
else if (swipeDirection > 0 && !disableBottomSwipe) {
|
||||
this._nextCard("bottom", gestureState.dx, swipeDirection, this.props.duration);
|
||||
}
|
||||
else {
|
||||
this._resetCard();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._resetCard();
|
||||
}
|
||||
},
|
||||
onPanResponderTerminate: (evt, gestureState) => {
|
||||
},
|
||||
onShouldBlockNativeResponder: (evt, gestureState) => {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (typeof this.props.children === "undefined") return;
|
||||
if (!this._isSameChildren(this.props.children, prevProps.children)) {
|
||||
const children = Array.isArray(this.props.children) ? this.props.children : [this.props.children];
|
||||
const aIndex = (this.state.topCard == "cardA") ?
|
||||
this._getIndex(this.state.sindex - 2, children.length) :
|
||||
this._getIndex(this.state.sindex - 1, children.length);
|
||||
const bIndex = (this.state.topCard == "cardB") ?
|
||||
this._getIndex(this.state.sindex - 2, children.length) :
|
||||
this._getIndex(this.state.sindex - 1, children.length);
|
||||
this.setState({
|
||||
cards: children,
|
||||
cardA: children[aIndex] || null,
|
||||
cardB: children[bIndex] || null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_getIndex(index, cards){
|
||||
return this.props.loop ?
|
||||
this.mod(index, cards):
|
||||
index;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.initDeck();
|
||||
}
|
||||
|
||||
_isSameChildren(a, b) {
|
||||
if (typeof a != typeof b) return false;
|
||||
if (typeof a === "undefined") return false;
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
if (a.length != b.length) return false;
|
||||
for (const i in a) {
|
||||
if (a[i].key != b[i].key) { return false }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (a.key !== b.key) return false;
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
initDeck() {
|
||||
if (typeof this.props.children === "undefined") return;
|
||||
const { children, loop } = this.props;
|
||||
const cards = Array.isArray(children) ? children : [children];
|
||||
const initialIndexA = this.props.initialIndex < cards.length ? this.props.initialIndex : 0;
|
||||
const initialIndexB = loop ? this.mod(initialIndexA + 1, cards.length) : initialIndexA + 1;
|
||||
const cardA = cards[initialIndexA] || null;
|
||||
const cardB = cards[initialIndexB] || null;
|
||||
this.setState({
|
||||
cards,
|
||||
cardA,
|
||||
cardB,
|
||||
sindex: initialIndexB + 1,
|
||||
});
|
||||
}
|
||||
|
||||
_resetCard() {
|
||||
Animated.timing(
|
||||
this.state.dragDistance,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: this.props.duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start();
|
||||
Animated.spring(
|
||||
this.state.drag,
|
||||
{
|
||||
toValue: { x: 0, y: 0 },
|
||||
duration: this.props.duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start();
|
||||
}
|
||||
|
||||
goBackFromTop() {
|
||||
this._goBack("top");
|
||||
}
|
||||
|
||||
goBackFromRight() {
|
||||
this._goBack("right");
|
||||
}
|
||||
|
||||
goBackFromLeft() {
|
||||
this._goBack("left");
|
||||
}
|
||||
|
||||
goBackFromBottom() {
|
||||
this._goBack("bottom");
|
||||
}
|
||||
|
||||
mod(n, m) {
|
||||
return ((n % m) + m) % m;
|
||||
}
|
||||
|
||||
_goBack(direction) {
|
||||
const { cards, sindex, topCard } = this.state;
|
||||
|
||||
if ((sindex - 3) < 0 && !this.props.loop) return;
|
||||
|
||||
const previusCardIndex = this.mod(sindex - 3, cards.length)
|
||||
let update = {};
|
||||
if (topCard === "cardA") {
|
||||
update = {
|
||||
...update,
|
||||
cardB: cards[previusCardIndex]
|
||||
|
||||
}
|
||||
} else {
|
||||
update = {
|
||||
...update,
|
||||
cardA: cards[previusCardIndex],
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
...update,
|
||||
topCard: (topCard === "cardA") ? "cardB" : "cardA",
|
||||
sindex: sindex - 1
|
||||
}, () => {
|
||||
|
||||
switch (direction) {
|
||||
case "top":
|
||||
this.state.drag.setValue({ x: 0, y: -height });
|
||||
this.state.dragDistance.setValue(height);
|
||||
break;
|
||||
case "left":
|
||||
this.state.drag.setValue({ x: -width, y: 0 });
|
||||
this.state.dragDistance.setValue(width);
|
||||
break;
|
||||
case "right":
|
||||
this.state.drag.setValue({ x: width, y: 0 });
|
||||
this.state.dragDistance.setValue(width);
|
||||
break;
|
||||
case "bottom":
|
||||
this.state.drag.setValue({ x: 0, y: height });
|
||||
this.state.dragDistance.setValue(width);
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
Animated.spring(
|
||||
this.state.dragDistance,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: this.props.duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start();
|
||||
|
||||
Animated.spring(
|
||||
this.state.drag,
|
||||
{
|
||||
toValue: { x: 0, y: 0 },
|
||||
duration: this.props.duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start();
|
||||
})
|
||||
}
|
||||
|
||||
swipeTop(d = null) {
|
||||
this._nextCard("top", 0, -height, d || this.props.duration);
|
||||
}
|
||||
|
||||
swipeBottom(d = null) {
|
||||
this._nextCard("bottom", 0, height, d || this.props.duration);
|
||||
}
|
||||
|
||||
swipeRight(d = null) {
|
||||
this._nextCard("right", width * 1.5, 0, d || this.props.duration);
|
||||
}
|
||||
|
||||
swipeLeft(d = null) {
|
||||
this._nextCard("left", -width * 1.5, 0, d || this.props.duration);
|
||||
}
|
||||
|
||||
_nextCard(direction, x, y, duration = 400) {
|
||||
const { verticalSwipe, horizontalSwipe, loop } = this.props;
|
||||
const { sindex, cards, topCard } = this.state;
|
||||
|
||||
// index for the next card to be renderd
|
||||
const nextCard = (loop) ? (Math.abs(sindex) % cards.length) : sindex;
|
||||
|
||||
// index of the swiped card
|
||||
const index = (loop) ? this.mod(nextCard - 2, cards.length) : nextCard - 2;
|
||||
|
||||
if (index === cards.length - 1) {
|
||||
this.props.onSwipedAll();
|
||||
}
|
||||
|
||||
if ((sindex - 2 < cards.length) || (loop)) {
|
||||
Animated.spring(
|
||||
this.state.dragDistance,
|
||||
{
|
||||
toValue: 220,
|
||||
duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start();
|
||||
|
||||
Animated.timing(
|
||||
this.state.drag,
|
||||
{
|
||||
toValue: { x: (horizontalSwipe) ? x : 0, y: (verticalSwipe) ? y : 0 },
|
||||
duration,
|
||||
useNativeDriver: this.props.useNativeDriver || false,
|
||||
}
|
||||
).start(() => {
|
||||
|
||||
const newTopCard = (topCard === "cardA") ? "cardB" : "cardA";
|
||||
|
||||
let update = {};
|
||||
if (newTopCard === "cardA") {
|
||||
update = {
|
||||
...update,
|
||||
cardB: cards[nextCard]
|
||||
};
|
||||
}
|
||||
if (newTopCard === "cardB") {
|
||||
update = {
|
||||
...update,
|
||||
cardA: cards[nextCard],
|
||||
};
|
||||
}
|
||||
this.state.drag.setValue({ x: 0, y: 0 });
|
||||
this.state.dragDistance.setValue(0);
|
||||
this.setState({
|
||||
...update,
|
||||
topCard: newTopCard,
|
||||
sindex: nextCard + 1
|
||||
});
|
||||
|
||||
this.props.onSwiped(index);
|
||||
switch (direction) {
|
||||
case "left":
|
||||
this.props.onSwipedLeft(index);
|
||||
if (this.state.cards[index] && this.state.cards[index].props.onSwipedLeft)
|
||||
this.state.cards[index] && this.state.cards[index].props.onSwipedLeft();
|
||||
break;
|
||||
case "right":
|
||||
this.props.onSwipedRight(index);
|
||||
if (this.state.cards[index] && this.state.cards[index].props.onSwipedRight)
|
||||
this.state.cards[index].props.onSwipedRight();
|
||||
break;
|
||||
case "top":
|
||||
this.props.onSwipedTop(index);
|
||||
if (this.state.cards[index] && this.state.cards[index].props.onSwipedTop)
|
||||
this.state.cards[index].props.onSwipedTop();
|
||||
break;
|
||||
case "bottom":
|
||||
this.props.onSwipedBottom(index);
|
||||
if (this.state.cards[index] && this.state.cards[index].props.onSwipedBottom)
|
||||
this.state.cards[index].props.onSwipedBottom();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description CardB’s click feature is trigger the CardA on the card stack. (Solved on Android)
|
||||
* @see https://facebook.github.io/react-native/docs/view#pointerevents
|
||||
*/
|
||||
_setPointerEvents(topCard, topCardName) {
|
||||
return { pointerEvents: topCard === topCardName ? "auto" : "none" }
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { secondCardZoom, renderNoMoreCards } = this.props;
|
||||
const { drag, dragDistance, cardA, cardB, topCard, sindex } = this.state;
|
||||
|
||||
const scale = dragDistance.interpolate({
|
||||
inputRange: [0, 10, 220],
|
||||
outputRange: [secondCardZoom, secondCardZoom, 1],
|
||||
extrapolate: "clamp",
|
||||
});
|
||||
const rotate = drag.x.interpolate({
|
||||
inputRange: [width * -1.5, 0, width * 1.5],
|
||||
outputRange: this.props.outputRotationRange,
|
||||
extrapolate: "clamp",
|
||||
});
|
||||
|
||||
return (
|
||||
<View {...this._panResponder.panHandlers} style={[{ position: "relative" }, this.props.style]}>
|
||||
|
||||
{renderNoMoreCards()}
|
||||
|
||||
<Animated.View
|
||||
{...this._setPointerEvents(topCard, "cardB")}
|
||||
style={[{
|
||||
position: "absolute",
|
||||
zIndex: (topCard === "cardB") ? 3 : 2,
|
||||
...Platform.select({
|
||||
android: {
|
||||
elevation: (topCard === "cardB") ? 3 : 2,
|
||||
}
|
||||
}),
|
||||
transform: [
|
||||
{ rotate: (topCard === "cardB") ? rotate : "0deg" },
|
||||
{ translateX: (topCard === "cardB") ? drag.x : 0 },
|
||||
{ translateY: (topCard === "cardB") ? drag.y : 0 },
|
||||
{ scale: (topCard === "cardB") ? 1 : scale },
|
||||
]
|
||||
}, this.props.cardContainerStyle]}>
|
||||
{cardB}
|
||||
</Animated.View>
|
||||
<Animated.View
|
||||
{...this._setPointerEvents(topCard, "cardA")}
|
||||
style={[{
|
||||
position: "absolute",
|
||||
zIndex: (topCard === "cardA") ? 3 : 2,
|
||||
...Platform.select({
|
||||
android: {
|
||||
elevation: (topCard === "cardA") ? 3 : 2,
|
||||
}
|
||||
}),
|
||||
transform: [
|
||||
{ rotate: (topCard === "cardA") ? rotate : "0deg" },
|
||||
{ translateX: (topCard === "cardA") ? drag.x : 0 },
|
||||
{ translateY: (topCard === "cardA") ? drag.y : 0 },
|
||||
{ scale: (topCard === "cardA") ? 1 : scale },
|
||||
]
|
||||
}, this.props.cardContainerStyle]}>
|
||||
{cardA}
|
||||
</Animated.View>
|
||||
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CardStack.propTypes = {
|
||||
|
||||
children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,
|
||||
|
||||
style: PropTypes.oneOfType([PropTypes.number, PropTypes.object, PropTypes.array]),
|
||||
cardContainerStyle: PropTypes.oneOfType([PropTypes.number, PropTypes.object, PropTypes.array]),
|
||||
secondCardZoom: PropTypes.number,
|
||||
loop: PropTypes.bool,
|
||||
initialIndex: PropTypes.number,
|
||||
renderNoMoreCards: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
|
||||
onSwipeStart: PropTypes.func,
|
||||
onSwipeEnd: PropTypes.func,
|
||||
onSwiped: PropTypes.func,
|
||||
onSwipedLeft: PropTypes.func,
|
||||
onSwipedRight: PropTypes.func,
|
||||
onSwipedTop: PropTypes.func,
|
||||
onSwipedBottom: PropTypes.func,
|
||||
onSwiped: PropTypes.func,
|
||||
onSwipedAll: PropTypes.func,
|
||||
onSwipe: PropTypes.func,
|
||||
|
||||
disableBottomSwipe: PropTypes.bool,
|
||||
disableLeftSwipe: PropTypes.bool,
|
||||
disableRightSwipe: PropTypes.bool,
|
||||
disableTopSwipe: PropTypes.bool,
|
||||
verticalSwipe: PropTypes.bool,
|
||||
verticalThreshold: PropTypes.number,
|
||||
|
||||
horizontalSwipe: PropTypes.bool,
|
||||
horizontalThreshold: PropTypes.number,
|
||||
outputRotationRange: PropTypes.array,
|
||||
duration: PropTypes.number
|
||||
}
|
||||
|
||||
CardStack.defaultProps = {
|
||||
|
||||
style: {},
|
||||
cardContainerStyle: {},
|
||||
secondCardZoom: 0.95,
|
||||
loop: false,
|
||||
initialIndex: 0,
|
||||
renderNoMoreCards: () => { return (<Text>No More Cards</Text>) },
|
||||
onSwipeStart: () => null,
|
||||
onSwipeEnd: () => null,
|
||||
onSwiped: () => { },
|
||||
onSwipedLeft: () => { },
|
||||
onSwipedRight: () => { },
|
||||
onSwipedTop: () => { },
|
||||
onSwipedBottom: () => { },
|
||||
onSwipedAll: async () => { },
|
||||
onSwipe: () => { },
|
||||
|
||||
disableBottomSwipe: false,
|
||||
disableLeftSwipe: false,
|
||||
disableRightSwipe: false,
|
||||
disableTopSwipe: false,
|
||||
verticalSwipe: true,
|
||||
verticalThreshold: height / 4,
|
||||
horizontalSwipe: true,
|
||||
horizontalThreshold: width / 2,
|
||||
outputRotationRange: ["-15deg", "0deg", "15deg"],
|
||||
duration: 300
|
||||
}
|
||||
|
||||
export default CardStack;
|
27
components/SuggestionCard.tsx
Normal file
27
components/SuggestionCard.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import React from "react";
|
||||
import styles from "../assets/styles";
|
||||
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
} from "react-native";
|
||||
|
||||
const SuggestionCard = ({
|
||||
actions,
|
||||
description,
|
||||
image,
|
||||
matches,
|
||||
name,
|
||||
onPressLeft,
|
||||
onPressRight,
|
||||
status,
|
||||
variant,
|
||||
}) => {
|
||||
return (
|
||||
<View style={styles.suggestionsCard}>
|
||||
<Text>NAME IS {name}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default SuggestionCard;
|
11
index.js
Normal file
11
index.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
import { AppRegistry } from "react-native";
|
||||
import App from "./App";
|
||||
import { name as appName } from "./app.json";
|
||||
import { NavigationContainer } from "@react-navigation/native";
|
||||
|
||||
export default function Main() {
|
||||
return <NavigationContainer><App /></NavigationContainer>;
|
||||
}
|
||||
|
||||
AppRegistry.registerComponent(appName, () => Main);
|
1
metro.config.js
Normal file
1
metro.config.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = {};
|
18703
package-lock.json
generated
Normal file
18703
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
23
package.json
Normal file
23
package.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"scripts": {
|
||||
"start": "npx @react-native-community/cli start",
|
||||
"android": "npx @react-native-community/cli run-android",
|
||||
"lint": "eslint . --ext .js,.tsx --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/metro-config": "^0.1.82",
|
||||
"@react-native-community/cli": "^5.0.1",
|
||||
"@react-navigation/native": "^6.0.2",
|
||||
"react-native": "^0.64.0",
|
||||
"react-native-cli": "^2.0.1",
|
||||
"react-native-safe-area-context": "^3.3.0",
|
||||
"react-native-screens": "^3.5.0",
|
||||
"react-navigation": "^4.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.1",
|
||||
"@typescript-eslint/parser": "^4.29.1",
|
||||
"eslint": "^7.32.0",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
36
pages/Home.tsx
Normal file
36
pages/Home.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import React, { Component } from "react";
|
||||
import {
|
||||
View,
|
||||
Animated,
|
||||
Text,
|
||||
} from "react-native";
|
||||
|
||||
import styles from "../assets/styles";
|
||||
import demoData from "../assets/data/demo";
|
||||
|
||||
import Card from "../components/Card";
|
||||
import CardStack from "../components/CardStack";
|
||||
import SuggestionCard from "../components/SuggestionCard";
|
||||
|
||||
class Home extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<CardStack
|
||||
ref={swiper => (this.swiper = swiper)}
|
||||
verticalSwipe={false}
|
||||
>
|
||||
{demoData.map((item, index) => (
|
||||
<Card key={index}>
|
||||
<SuggestionCard
|
||||
name={item.name}
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</CardStack>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Home;
|
Loading…
Reference in a new issue