Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
yarn.lock
25 changes: 25 additions & 0 deletions App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import {createStore, applyMiddleware} from 'redux';
import createSagaMiddleware from 'redux-saga';
import { composeWithDevTools } from 'redux-devtools-extension';
import { Provider } from 'react-redux';


import ScreensNavigation from './src/navigation';
import rootSaga from './src/store/actions';
import rootReducer from './src/store/reducers';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(sagaMiddleware)));
sagaMiddleware.run(rootSaga);

const App = () => {
return (
<Provider store={store}>
<ScreensNavigation />
</Provider>
);
};

export default App;
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,24 @@ Please clone the repository, complete the exercise, and submit a Pull Request fo

A) Describe the strategy used to consume the API endpoints and the data management.

> First of all, when we define a user story the backend need to understand the feature and how can they proceed to make the endpoint and the service to deliver, so, if the backend is in our team, the task is easy because its easier change with an API with graphql can be easier or the structure in the backend and provide the info with the complete structure, but if the backend is not in our team or it's worse change the structure on the backend we can talk with the UX or designers to change the wireframe and only get a link or button to get the ingredients or something like that.
If nothing of these alternatives is valid, so one of many solutions is call the api in each card, but, I think that solution is the worst because the performance, data, servers, network, memory, a lot of things will be implicated in this, so I think the best way to proceed for this case is with pagination in the front-end layer.
How?, We render only 5 cards (can be 10), call the ingredients API 5 times with the respective id, and use the onEndReached of Flatlist, so when the user scroll until the last card, call the other 5 cards with the api and so on.

>I saved the data of the first API on the store and also the data that its render and fill it in each pagination call

B) Explain which library was used for the routing and why. Would you use the same for a consumer facing app targeting thousands of users? Why?

> I used React Navigation, because its the most used library and with good community and stars on github.

C) Have you used any strategy to optimize the performance of the list generated for the first feature?

> Yes, It's difficult to improve more the performance because with 10 cards initially its also bad because the endpoint is not good, but we can use memo and some other strategies. I use pagination with 10 first calls to detail api, but I know we can improve the performance a little bit more.

D) Would you like to add any further comments or observations?

> The challenge was very good, I made the search input as a component inside the container and not in the header bar because, I used react navigation with native base and with native base It can be easier with the header tag use the SearchBar, but the behavior meets the requirement


## Overview:

Expand Down Expand Up @@ -104,4 +116,12 @@ B) Include test coverage for the core features.
Thank you and looking forward to seeing your great work!


## Instructions:

```
yarn install

yarn android / ios

```

14 changes: 14 additions & 0 deletions __tests__/App-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @format
*/

import 'react-native';
import React from 'react';
import App from '../App';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
renderer.create(<App />);
});
Binary file not shown.
Binary file not shown.
Binary file added android/.gradle/5.5/fileChanges/last-build.bin
Binary file not shown.
Binary file added android/.gradle/5.5/fileContent/fileContent.lock
Binary file not shown.
Binary file added android/.gradle/5.5/fileHashes/fileHashes.bin
Binary file not shown.
Binary file added android/.gradle/5.5/fileHashes/fileHashes.lock
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file added android/.gradle/5.5/javaCompile/jarAnalysis.bin
Binary file not shown.
Binary file added android/.gradle/5.5/javaCompile/javaCompile.lock
Binary file not shown.
Binary file added android/.gradle/5.5/javaCompile/taskHistory.bin
Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions android/.gradle/buildOutputCleanup/cache.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Thu Sep 26 15:30:06 COT 2019
gradle.version=5.5
Binary file not shown.
Empty file.
55 changes: 55 additions & 0 deletions android/app/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# To learn about Buck see [Docs](https://buckbuild.com/).
# To run your application with Buck:
# - install Buck
# - `npm start` - to start the packager
# - `cd android`
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
# - `buck install -r android/app` - compile, install and run application
#

load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")

lib_deps = []

create_aar_targets(glob(["libs/*.aar"]))

create_jar_targets(glob(["libs/*.jar"]))

android_library(
name = "all-libs",
exported_deps = lib_deps,
)

android_library(
name = "app-code",
srcs = glob([
"src/main/java/**/*.java",
]),
deps = [
":all-libs",
":build_config",
":res",
],
)

android_build_config(
name = "build_config",
package = "com.cocktails",
)

android_resource(
name = "res",
package = "com.cocktails",
res = "src/main/res",
)

android_binary(
name = "app",
keystore = "//android/keystores:debug",
manifest = "src/main/AndroidManifest.xml",
package_type = "debug",
deps = [
":app-code",
],
)
202 changes: 202 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
apply plugin: "com.android.application"

import com.android.build.OutputFile

/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation
* entryFile: "index.android.js",
*
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/

project.ext.react = [
entryFile: "index.js",
enableHermes: false, // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"

/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false

/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false

/**
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'

/**
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and mirrored here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);

android {
compileSdkVersion rootProject.ext.compileSdkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
applicationId "com.cocktails"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://facebook.github.io/react-native/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}

}
}
}

dependencies {
implementation project(':react-native-vector-icons')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules

if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
Loading