diff --git a/.expo-shared/assets.json b/.expo-shared/assets.json new file mode 100644 index 00000000..1e6decfb --- /dev/null +++ b/.expo-shared/assets.json @@ -0,0 +1,4 @@ +{ + "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true, + "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true +} diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 00000000..ea3ca3d0 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,29 @@ +name: ID PASS - MOSIP Resident Application + +on: + push: + branches: + - main + - develop + tags: + - '*' + pull_request: + branches: + - '*' +jobs: + build-android: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install npm dependencies + run: | + npm install + - name: Build App Newlogic Release + run: | + cd android && ./gradlew :app:assembleNewlogicRelease + - name: Upload Artifact + uses: actions/upload-artifact@v2 + with: + name: output + path: android/app/build/outputs/apk/newlogic/release/ + retention-days: 1 diff --git a/.gitignore b/.gitignore index 56cc6425..41a189cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,85 +1,80 @@ +node_modules/ +.expo/ +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ + +# @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8 +# The following patterns were generated by expo-cli + # Built application files *.apk -*.aar -*.ap_ *.aab +android/app/debug/output-metadata.json +android/app/release/output-metadata.json -# Files for the ART/Dalvik VM -*.dex +# OSX +# +.DS_Store -# Java class files -*.class - -# Generated files -bin/ -gen/ -out/ -# Uncomment the following line in case you need and you don't have the release build type files in your app -# release/ - -# Gradle files -.gradle/ +# Xcode +# build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace -# Local configuration file (sdk path, etc) +# Android/IntelliJ +# +build/ +.idea +.gradle local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ *.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml +*.hprof -# Keystore files -# Uncomment the following lines if you do not want to check your keystore files in. -#*.jks -#*.keystore +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log -# External native build folder generated in Android Studio 2.2 and later -.externalNativeBuild -.cxx/ +# BUCK +buck-out/ +\.buckd/ +*.keystore +!debug.keystore -# Google Services (e.g. APIs or Firebase) -# google-services.json +# Bundle artifacts +*.jsbundle -# Freeline -freeline.py -freeline/ -freeline_project_description.json +# CocoaPods +/ios/Pods/ -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md +# Expo +.expo/ +web-build/ +dist/ -# Version control -vcs.xml +# @end expo-cli -# lint -lint/intermediates/ -lint/generated/ -lint/outputs/ -lint/tmp/ -# lint/reports/ +.vscode/ +temp/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..89cb0e4e --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,13 @@ +{ + "arrowParens": "always", + "bracketSpacing": true, + "bracketSameLine": true, + "jsxSingleQuote": false, + "quoteProps": "consistent", + "printWidth": 80, + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "useTabs": false +} \ No newline at end of file diff --git a/App.tsx b/App.tsx new file mode 100644 index 00000000..2c1bdd4b --- /dev/null +++ b/App.tsx @@ -0,0 +1,24 @@ +import React, { useContext } from 'react'; +import AppLoading from 'expo-app-loading'; +import { AppLayout } from './screens/AppLayout'; +import { useFont } from './shared/hooks/useFont'; +import { GlobalContextProvider } from './components/GlobalContextProvider'; +import { GlobalContext } from './shared/GlobalContext'; +import { useSelector } from '@xstate/react'; +import { selectIsReady } from './machines/app'; + +const AppInitialization: React.FC = (props) => { + const { appService } = useContext(GlobalContext); + const hasFontsLoaded = useFont(); + const isReady = useSelector(appService, selectIsReady); + + return isReady && hasFontsLoaded ? : ; +}; + +export default function App() { + return ( + + + + ); +} diff --git a/README.md b/README.md index 4acb43da..d7291021 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,48 @@ # inji -This is a mobile id client. +This is a mobile id client. + +## Dependencies + +Be sure to have the following build tools installed before proceeding: + +- [Gradle](https://gradle.org/install/) +- [Java 8](https://www.oracle.com/ph/java/technologies/javase/javase8-archive-downloads.html) +- [Expo](https://docs.expo.dev/get-started/installation/) + +## Running the app + +```bash +# Install all dependencies +npm install +# run dev client +npm start +# run Mosip ID PASS directly to connected emulator or device (Default) +npm run android:newlogic +# run Mosip Philippines directly to connected emulator or device +npm run android:ph +``` + +# Building from Source + +## Build via Android Studio + +The app is available in this repository's `frontend/android` directory. Open this directory in Android Studio (version 4.1 and above) and the app can be built and run from there. + +More info here: [Build your app using Android Studio](https://developer.android.com/studio/run) + +## Build via command line + +1. Build for Mosip Philipines +```bash +npm run build:android:ph +``` + +2. Build for ID PASS + +```bash +npm run build:android:newlogic +``` + +Note for release builds you will need to have a keystore: [Create a Keystore](https://medium.com/@tom.truyen/create-an-android-keystore-using-keytool-commandline-10399a62e774) + +More info here: [Build your app from the command line](https://developer.android.com/studio/build/building-cmdline) diff --git a/android/.project b/android/.project new file mode 100644 index 00000000..03a28c13 --- /dev/null +++ b/android/.project @@ -0,0 +1,28 @@ + + + MOSIP Resident App + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + + + 1637742618855 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..267336a2 --- /dev/null +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/OpenJDK/openjdk-11.0.12_7 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/android/app/BUCK b/android/app/BUCK new file mode 100644 index 00000000..b4ce6f6a --- /dev/null +++ b/android/app/BUCK @@ -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 = "io.mosip.residentapp", +) + +android_resource( + name = "res", + package = "io.mosip.residentapp", + res = "src/main/res", +) + +android_binary( + name = "app", + keystore = "//android/keystores:debug", + manifest = "src/main/AndroidManifest.xml", + package_type = "debug", + deps = [ + ":app-code", + ], +) diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 00000000..fecf19b7 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,287 @@ +plugins { + id 'com.gladed.androidgitversion' version '0.4.14' +} + +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. If none specified and + * // "index.android.js" exists, it will be used. Otherwise "index.js" is + * // default. Can be overridden with ENTRY_FILE environment variable. + * entryFile: "index.android.js", + * + * // https://reactnative.dev/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 = [ + enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes", + bundleInDebug: true, + bundleInRelease: true, + devDisabledInRelease: true, + cliPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/cli.js", + hermesCommand: new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/%OS-BIN%/hermesc", + composeSourceMapsPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/compose-source-maps.js", +] + +apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../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); + +androidGitVersion { + baseCode 1 +} + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + + ext { + APP_NAME_RELEASE = "@string/app_name" + APP_NAME_PH = "@string/app_name_ph" + APP_NAME_NEWLOGIC = "@string/app_name_newlogic" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + applicationId 'io.mosip.residentapp' + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + // Update versionName and/or versionCode via git tag + // More info here: + // https://github.com/gladed/gradle-android-git-version#3-use-a-git-tag-to-specify-your-version-number-see-semantic-versioning + versionName androidGitVersion.name() + versionCode androidGitVersion.code() + manifestPlaceholders = [ + APP_NAME : APP_NAME_RELEASE + ] + } + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + } + } + signingConfigs { + release { + // TODO add proper release keystore via local.properties + storeFile file('debug.keystore') + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' + } + 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://reactnative.dev/docs/signed-apk-android. + signingConfig signingConfigs.debug + minifyEnabled enableProguardInReleaseBuilds + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } + } + + flavorDimensions "mosip" + + productFlavors { + ph { + versionName defaultConfig.versionName + "-ph" + buildConfigField "boolean", "ENABLE_LOG", "true" + manifestPlaceholders = [ + APP_NAME: APP_NAME_PH + ] + dimension "mosip" + } + newlogic { + buildConfigField "boolean", "ENABLE_LOG", "false" + versionName defaultConfig.versionName + "-newlogic" + manifestPlaceholders = [ + APP_NAME: APP_NAME_NEWLOGIC + ] + dimension "mosip" + } + } + + android.applicationVariants.all { variant -> + variant.outputs.all { + def datetime = new Date().format('yyyyMMdd_HHmm') + outputFileName = "${defaultConfig.applicationId}-${variant.versionName}_${datetime}.apk" + } + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + //noinspection GradleDynamicVersion + implementation "com.facebook.react:react-native:+" // From node_modules + + def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true"; + def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true"; + def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true"; + + // If your app supports Android versions before Ice Cream Sandwich (API level 14) + // All fresco packages should use the same version + if (isGifEnabled || isWebpEnabled) { + implementation 'com.facebook.fresco:fresco:2.0.0' + implementation 'com.facebook.fresco:imagepipeline-okhttp3:2.0.0' + } + + if (isGifEnabled) { + // For animated gif support + implementation 'com.facebook.fresco:animated-gif:2.0.0' + } + + if (isWebpEnabled) { + // For webp support + implementation 'com.facebook.fresco:webpsupport:2.0.0' + if (isWebpAnimatedEnabled) { + // Animated webp support + implementation 'com.facebook.fresco:animated-webp:2.0.0' + } + } + + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + 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' + } + + if (enableHermes) { + debugImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/hermes-debug.aar")) + releaseImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/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: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle"); +applyNativeModulesAppBuildGradle(project) +apply from: "./eas-build.gradle" diff --git a/android/app/build_defs.bzl b/android/app/build_defs.bzl new file mode 100644 index 00000000..fff270f8 --- /dev/null +++ b/android/app/build_defs.bzl @@ -0,0 +1,19 @@ +"""Helper definitions to glob .aar and .jar targets""" + +def create_aar_targets(aarfiles): + for aarfile in aarfiles: + name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] + lib_deps.append(":" + name) + android_prebuilt_aar( + name = name, + aar = aarfile, + ) + +def create_jar_targets(jarfiles): + for jarfile in jarfiles: + name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] + lib_deps.append(":" + name) + prebuilt_jar( + name = name, + binary_jar = jarfile, + ) diff --git a/android/app/debug.keystore b/android/app/debug.keystore new file mode 100644 index 00000000..364e105e Binary files /dev/null and b/android/app/debug.keystore differ diff --git a/android/app/eas-build.gradle b/android/app/eas-build.gradle new file mode 100644 index 00000000..0edd2df3 --- /dev/null +++ b/android/app/eas-build.gradle @@ -0,0 +1,74 @@ +// Build integration with EAS + +import java.nio.file.Paths + +android { + signingConfigs { + release { + // This is necessary to avoid needing the user to define a release signing config manually + // If no release config is defined, and this is not present, build for assembleRelease will crash + } + } + + buildTypes { + release { + // This is necessary to avoid needing the user to define a release build type manually + } + } +} + +def isEasBuildConfigured = false + +tasks.whenTaskAdded { + def debug = gradle.startParameter.taskNames.any { it.toLowerCase().contains('debug') } + + if (debug) { + return + } + + // We only need to configure EAS build once + if (isEasBuildConfigured) { + return + } + + isEasBuildConfigured = true; + + android.signingConfigs.release { + def credentialsJson = rootProject.file("../credentials.json"); + + if (credentialsJson.exists()) { + if (storeFile && !System.getenv("EAS_BUILD")) { + println("Path to release keystore file is already set, ignoring 'credentials.json'") + } else { + try { + def credentials = new groovy.json.JsonSlurper().parse(credentialsJson) + def keystorePath = Paths.get(credentials.android.keystore.keystorePath); + def storeFilePath = keystorePath.isAbsolute() + ? keystorePath + : rootProject.file("..").toPath().resolve(keystorePath); + + storeFile storeFilePath.toFile() + storePassword credentials.android.keystore.keystorePassword + keyAlias credentials.android.keystore.keyAlias + if (credentials.android.keystore.containsKey("keyPassword")) { + keyPassword credentials.android.keystore.keyPassword + } else { + // key password is required by Gradle, but PKCS keystores don't have one + // using the keystore password seems to satisfy the requirement + keyPassword credentials.android.keystore.keystorePassword + } + } catch (Exception e) { + println("An error occurred while parsing 'credentials.json': " + e.message) + } + } + } else { + if (storeFile == null) { + println("Couldn't find a 'credentials.json' file, skipping release keystore configuration") + } + } + } + + android.buildTypes.release { + signingConfig android.signingConfigs.release + } +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 00000000..11b02572 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,10 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..99e38fc5 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/android/app/src/debug/java/io/mosip/residentapp/ReactNativeFlipper.java b/android/app/src/debug/java/io/mosip/residentapp/ReactNativeFlipper.java new file mode 100644 index 00000000..ef368bd9 --- /dev/null +++ b/android/app/src/debug/java/io/mosip/residentapp/ReactNativeFlipper.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + */ +package io.mosip.residentapp; + +import android.content.Context; +import com.facebook.flipper.android.AndroidFlipperClient; +import com.facebook.flipper.android.utils.FlipperUtils; +import com.facebook.flipper.core.FlipperClient; +import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; +import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; +import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; +import com.facebook.flipper.plugins.inspector.DescriptorMapping; +import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; +import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; +import com.facebook.flipper.plugins.react.ReactFlipperPlugin; +import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.modules.network.NetworkingModule; +import okhttp3.OkHttpClient; + +public class ReactNativeFlipper { + public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { + if (FlipperUtils.shouldEnableFlipper(context)) { + final FlipperClient client = AndroidFlipperClient.getInstance(context); + client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); + client.addPlugin(new ReactFlipperPlugin()); + client.addPlugin(new DatabasesFlipperPlugin(context)); + client.addPlugin(new SharedPreferencesFlipperPlugin(context)); + client.addPlugin(CrashReporterPlugin.getInstance()); + NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); + NetworkingModule.setCustomClientBuilder( + new NetworkingModule.CustomClientBuilder() { + @Override + public void apply(OkHttpClient.Builder builder) { + builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); + } + }); + client.addPlugin(networkFlipperPlugin); + client.start(); + // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized + // Hence we run if after all native modules have been initialized + ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); + if (reactContext == null) { + reactInstanceManager.addReactInstanceEventListener( + new ReactInstanceManager.ReactInstanceEventListener() { + @Override + public void onReactContextInitialized(ReactContext reactContext) { + reactInstanceManager.removeReactInstanceEventListener(this); + reactContext.runOnNativeModulesQueueThread( + new Runnable() { + @Override + public void run() { + client.addPlugin(new FrescoFlipperPlugin()); + } + }); + } + }); + } else { + client.addPlugin(new FrescoFlipperPlugin()); + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..12c765d6 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/ic_launcher-playstore.png b/android/app/src/main/ic_launcher-playstore.png new file mode 100644 index 00000000..3e5bd6ef Binary files /dev/null and b/android/app/src/main/ic_launcher-playstore.png differ diff --git a/android/app/src/main/java/io/mosip/residentapp/MainActivity.java b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java new file mode 100644 index 00000000..ef1e17f8 --- /dev/null +++ b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java @@ -0,0 +1,127 @@ +package io.mosip.residentapp; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.core.content.ContextCompat; +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.ReactRootView; +import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; +import expo.modules.ReactActivityDelegateWrapper; + +/** + * IMPORTANT NOTE: The Android permission flow here works + * for Android 10 and below, and Android 11, + * and under continuous investigation if other manufacturers + * fails to work, etc. + */ +public class MainActivity extends ReactActivity { + + private static final String[] REQUIRED_PERMISSIONS = new String[] { + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, + Manifest.permission.ACCESS_WIFI_STATE, + Manifest.permission.CHANGE_WIFI_STATE, + Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + }; + + private static final int REQUEST_CODE_REQUIRED_PERMISSIONS = 1; + + @Override + protected void onCreate(Bundle savedInstanceState) { + // Set the theme to AppTheme BEFORE onCreate to support + // coloring the background, status bar, and navigation bar. + // This is required for expo-splash-screen. + setTheme(R.style.AppTheme); + super.onCreate(null); + } + + /** + * Returns the name of the main component registered from JavaScript. This is used to schedule + * rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "main"; + } + + @RequiresApi(api = Build.VERSION_CODES.M) + @Override + protected void onStart() { + super.onStart(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (!hasPermissions(this, REQUIRED_PERMISSIONS)) { + this.requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_REQUIRED_PERMISSIONS); + } + } + // TODO Commenting this only for now if permission is not working for other Android 11 manifacturer/devices + // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + // WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE ); + // if (wifi != null){ + // WifiManager.MulticastLock lock = wifi.createMulticastLock("IdpassSmartshareExample"); + // lock.acquire(); + // } + // } + // Must add this to onDestroy/onStop or disconnect to save battery + // lock.release(); + + } + + /** + * Returns true if the app was granted all the permissions. Otherwise, returns false. + */ + private static boolean hasPermissions(Context context, String... permissions) { + for (String permission : permissions) { + if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; + } + + /** + * Handles user acceptance (or denial) of our permission request. + */ + @CallSuper + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (requestCode != REQUEST_CODE_REQUIRED_PERMISSIONS) { + return; + } + + for (int grantResult : grantResults) { + if (grantResult == PackageManager.PERMISSION_DENIED) { + // Toast.makeText(this, R.string.error_missing_permissions, Toast.LENGTH_LONG).show(); + // connectButton.setEnabled(false); + Log.d("Main", "Denied"); + return; + } + } + recreate(); + } + + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegateWrapper( + this, + new ReactActivityDelegate(this, getMainComponentName()) { + @Override + protected ReactRootView createRootView() { + return new RNGestureHandlerEnabledRootView(MainActivity.this); + } + } + ); + } +} diff --git a/android/app/src/main/java/io/mosip/residentapp/MainActivity.java.bak b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java.bak new file mode 100644 index 00000000..329fdf4c --- /dev/null +++ b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java.bak @@ -0,0 +1,42 @@ +package io.mosip.residentapp; + +import android.os.Bundle; + +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.ReactRootView; +import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; + +import expo.modules.ReactActivityDelegateWrapper; + +public class MainActivity extends ReactActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + // Set the theme to AppTheme BEFORE onCreate to support + // coloring the background, status bar, and navigation bar. + // This is required for expo-splash-screen. + setTheme(R.style.AppTheme); + super.onCreate(null); + } + + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "main"; + } + + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegateWrapper( + this, + new ReactActivityDelegate(this, getMainComponentName()) { + @Override + protected ReactRootView createRootView() { + return new RNGestureHandlerEnabledRootView(MainActivity.this); + } + }); + } +} diff --git a/android/app/src/main/java/io/mosip/residentapp/MainApplication.java b/android/app/src/main/java/io/mosip/residentapp/MainApplication.java new file mode 100644 index 00000000..b31df684 --- /dev/null +++ b/android/app/src/main/java/io/mosip/residentapp/MainApplication.java @@ -0,0 +1,103 @@ +package io.mosip.residentapp; + +import android.app.Application; +import android.content.Context; +import android.content.res.Configuration; +import androidx.annotation.NonNull; + +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 expo.modules.ApplicationLifecycleDispatcher; +import expo.modules.ReactNativeHostWrapper; + +import com.facebook.react.bridge.JSIModulePackage; +import com.swmansion.reanimated.ReanimatedJSIModulePackage; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +public class MainApplication extends Application implements ReactApplication { + private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper( + this, + new ReactNativeHost(this) { + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + @SuppressWarnings("UnnecessaryLocalVariable") + List 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 + protected JSIModulePackage getJSIModulePackage() { + return new ReanimatedJSIModulePackage(); + } + }); + + @Override + public ReactNativeHost getReactNativeHost() { + return mReactNativeHost; + } + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + + initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + ApplicationLifecycleDispatcher.onApplicationCreate(this); + } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); + } + + /** + * 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.mosip.residentapp.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(); + } + } + } +} diff --git a/android/app/src/main/res/drawable-hdpi/splashscreen_image.png b/android/app/src/main/res/drawable-hdpi/splashscreen_image.png new file mode 100644 index 00000000..7855a1f2 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/splashscreen_image.png differ diff --git a/android/app/src/main/res/drawable-mdpi/splashscreen_image.png b/android/app/src/main/res/drawable-mdpi/splashscreen_image.png new file mode 100644 index 00000000..7855a1f2 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/splashscreen_image.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png b/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png new file mode 100644 index 00000000..7855a1f2 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png b/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png new file mode 100644 index 00000000..7855a1f2 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png b/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png new file mode 100644 index 00000000..7855a1f2 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png differ diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..ca3826a4 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/mosip_logo.png b/android/app/src/main/res/drawable/mosip_logo.png new file mode 100644 index 00000000..c761d380 Binary files /dev/null and b/android/app/src/main/res/drawable/mosip_logo.png differ diff --git a/android/app/src/main/res/drawable/splashscreen.xml b/android/app/src/main/res/drawable/splashscreen.xml new file mode 100644 index 00000000..70fc5faf --- /dev/null +++ b/android/app/src/main/res/drawable/splashscreen.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..00b86e2f --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..00b86e2f --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..bdb1022a Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..0baedc4b Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_mosip.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_mosip.png new file mode 100644 index 00000000..8fcc1dfc Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_mosip.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000..d699dce7 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..20ab661b Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..4ac95aa5 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_mosip.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_mosip.png new file mode 100644 index 00000000..d6694772 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_mosip.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000..f667950c Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..95cfd92b Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..4932bbad Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_mosip.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_mosip.png new file mode 100644 index 00000000..763e641b Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_mosip.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000..f17fb26b Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..2852d710 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..5435db13 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_mosip.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_mosip.png new file mode 100644 index 00000000..b6d6d55e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_mosip.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..dd3eca94 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..9f64b814 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..8e2fea97 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_mosip.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_mosip.png new file mode 100644 index 00000000..b98b0328 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_mosip.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..c85fb66f Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml new file mode 100644 index 00000000..9dc2f904 --- /dev/null +++ b/android/app/src/main/res/values-night/colors.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..85f04e2e --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,7 @@ + + + #ffffff + #FFFFFF + #023c69 + #ffffff + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..5cf74ccb --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + MOSIP Resident App + MOSIP Resident App - PH + MOSIP Resident App - Newlogic + contain + false + \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..bef78ada --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 00000000..295d5e17 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,42 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + ext { + buildToolsVersion = "29.0.3" + minSdkVersion = 21 + compileSdkVersion = 30 + targetSdkVersion = 30 + } + repositories { + google() + mavenCentral() + jcenter() + } + dependencies { + classpath("com.android.tools.build:gradle:4.1.0") + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + mavenLocal() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../android")) + } + maven { + // Android JSC is installed from npm + url(new File(["node", "--print", "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), "../dist")) + } + + google() + mavenCentral() + jcenter() + maven { url 'https://www.jitpack.io' } + } +} + +allprojects { repositories { maven { url "$rootDir/../node_modules/expo-camera/android/maven" } } } diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 00000000..8eac5b69 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,41 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true + +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true + +# Version of flipper SDK to use with React Native +FLIPPER_VERSION=0.54.0 + +# The hosted JavaScript engine +# Supported values: expo.jsEngine = "hermes" | "jsc" +expo.jsEngine=jsc + +# Enable GIF support in React Native images (~200 B increase) +expo.gif.enabled=true +# Enable webp support in React Native images (~85 KB increase) +expo.webp.enabled=true +# Enable animated webp support (~3.4 MB increase) +# Disabled by default because iOS doesn't support animated webp +expo.webp.animated=false \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..2c6137b8 Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..7665b0fa --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew new file mode 100755 index 00000000..2fe81a7d --- /dev/null +++ b/android/gradlew @@ -0,0 +1,183 @@ +#!/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 + ;; + 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" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 00000000..62bd9b9c --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,103 @@ +@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 init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +: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 diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 00000000..ee5198af --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,9 @@ +rootProject.name = 'MOSIP Resident App' + +apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle"); +useExpoModules() + +apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle"); +applyNativeModulesSettingsGradle(settings) + +include ':app' diff --git a/app.json b/app.json new file mode 100644 index 00000000..c0904373 --- /dev/null +++ b/app.json @@ -0,0 +1,36 @@ +{ + "expo": { + "name": "MOSIP Resident App", + "slug": "mosip-resident-app", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "updates": { + "fallbackToCacheTimeout": 0 + }, + "assetBundlePatterns": [ + "**/*" + ], + "ios": { + "bundleIdentifier": "io.mosip.residentapp", + "buildNumber": "1.0.0", + "supportsTablet": true + }, + "android": { + "package": "io.mosip.residentapp", + "versionCode": 1, + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#FFFFFF" + } + }, + "web": { + "favicon": "./assets/favicon.png" + } + } +} diff --git a/assets/adaptive-icon.png b/assets/adaptive-icon.png new file mode 100644 index 00000000..48c75eb7 Binary files /dev/null and b/assets/adaptive-icon.png differ diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 00000000..e75f697b Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 00000000..48c75eb7 Binary files /dev/null and b/assets/icon.png differ diff --git a/assets/idpass-logo.png b/assets/idpass-logo.png new file mode 100644 index 00000000..ba55dbad Binary files /dev/null and b/assets/idpass-logo.png differ diff --git a/assets/mosip-logo.png b/assets/mosip-logo.png new file mode 100644 index 00000000..48c75eb7 Binary files /dev/null and b/assets/mosip-logo.png differ diff --git a/assets/splash.png b/assets/splash.png new file mode 100644 index 00000000..48c75eb7 Binary files /dev/null and b/assets/splash.png differ diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..2900afe9 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/components/DeviceInfoList.tsx b/components/DeviceInfoList.tsx new file mode 100644 index 00000000..6754ebb6 --- /dev/null +++ b/components/DeviceInfoList.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { TextItem } from './ui/TextItem'; + +export const DeviceInfoList: React.FC = (props) => { + return ( + + + + + + ); +}; + +interface DeviceInfoProps { + of: 'sender' | 'receiver'; + deviceInfo: DeviceInfo; +} + +export interface DeviceInfo { + deviceName: string; + name: string; + deviceId: string; +} diff --git a/components/EditableListItem.tsx b/components/EditableListItem.tsx new file mode 100644 index 00000000..8960d5cd --- /dev/null +++ b/components/EditableListItem.tsx @@ -0,0 +1,55 @@ +import React, { useState } from 'react'; +import { Dimensions } from 'react-native'; +import { ListItem, Overlay, Input } from 'react-native-elements'; +import { Text, Column, Row, Button } from './ui'; +import { Colors } from './ui/styleUtils'; + +export const EditableListItem: React.FC = (props) => { + const [isEditing, setIsEditing] = useState(false); + const [newValue, setNewValue] = useState(props.value); + + return ( + setIsEditing(true)}> + + + {props.label} + + + {props.value} + + + Edit {props.label} + + +