diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..c589cc6 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,67 @@ +name: Publish +on: + push: + paths: + - 'cmp-mifos-passcode/**' + - 'sample/**' + workflow_dispatch: + inputs: + versionName: + description: 'Version Name' + required: true + +jobs: + publish: + name: Publish + runs-on: macos-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'adopt' + + - name: Grant Permission to Execute Gradle + run: chmod +x gradlew + + - name: Build with Gradle + uses: gradle/gradle-build-action@v2 + with: + arguments: build + + - name: Publish Library + run: | + echo "Publishing and Releasing library 🚀" + ./gradlew publish + echo "Published and Released ✅" + env: + ORG_GRADLE_PROJECT_VERSION_NAME: ${{ github.event.inputs.versionName }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEYPASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_MAVENCENTRALUSERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_MAVENCENTRALPASSWORD }} + + - name: Create and push tag + run: | + git config --global user.email "akash.meruva2003@gmail.com" + git config --global user.name "$GITHUB_ACTOR" + + git tag -a $TAG -m "Release v$TAG" + git push origin $TAG + env: + TAG: ${{ github.event.inputs.versionName }} + + - name: Create Release on GitHub + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.event.inputs.versionName }} + release_name: ${{ github.event.inputs.versionName }} + draft: true + prerelease: false \ No newline at end of file diff --git a/.gitignore b/.gitignore index a674bf8..853fd5b 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,6 @@ google-services.json # Freeline freeline.py freeline/ -freeline_project_description.json \ No newline at end of file +freeline_project_description.json + +.kotlin/ \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleMain.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleMain.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleTest.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-appleTest.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosMain.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosMain.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosTest.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-iosTest.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeMain.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeMain.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeTest.cinteropLibraries new file mode 100644 index 0000000..1692c73 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.cmp-mifos-passcode-nativeTest.cinteropLibraries @@ -0,0 +1,2 @@ +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +/Users/akash.meruva/StudioProjects/mifos-passcode/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleMain.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleMain.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleTest.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-appleTest.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosMain.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosMain.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosTest.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-iosTest.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeMain.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeMain.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeMain.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeTest.cinteropLibraries b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeTest.cinteropLibraries new file mode 100644 index 0000000..e8c3560 --- /dev/null +++ b/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.sample.shared-nativeTest.cinteropLibraries @@ -0,0 +1,2 @@ +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.compose.ui-ui-uikit-1.6.10-uikitMain-cinterop\org.jetbrains.compose.ui_ui-uikit-cinterop-utils-DC3XFw.klib +E:\Projects\projects\Android\mifos-passcode\.kotlin\metadata\kotlinTransformedCInteropMetadataLibraries\org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop\org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib \ No newline at end of file diff --git a/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.10-commonMain-2bbUHA.klib b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.10-commonMain-2bbUHA.klib new file mode 100644 index 0000000..ddbc0ec Binary files /dev/null and b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.10-commonMain-2bbUHA.klib differ diff --git a/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-annotationsCommonMain-24eTFQ.klib b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-annotationsCommonMain-24eTFQ.klib new file mode 100644 index 0000000..3f75368 Binary files /dev/null and b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-annotationsCommonMain-24eTFQ.klib differ diff --git a/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-assertionsCommonMain-24eTFQ.klib b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-assertionsCommonMain-24eTFQ.klib new file mode 100644 index 0000000..1226ae7 Binary files /dev/null and b/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.10-assertionsCommonMain-24eTFQ.klib differ diff --git a/androidApp/build.gradle b/androidApp/build.gradle index 13a8348..a19d401 100644 --- a/androidApp/build.gradle +++ b/androidApp/build.gradle @@ -46,7 +46,6 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation(project(":compose")) implementation project(':shared') implementation(libs.compose.ui) implementation(libs.compose.ui.tooling.preview) @@ -57,11 +56,13 @@ dependencies { androidTestImplementation libs.androidx.monitor androidTestImplementation libs.runner androidTestImplementation libs.junit + testImplementation libs.junit androidTestImplementation libs.runner androidTestImplementation libs.androidx.monitor debugImplementation(libs.compose.ui.tooling) implementation (libs.androidx.navigation.compose) implementation (libs.androidx.biometric) + implementation(libs.androidx.constraintlayout) } repositories { mavenCentral() diff --git a/androidApp/src/androidTest/java/com/mifos/passcode/ExampleInstrumentedTest.java b/androidApp/src/androidTest/java/com/mifos/passcode/ExampleInstrumentedTest.java index 52aef03..7496271 100644 --- a/androidApp/src/androidTest/java/com/mifos/passcode/ExampleInstrumentedTest.java +++ b/androidApp/src/androidTest/java/com/mifos/passcode/ExampleInstrumentedTest.java @@ -17,7 +17,7 @@ public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); assertEquals("com.mifos.passcode", appContext.getPackageName()); } diff --git a/cmp-mifos-passcode/build.gradle.kts b/cmp-mifos-passcode/build.gradle.kts new file mode 100644 index 0000000..da6a104 --- /dev/null +++ b/cmp-mifos-passcode/build.gradle.kts @@ -0,0 +1,76 @@ +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.kotlinCocoapods) + alias(libs.plugins.androidLibrary) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.compose.compiler) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "17" + } + } + } + iosX64() + iosArm64() + iosSimulatorArm64() + + cocoapods { + summary = "Some description for the Shared Module" + homepage = "Link to the Shared Module homepage" + version = "1.0" + ios.deploymentTarget = "16.0" + framework { + baseName = "shared" + isStatic = true + } + } + + sourceSets { + commonMain.dependencies { + implementation(libs.androidx.lifecycle.viewmodel.ktx) + implementation(compose.ui) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(compose.components.resources) + implementation(libs.navigation.compose) + implementation(libs.multiplatform.settings.no.arg) + } + commonTest.dependencies { + implementation(libs.kotlin.test) + } + androidMain.dependencies { + implementation (libs.androidx.biometric) + } + } + task("testClasses") +} + +android { + namespace = "com.mifos.cmp.mifos.passcode" + compileSdk = 35 + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].res.srcDirs("src/androidMain/res") + sourceSets["main"].resources.srcDirs("src/commonMain/resources") + defaultConfig { + minSdk = 24 + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} +dependencies { + implementation(libs.androidx.ui.tooling.preview.android) + implementation(libs.androidx.ui.android) +} + +compose.resources { + publicResClass = true + packageOfResClass = "com.mifos.cmp-mifos-passcode.resources" + generateResClass = always +} \ No newline at end of file diff --git a/cmp-mifos-passcode/cmp_mifos_passcode.podspec b/cmp-mifos-passcode/cmp_mifos_passcode.podspec new file mode 100644 index 0000000..a760d92 --- /dev/null +++ b/cmp-mifos-passcode/cmp_mifos_passcode.podspec @@ -0,0 +1,54 @@ +Pod::Spec.new do |spec| + spec.name = 'cmp_mifos_passcode' + spec.version = '1.0' + spec.homepage = 'Link to the Shared Module homepage' + spec.source = { :http=> ''} + spec.authors = '' + spec.license = '' + spec.summary = 'Some description for the Shared Module' + spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework' + spec.libraries = 'c++' + spec.ios.deployment_target = '16.0' + + + if !Dir.exist?('build/cocoapods/framework/shared.framework') || Dir.empty?('build/cocoapods/framework/shared.framework') + raise " + + Kotlin framework 'shared' doesn't exist yet, so a proper Xcode project can't be generated. + 'pod install' should be executed after running ':generateDummyFramework' Gradle task: + + ./gradlew :cmp-mifos-passcode:generateDummyFramework + + Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" + end + + spec.xcconfig = { + 'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO', + } + + spec.pod_target_xcconfig = { + 'KOTLIN_PROJECT_PATH' => ':cmp-mifos-passcode', + 'PRODUCT_MODULE_NAME' => 'shared', + } + + spec.script_phases = [ + { + :name => 'Build cmp_mifos_passcode', + :execution_position => :before_compile, + :shell_path => '/bin/sh', + :script => <<-SCRIPT + if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then + echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" + exit 0 + fi + set -ev + REPO_ROOT="$PODS_TARGET_SRCROOT" + "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ + -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ + -Pkotlin.native.cocoapods.archs="$ARCHS" \ + -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" + SCRIPT + } + ] + spec.resources = ['build/compose/cocoapods/compose-resources'] +end \ No newline at end of file diff --git a/compose/.gitignore b/compose/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/compose/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/compose/build.gradle b/compose/build.gradle deleted file mode 100644 index 541323d..0000000 --- a/compose/build.gradle +++ /dev/null @@ -1,72 +0,0 @@ -plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlinAndroid) - alias(libs.plugins.dagger.hilt) - alias(libs.plugins.devToolsKsp) - alias(libs.plugins.compose.compiler) -} - -android { - namespace 'com.mifos.compose' - compileSdk 35 - - defaultConfig { - minSdk 24 - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles "consumer-rules.pro" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - kotlinOptions { - jvmTarget = '17' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion = "1.5.2" - } - packagingOptions { - exclude 'META-INF/com.google.dagger_dagger.version' - } - -} - -dependencies { - - implementation libs.androidx.core.ktx.v1131 - implementation platform(libs.kotlin.bom) - implementation libs.androidx.appcompat - implementation libs.material - implementation project(':shared') - testImplementation libs.junit - androidTestImplementation libs.ext.junit - androidTestImplementation libs.androidx.espresso.core - implementation(libs.lifecycle.runtime.ktx) - implementation(libs.androidx.activity.compose) - implementation(platform(libs.compose.bom)) - implementation(libs.compose.ui) - implementation(libs.androidx.ui.graphics) - implementation(libs.compose.ui.tooling.preview) - implementation(libs.compose.material3) - implementation libs.androidx.material.icons.extended - implementation libs.androidx.lifecycle.runtime.compose - debugImplementation libs.compose.ui.tooling - debugImplementation libs.androidx.ui.test.manifest - - // Hilt Implementation - implementation libs.hilt.android - ksp(libs.hilt.compiler) - implementation(libs.androidx.hilt.navigation.compose.v120) - -} \ No newline at end of file diff --git a/compose/consumer-rules.pro b/compose/consumer-rules.pro deleted file mode 100644 index e69de29..0000000 diff --git a/compose/proguard-rules.pro b/compose/proguard-rules.pro deleted file mode 100644 index 481bb43..0000000 --- a/compose/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/compose/src/androidTest/java/com/mifos/compose/ExampleInstrumentedTest.kt b/compose/src/androidTest/java/com/mifos/compose/ExampleInstrumentedTest.kt deleted file mode 100644 index bdb5aa3..0000000 --- a/compose/src/androidTest/java/com/mifos/compose/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.mifos.compose - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.assignment.compose.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/compose/src/main/AndroidManifest.xml b/compose/src/main/AndroidManifest.xml deleted file mode 100644 index 2d915ee..0000000 --- a/compose/src/main/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/PasscodeRepository.kt b/compose/src/main/java/com/mifos/compose/PasscodeRepository.kt deleted file mode 100644 index cb37964..0000000 --- a/compose/src/main/java/com/mifos/compose/PasscodeRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mifos.compose - -interface PasscodeRepository { - fun getSavedPasscode(): String - val hasPasscode: Boolean - fun savePasscode(passcode: String) -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/PasscodeRepositoryImpl.kt b/compose/src/main/java/com/mifos/compose/PasscodeRepositoryImpl.kt deleted file mode 100644 index 8cdc658..0000000 --- a/compose/src/main/java/com/mifos/compose/PasscodeRepositoryImpl.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.mifos.compose - -import com.mifos.compose.utility.PreferenceManager -import javax.inject.Inject - -class PasscodeRepositoryImpl @Inject constructor(private val preferenceManager: PreferenceManager) : - PasscodeRepository { - - override fun getSavedPasscode(): String { - return preferenceManager.getSavedPasscode() - } - - override val hasPasscode: Boolean - get() = preferenceManager.hasPasscode - - override fun savePasscode(passcode: String) { - preferenceManager.savePasscode(passcode) - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/MifosIcon.kt b/compose/src/main/java/com/mifos/compose/component/MifosIcon.kt deleted file mode 100644 index 9ce09e0..0000000 --- a/compose/src/main/java/com/mifos/compose/component/MifosIcon.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import com.mifos.compose.R - -@Composable -fun MifosIcon(modifier: Modifier) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.Center - ) { - Image( - modifier = Modifier.size(180.dp), - painter = painterResource(id = R.drawable.mifos_logo), - contentDescription = null - ) - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PassCodeScreen.kt b/compose/src/main/java/com/mifos/compose/component/PassCodeScreen.kt deleted file mode 100644 index bec9600..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PassCodeScreen.kt +++ /dev/null @@ -1,215 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.Animatable -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Visibility -import androidx.compose.material.icons.filled.VisibilityOff -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.mifos.compose.PasscodeRepository -import com.mifos.compose.theme.blueTint -import com.mifos.compose.utility.Constants.PASSCODE_LENGTH -import com.mifos.compose.utility.PreferenceManager -import com.mifos.compose.utility.ShakeAnimation.performShakeAnimation -import com.mifos.compose.utility.VibrationFeedback.vibrateFeedback -import com.mifos.compose.viewmodels.PasscodeViewModel - -/** - * @author pratyush - * @since 15/3/24 - */ - -@Composable -fun PasscodeScreen( - viewModel: PasscodeViewModel = hiltViewModel(), - onForgotButton: () -> Unit, - onSkipButton: () -> Unit, - onPasscodeConfirm: (String) -> Unit, - onPasscodeRejected: () -> Unit, -) { - val context = LocalContext.current - val preferenceManager = remember { PreferenceManager(context) } - val activeStep by viewModel.activeStep.collectAsStateWithLifecycle() - val filledDots by viewModel.filledDots.collectAsStateWithLifecycle() - val passcodeVisible by viewModel.passcodeVisible.collectAsStateWithLifecycle() - val currentPasscode by viewModel.currentPasscodeInput.collectAsStateWithLifecycle() - val xShake = remember { Animatable(initialValue = 0.0F) } - var passcodeRejectedDialogVisible by remember { mutableStateOf(false) } - - LaunchedEffect(key1 = viewModel.onPasscodeConfirmed) { - viewModel.onPasscodeConfirmed.collect { - onPasscodeConfirm(it) - } - } - LaunchedEffect(key1 = viewModel.onPasscodeRejected) { - viewModel.onPasscodeRejected.collect { - passcodeRejectedDialogVisible = true - vibrateFeedback(context) - performShakeAnimation(xShake) - onPasscodeRejected() - } - } - - Column( - modifier = Modifier - .fillMaxSize() - .background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - PasscodeToolbar(activeStep = activeStep, preferenceManager.hasPasscode) - PasscodeSkipButton( - onSkipButton = { onSkipButton.invoke() }, - hasPassCode = preferenceManager.hasPasscode - ) - MifosIcon(modifier = Modifier.fillMaxWidth()) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 16.dp, bottom = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - PasscodeHeader( - activeStep = activeStep, - isPasscodeAlreadySet = preferenceManager.hasPasscode - ) - PasscodeView( - filledDots = filledDots, - currentPasscode = currentPasscode, - passcodeVisible = passcodeVisible, - togglePasscodeVisibility = { viewModel.togglePasscodeVisibility() }, - restart = { viewModel.restart() }, - passcodeRejectedDialogVisible = passcodeRejectedDialogVisible, - onDismissDialog = { passcodeRejectedDialogVisible = false }, - xShake = xShake - ) - } - Spacer(modifier = Modifier.height(6.dp)) - PasscodeKeys( - enterKey = { viewModel.enterKey(it) }, - deleteKey = { viewModel.deleteKey() }, - deleteAllKeys = { viewModel.deleteAllKeys() }, - modifier = Modifier.padding(horizontal = 12.dp) - ) - Spacer(modifier = Modifier.height(8.dp)) - PasscodeForgotButton( - onForgotButton = { onForgotButton.invoke() }, - hasPassCode = preferenceManager.hasPasscode - ) - } -} - -@Composable -private fun PasscodeView( - modifier: Modifier = Modifier, - restart: () -> Unit, - togglePasscodeVisibility: () -> Unit, - filledDots: Int, - passcodeVisible: Boolean, - currentPasscode: String, - passcodeRejectedDialogVisible: Boolean, - onDismissDialog: () -> Unit, - xShake: Animatable -) { - PasscodeMismatchedDialog( - visible = passcodeRejectedDialogVisible, - onDismiss = { - onDismissDialog.invoke() - restart() - } - ) - - Row( - modifier = modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically - ) { - Row( - modifier = modifier.offset(x = xShake.value.dp), - horizontalArrangement = Arrangement.spacedBy( - space = 26.dp, - alignment = Alignment.CenterHorizontally - ), - verticalAlignment = Alignment.CenterVertically - ) { - repeat(PASSCODE_LENGTH) { dotIndex -> - if (passcodeVisible && dotIndex < currentPasscode.length) { - Text( - text = currentPasscode[dotIndex].toString(), - color = blueTint - ) - } else { - val isFilledDot = dotIndex + 1 <= filledDots - val dotColor = animateColorAsState( - if (isFilledDot) blueTint else Color.Gray, label = "" - ) - - Box( - modifier = Modifier - .size(14.dp) - .background( - color = dotColor.value, - shape = CircleShape - ) - ) - } - } - } - IconButton( - onClick = { togglePasscodeVisibility.invoke() }, - modifier = Modifier.padding(start = 10.dp) - ) { - Icon( - imageVector = if (passcodeVisible) Icons.Filled.Visibility else Icons.Filled.VisibilityOff, - contentDescription = null - ) - } - } -} - -@Preview(showBackground = true) -@Composable -fun PasscodeScreenPreview() { - PasscodeScreen( - viewModel = PasscodeViewModel(object : PasscodeRepository { - override fun getSavedPasscode(): String { - return "" - } - - override val hasPasscode: Boolean - get() = false - - override fun savePasscode(passcode: String) {} - - }), - {}, {}, {}, {} - ) -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeButton.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeButton.kt deleted file mode 100644 index 168548c..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeButton.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import com.mifos.compose.R -import com.mifos.compose.theme.forgotButtonStyle -import com.mifos.compose.theme.skipButtonStyle - -@Composable -fun PasscodeSkipButton( - onSkipButton: () -> Unit, - hasPassCode: Boolean -) { - if (!hasPassCode) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(end = 16.dp), - horizontalArrangement = Arrangement.End - ) { - TextButton( - onClick = { onSkipButton.invoke() } - ) { - Text(text = stringResource(R.string.skip), style = skipButtonStyle) - } - } - } - -} - -@Composable -fun PasscodeForgotButton( - onForgotButton: () -> Unit, - hasPassCode: Boolean -) { - if (hasPassCode) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(end = 16.dp), - horizontalArrangement = Arrangement.Center - ) { - TextButton( - onClick = { onForgotButton.invoke() } - ) { - Text( - text = stringResource(R.string.forgot_passcode_login_manually), - style = forgotButtonStyle - ) - } - } - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeHeader.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeHeader.kt deleted file mode 100644 index 6aa8c5f..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeHeader.kt +++ /dev/null @@ -1,112 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.animation.core.Transition -import androidx.compose.animation.core.animateFloat -import androidx.compose.animation.core.animateOffset -import androidx.compose.animation.core.updateTransition -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.offset -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.scale -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.mifos.compose.R -import com.mifos.compose.utility.Step - -@Composable -fun PasscodeHeader( - modifier: Modifier = Modifier, - activeStep: Step, - isPasscodeAlreadySet: Boolean, -) { - val transitionState = remember { MutableTransitionState(activeStep) } - transitionState.targetState = activeStep - - val transition: Transition = updateTransition( - transitionState = transitionState, - label = "Headers Transition" - ) - - val offset = 200.0F - val zeroOffset = Offset(x = 0.0F, y = 0.0F) - val negativeOffset = Offset(x = -offset, y = 0.0F) - val positiveOffset = Offset(x = offset, y = 0.0F) - - val xTransitionHeader1 by transition.animateOffset(label = "Transition Offset Header 1") { - if (it == Step.Create) zeroOffset else negativeOffset - } - val xTransitionHeader2 by transition.animateOffset(label = "Transition Offset Header 2") { - if (it == Step.Confirm) zeroOffset else positiveOffset - } - val alphaHeader1 by transition.animateFloat(label = "Transition Alpha Header 1") { - if (it == Step.Create) 1.0F else 0.0F - } - val alphaHeader2 by transition.animateFloat(label = "Transition Alpha Header 2") { - if (it == Step.Confirm) 1.0F else 0.0F - } - val scaleHeader1 by transition.animateFloat(label = "Transition Alpha Header 1") { - if (it == Step.Create) 1.0F else 0.5F - } - val scaleHeader2 by transition.animateFloat(label = "Transition Alpha Header 2") { - if (it == Step.Confirm) 1.0F else 0.5F - } - - Box( - modifier = modifier.fillMaxWidth(), - contentAlignment = Alignment.Center - ) { - Box( - modifier = modifier.fillMaxWidth(), - contentAlignment = Alignment.Center - ) { - if (isPasscodeAlreadySet) { - Text( - modifier = Modifier - .offset(x = xTransitionHeader1.x.dp) - .alpha(alpha = alphaHeader1) - .scale(scale = scaleHeader1), - text = stringResource(id = R.string.enter_your_passcode), - style = TextStyle(fontSize = 20.sp) - ) - } else { - if (activeStep == Step.Create) { - Text( - modifier = Modifier - .offset(x = xTransitionHeader1.x.dp) - .alpha(alpha = alphaHeader1) - .scale(scale = scaleHeader1), - text = stringResource(id = R.string.create_passcode), - style = TextStyle(fontSize = 20.sp) - ) - } else if (activeStep == Step.Confirm) { - Text( - modifier = Modifier - .offset(x = xTransitionHeader2.x.dp) - .alpha(alpha = alphaHeader2) - .scale(scale = scaleHeader2), - text = stringResource(id = R.string.confirm_passcode), - style = TextStyle(fontSize = 20.sp) - ) - } - } - } - } -} - -@Preview -@Composable -fun PasscodeHeaderPreview() { - PasscodeHeader(activeStep = Step.Create, isPasscodeAlreadySet = true) -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeKeys.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeKeys.kt deleted file mode 100644 index 643872d..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeKeys.kt +++ /dev/null @@ -1,202 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Backspace -import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Icon -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.mifos.compose.R -import com.mifos.compose.theme.PasscodeKeyButtonStyle -import com.mifos.compose.theme.blueTint - -@Composable -fun PasscodeKeys( - enterKey: (String) -> Unit, - deleteKey: () -> Unit, - deleteAllKeys: () -> Unit, - modifier: Modifier = Modifier, -) { - val onEnterKeyClick = { keyTitle: String -> - enterKey(keyTitle) - } - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Row(modifier = Modifier.fillMaxWidth()) { - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "1", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "2", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "3", - onClick = onEnterKeyClick - ) - } - Row(modifier = Modifier.fillMaxWidth()) { - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "4", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "5", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "6", - onClick = onEnterKeyClick - ) - } - Row(modifier = Modifier.fillMaxWidth()) { - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "7", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "8", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "9", - onClick = onEnterKeyClick - ) - } - Row(modifier = Modifier.fillMaxWidth()) { - PasscodeKey(modifier = Modifier.weight(weight = 1.0F)) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyTitle = "0", - onClick = onEnterKeyClick - ) - PasscodeKey( - modifier = Modifier.weight(weight = 1.0F), - keyIcon = ImageVector.vectorResource(id = R.drawable.ic_delete), - keyIconContentDescription = "Delete Passcode Key Button", - onClick = { - deleteKey() - }, - onLongClick = { - deleteAllKeys() - } - ) - } - } -} - -@Composable -fun PasscodeKey( - modifier: Modifier = Modifier, - keyTitle: String = "", - keyIcon: ImageVector? = null, - keyIconContentDescription: String = "", - onClick: ((String) -> Unit)? = null, - onLongClick: (() -> Unit)? = null -) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.Center - ) { - CombinedClickableIconButton( - modifier = Modifier - .padding(all = 4.dp), - onClick = { - onClick?.invoke(keyTitle) - }, - onLongClick = { - onLongClick?.invoke() - } - ) { - if (keyIcon == null) { - Text( - text = keyTitle, - style = PasscodeKeyButtonStyle.copy(color = blueTint) - ) - } else { - Icon( - imageVector = Icons.Default.Backspace, - contentDescription = keyIconContentDescription, - tint = blueTint - ) - } - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun CombinedClickableIconButton( - onClick: () -> Unit, - onLongClick: () -> Unit, - modifier: Modifier = Modifier, - size: Dp = 48.dp, - rippleRadius: Dp = 36.dp, - enabled: Boolean = true, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - content: @Composable () -> Unit -) { - Column( - modifier = modifier - .size(size = size) - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick, - enabled = enabled, - role = Role.Button, - interactionSource = interactionSource, - indication = rememberRipple( - bounded = false, - radius = rippleRadius, - color = Color.Cyan - ) - ), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - val contentAlpha = - if (enabled) LocalContentColor.current else LocalContentColor.current.copy(alpha = 0f) - CompositionLocalProvider(LocalContentColor provides contentAlpha, content = content) - } -} - - -@Preview -@Composable -fun PasscodeKeysPreview() { - PasscodeKeys({}, {}, {}) -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeMismatchedDialog.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeMismatchedDialog.kt deleted file mode 100644 index 8856afa..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeMismatchedDialog.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import com.mifos.compose.R - -@Composable -fun PasscodeMismatchedDialog( - visible: Boolean, - onDismiss: () -> Unit -) { - if (visible) { - AlertDialog( - shape = MaterialTheme.shapes.large, - containerColor = Color.White, - title = { - Text( - text = stringResource(R.string.passcode_do_not_match), - color = Color.Black - ) - }, - confirmButton = { - TextButton(onClick = onDismiss) { - Text(text = stringResource(R.string.try_again), color = Color.Black) - } - }, - onDismissRequest = onDismiss - ) - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeStepIndicator.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeStepIndicator.kt deleted file mode 100644 index 0acd1fa..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeStepIndicator.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import com.mifos.compose.theme.blueTint -import com.mifos.compose.utility.Constants.STEPS_COUNT -import com.mifos.compose.utility.Step - -@Composable -fun PasscodeStepIndicator( - modifier: Modifier = Modifier, - activeStep: Step -) { - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy( - space = 6.dp, - alignment = Alignment.CenterHorizontally - ) - ) { - repeat(STEPS_COUNT) { step -> - val isActiveStep = step <= activeStep.index - val stepColor = - animateColorAsState(if (isActiveStep) blueTint else Color.Gray, label = "") - - Box( - modifier = Modifier - .size( - width = 72.dp, - height = 4.dp - ) - .background( - color = stepColor.value, - shape = MaterialTheme.shapes.medium - ) - ) - } - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/component/PasscodeToolbar.kt b/compose/src/main/java/com/mifos/compose/component/PasscodeToolbar.kt deleted file mode 100644 index 6fbe028..0000000 --- a/compose/src/main/java/com/mifos/compose/component/PasscodeToolbar.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.mifos.compose.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import com.mifos.compose.R -import com.mifos.compose.utility.Step - -@Composable -fun PasscodeToolbar(activeStep: Step, hasPasscode: Boolean) { - var exitWarningDialogVisible by remember { mutableStateOf(false) } - ExitWarningDialog( - visible = exitWarningDialogVisible, - onConfirm = {}, - onDismiss = { - exitWarningDialogVisible = false - } - ) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - horizontalArrangement = Arrangement.Center - ) { - if (!hasPasscode) { - PasscodeStepIndicator( - activeStep = activeStep - ) - } - } -} - -@Composable -fun ExitWarningDialog( - visible: Boolean, - onConfirm: () -> Unit, - onDismiss: () -> Unit -) { - if (visible) { - AlertDialog( - shape = MaterialTheme.shapes.large, - containerColor = Color.White, - title = { - Text( - text = stringResource(R.string.are_you_sure_you_want_to_exit), - color = Color.Black - ) - }, - confirmButton = { - TextButton(onClick = onConfirm) { - Text(text = stringResource(R.string.exit)) - } - }, - dismissButton = { - TextButton(onClick = onDismiss) { - Text(text = stringResource(R.string.cancel)) - } - }, - onDismissRequest = onDismiss - ) - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/di/ApplicationModule.kt b/compose/src/main/java/com/mifos/compose/di/ApplicationModule.kt deleted file mode 100644 index ade0d90..0000000 --- a/compose/src/main/java/com/mifos/compose/di/ApplicationModule.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.mifos.compose.di - -import android.content.Context -import com.mifos.compose.PasscodeRepository -import com.mifos.compose.PasscodeRepositoryImpl -import com.mifos.compose.utility.PreferenceManager -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -/** - * @author pratyush - * @since 15/3/24 - */ - -@Module -@InstallIn(SingletonComponent::class) -object ApplicationModule { - @Provides - @Singleton - fun providePrefManager(@ApplicationContext context: Context): PreferenceManager { - return PreferenceManager(context) - } - - @Provides - @Singleton - fun providesPasscodeRepository(preferenceManager: PreferenceManager): PasscodeRepository { - return PasscodeRepositoryImpl(preferenceManager) - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/theme/Color.kt b/compose/src/main/java/com/mifos/compose/theme/Color.kt deleted file mode 100644 index 0bfac2f..0000000 --- a/compose/src/main/java/com/mifos/compose/theme/Color.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.mifos.compose.theme - -import androidx.compose.ui.graphics.Color - -val blueTint = Color(0xFF03A9F4) \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/theme/Font.kt b/compose/src/main/java/com/mifos/compose/theme/Font.kt deleted file mode 100644 index 4371ddb..0000000 --- a/compose/src/main/java/com/mifos/compose/theme/Font.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.mifos.compose.theme - -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import com.mifos.compose.R - -val LatoFonts = FontFamily( - Font( - resId = R.font.lato_regular, - weight = FontWeight.Normal, - style = FontStyle.Normal - ), - Font( - resId = R.font.lato_bold, - weight = FontWeight.Bold, - style = FontStyle.Normal - ), - Font( - resId = R.font.lato_black, - weight = FontWeight.Black, - style = FontStyle.Normal - ) -) \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/theme/Theme.kt b/compose/src/main/java/com/mifos/compose/theme/Theme.kt deleted file mode 100644 index a05a3d1..0000000 --- a/compose/src/main/java/com/mifos/compose/theme/Theme.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.mifos.compose.theme - -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Color.Companion.Blue - -private val DarkColorPalette = darkColorScheme( - primary = Color.Cyan, - onPrimary = Color.Cyan, - secondary = Color.Black.copy(alpha = 0.2f), - background = Color.Black -) -private val LightColorPalette = lightColorScheme( - primary = Blue, - onPrimary = Blue, - secondary = Color.Blue.copy(alpha = 0.4f), - background = Color.White -) - -@Composable -fun MifosPasscodeTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - content: @Composable () -> Unit -) { - val colors = if (darkTheme) { - DarkColorPalette - } else { - LightColorPalette - } - - MaterialTheme( - colorScheme = colors, - typography = Typography, - content = content - ) -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/theme/Type.kt b/compose/src/main/java/com/mifos/compose/theme/Type.kt deleted file mode 100644 index b8801d0..0000000 --- a/compose/src/main/java/com/mifos/compose/theme/Type.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.mifos.compose.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -val Typography = Typography( - displayLarge = TextStyle( - fontFamily = LatoFonts, - fontWeight = FontWeight.Black, - fontSize = 34.sp - ) -) - -val PasscodeKeyButtonStyle = TextStyle( - fontFamily = LatoFonts, - fontWeight = FontWeight.Bold, - fontSize = 24.sp -) - -val skipButtonStyle = TextStyle( - color = blueTint, - fontSize = 20.sp, - fontFamily = LatoFonts -) - -val forgotButtonStyle = TextStyle( - color = blueTint, - fontSize = 14.sp, - fontFamily = LatoFonts -) \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/utility/Constants.kt b/compose/src/main/java/com/mifos/compose/utility/Constants.kt deleted file mode 100644 index 2743ad5..0000000 --- a/compose/src/main/java/com/mifos/compose/utility/Constants.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mifos.compose.utility - -object Constants { - const val STEPS_COUNT = 2 - const val PASSCODE_LENGTH = 4 - const val VIBRATE_FEEDBACK_DURATION = 300L -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/utility/PreferenceManager.kt b/compose/src/main/java/com/mifos/compose/utility/PreferenceManager.kt deleted file mode 100644 index f56cf3a..0000000 --- a/compose/src/main/java/com/mifos/compose/utility/PreferenceManager.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.mifos.compose.utility - -import android.content.Context -import androidx.compose.runtime.mutableStateOf -import com.mifos.compose.R - -/** - * @author pratyush - * @since 15/3/24 - */ - -class PreferenceManager(context: Context) { - private val sharedPreference = context.getSharedPreferences( - R.string.pref_name.toString(), - Context.MODE_PRIVATE - ) - - var hasPasscode: Boolean - get() = sharedPreference.getBoolean(R.string.has_passcode.toString(), false) - set(value) = sharedPreference.edit().putBoolean(R.string.has_passcode.toString(), value) - .apply() - - fun savePasscode(passcode: String) { - sharedPreference.edit().putString(R.string.passcode.toString(), passcode).apply() - hasPasscode = true - } - - fun getSavedPasscode(): String { - return sharedPreference.getString(R.string.passcode.toString(), "").toString() - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/utility/ShakeAnimation.kt b/compose/src/main/java/com/mifos/compose/utility/ShakeAnimation.kt deleted file mode 100644 index 6ed3282..0000000 --- a/compose/src/main/java/com/mifos/compose/utility/ShakeAnimation.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.mifos.compose.utility - -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.LinearOutSlowInEasing -import androidx.compose.animation.core.keyframes -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - -object ShakeAnimation { - - fun CoroutineScope.performShakeAnimation(xShake: Animatable) { - launch { - xShake.animateTo( - targetValue = 0f, // This resets the position after the shake - animationSpec = keyframes { - durationMillis = 280 // Total animation duration - 0f at 0 with LinearOutSlowInEasing // Start position - 20f at 80 with LinearOutSlowInEasing // Move right - -20f at 120 with LinearOutSlowInEasing // Move left - 10f at 160 with LinearOutSlowInEasing // Move right - -10f at 200 with LinearOutSlowInEasing // Move left - 5f at 240 with LinearOutSlowInEasing // Move right - 0f at 280 // End at the original position - } - ) - } - } - -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/utility/Step.kt b/compose/src/main/java/com/mifos/compose/utility/Step.kt deleted file mode 100644 index c58f82c..0000000 --- a/compose/src/main/java/com/mifos/compose/utility/Step.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mifos.compose.utility - -enum class Step(var index: Int) { - Create(0), - Confirm(1) -} diff --git a/compose/src/main/java/com/mifos/compose/utility/VibrationFeedback.kt b/compose/src/main/java/com/mifos/compose/utility/VibrationFeedback.kt deleted file mode 100644 index c5ceaa1..0000000 --- a/compose/src/main/java/com/mifos/compose/utility/VibrationFeedback.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.mifos.compose.utility - -import android.content.Context -import android.os.Build -import android.os.CombinedVibration -import android.os.VibrationEffect -import android.os.Vibrator -import android.os.VibratorManager -import com.mifos.compose.utility.Constants.VIBRATE_FEEDBACK_DURATION - -/** - * @author pratyush - * @since 15/3/24 - */ - -object VibrationFeedback { - - @Suppress("DEPRECATION") - fun vibrateFeedback(context: Context) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - (context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).vibrate( - CombinedVibration.createParallel( - VibrationEffect.createOneShot( - VIBRATE_FEEDBACK_DURATION, - VibrationEffect.DEFAULT_AMPLITUDE - ) - ) - ) - } else { - (context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator).let { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - it.vibrate( - VibrationEffect.createOneShot( - VIBRATE_FEEDBACK_DURATION, - VibrationEffect.DEFAULT_AMPLITUDE - ) - ) - } else { - it.vibrate(VIBRATE_FEEDBACK_DURATION) - } - } - } - } -} \ No newline at end of file diff --git a/compose/src/main/java/com/mifos/compose/viewmodels/PasscodeViewModel.kt b/compose/src/main/java/com/mifos/compose/viewmodels/PasscodeViewModel.kt deleted file mode 100644 index 7fa9410..0000000 --- a/compose/src/main/java/com/mifos/compose/viewmodels/PasscodeViewModel.kt +++ /dev/null @@ -1,147 +0,0 @@ -package com.mifos.compose.viewmodels - -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mifos.compose.PasscodeRepository -import com.mifos.compose.utility.Constants.PASSCODE_LENGTH -import com.mifos.compose.utility.Step -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - -/** - * @author pratyush - * @since 15/3/24 - */ - -@HiltViewModel -class PasscodeViewModel @Inject constructor(private val passcodeRepository: PasscodeRepository) : - ViewModel() { - - private val _onPasscodeConfirmed = MutableSharedFlow() - private val _onPasscodeRejected = MutableSharedFlow() - - private val _activeStep = MutableStateFlow(Step.Create) - private val _filledDots = MutableStateFlow(0) - - private var createPasscode: StringBuilder = StringBuilder() - private var confirmPasscode: StringBuilder = StringBuilder() - - val onPasscodeConfirmed = _onPasscodeConfirmed.asSharedFlow() - val onPasscodeRejected = _onPasscodeRejected.asSharedFlow() - - val activeStep = _activeStep.asStateFlow() - val filledDots = _filledDots.asStateFlow() - - private val _passcodeVisible = MutableStateFlow(false) - val passcodeVisible = _passcodeVisible.asStateFlow() - - private val _currentPasscodeInput = MutableStateFlow("") - val currentPasscodeInput = _currentPasscodeInput.asStateFlow() - - private var _isPasscodeAlreadySet = mutableStateOf(passcodeRepository.hasPasscode) - - init { - resetData() - } - - private fun emitActiveStep(activeStep: Step) = viewModelScope.launch { - _activeStep.emit(activeStep) - } - - private fun emitFilledDots(filledDots: Int) = viewModelScope.launch { - _filledDots.emit(filledDots) - } - - private fun emitOnPasscodeConfirmed(confirmPassword: String) = viewModelScope.launch { - _onPasscodeConfirmed.emit(confirmPassword) - } - - private fun emitOnPasscodeRejected() = viewModelScope.launch { - _onPasscodeRejected.emit(Unit) - } - - fun togglePasscodeVisibility() { - _passcodeVisible.value = !_passcodeVisible.value - } - - private fun resetData() { - emitActiveStep(Step.Create) - emitFilledDots(0) - - createPasscode.clear() - confirmPasscode.clear() - } - - fun enterKey(key: String) { - if (_filledDots.value >= PASSCODE_LENGTH) { - return - } - - val currentPasscode = - if (_activeStep.value == Step.Create) createPasscode else confirmPasscode - currentPasscode.append(key) - _currentPasscodeInput.value = currentPasscode.toString() - emitFilledDots(currentPasscode.length) - - if (_filledDots.value == PASSCODE_LENGTH) { - if (_isPasscodeAlreadySet.value) { - if (passcodeRepository.getSavedPasscode() == createPasscode.toString()) { - emitOnPasscodeConfirmed(createPasscode.toString()) - createPasscode.clear() - } else { - emitOnPasscodeRejected() - // logic for retires can be written here - } - _currentPasscodeInput.value = "" - } else if (_activeStep.value == Step.Create) { - emitActiveStep(Step.Confirm) - emitFilledDots(0) - _currentPasscodeInput.value = "" - } else { - if (createPasscode.toString() == confirmPasscode.toString()) { - emitOnPasscodeConfirmed(confirmPasscode.toString()) - passcodeRepository.savePasscode(confirmPasscode.toString()) - _isPasscodeAlreadySet.value = true - resetData() - } else { - emitOnPasscodeRejected() - resetData() - } - _currentPasscodeInput.value = "" - } - } - } - - fun deleteKey() { - val currentPasscode = - if (_activeStep.value == Step.Create) createPasscode else confirmPasscode - - if (currentPasscode.isNotEmpty()) { - currentPasscode.deleteAt(currentPasscode.length - 1) - _currentPasscodeInput.value = currentPasscode.toString() - emitFilledDots(currentPasscode.length) - } - } - - - fun deleteAllKeys() { - if (_activeStep.value == Step.Create) { - createPasscode.clear() - } else { - confirmPasscode.clear() - } - _currentPasscodeInput.value = "" - emitFilledDots(0) - } - - fun restart() { - resetData() - _passcodeVisible.value = false - } -} \ No newline at end of file diff --git a/compose/src/main/res/drawable/baseline_delete_forever_24.xml b/compose/src/main/res/drawable/baseline_delete_forever_24.xml deleted file mode 100644 index a0c03a9..0000000 --- a/compose/src/main/res/drawable/baseline_delete_forever_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/compose/src/main/res/drawable/ic_delete.xml b/compose/src/main/res/drawable/ic_delete.xml deleted file mode 100644 index 62ae9c4..0000000 --- a/compose/src/main/res/drawable/ic_delete.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - diff --git a/compose/src/main/res/drawable/mifos_logo.jpg b/compose/src/main/res/drawable/mifos_logo.jpg deleted file mode 100644 index a067a3c..0000000 Binary files a/compose/src/main/res/drawable/mifos_logo.jpg and /dev/null differ diff --git a/compose/src/main/res/font/lato_black.ttf b/compose/src/main/res/font/lato_black.ttf deleted file mode 100644 index 4340502..0000000 Binary files a/compose/src/main/res/font/lato_black.ttf and /dev/null differ diff --git a/compose/src/main/res/font/lato_bold.ttf b/compose/src/main/res/font/lato_bold.ttf deleted file mode 100644 index 016068b..0000000 Binary files a/compose/src/main/res/font/lato_bold.ttf and /dev/null differ diff --git a/compose/src/main/res/font/lato_regular.ttf b/compose/src/main/res/font/lato_regular.ttf deleted file mode 100644 index bb2e887..0000000 Binary files a/compose/src/main/res/font/lato_regular.ttf and /dev/null differ diff --git a/compose/src/main/res/values/strings.xml b/compose/src/main/res/values/strings.xml deleted file mode 100644 index 647e23a..0000000 --- a/compose/src/main/res/values/strings.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - Passcode - hasPasscode - hasDragPasscode - passcode - drag_passcode - - Create Passcode - Confirm Passcode - Enter your Passcode - Forgot Passcode - Delete Passcode Key Button - Drag your finger here only in one direction. - Drag your Pattern - Exit - Cancel - Skip - Forgot Passcode, Login Manually - Try again - Passcode do not match! - Are you sure you want to exit? - - \ No newline at end of file diff --git a/compose/src/test/java/com/mifos/compose/ExampleUnitTest.kt b/compose/src/test/java/com/mifos/compose/ExampleUnitTest.kt deleted file mode 100644 index 0400f64..0000000 --- a/compose/src/test/java/com/mifos/compose/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.mifos.compose - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 65d4004..71666ea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,14 @@ [versions] +activityComposeVersion = "1.8.2" agp = "8.3.0" androidMavenGradlePlugin = "2.1" +androidxNavigationCompose = "2.7.6" +cmpPreference = "1.0.0" +constraintlayout = "2.1.4" coreKtxVersion = "1.13.1" espressoCoreVersion = "3.6.0-alpha01" gradle = "8.3.1" +gradleBintrayPlugin = "1.7.3" hiltCompiler = "2.48.1" hiltNavigationComposeVersion = "1.2.0" kotlin = "2.0.0" @@ -11,20 +16,32 @@ compose = "1.5.4" compose-material3 = "1.1.2" androidx-activityCompose = "1.8.0" kotlinStdlibJdk8 = "1.7.20" +kotlinBom = "1.9.0" +kvault = "1.12.0" lifecycleViewmodelKtx = "2.8.1" compose-plugin = "1.6.10" multiplatformSettings = "1.0.0" navigationCompose = "2.7.7" navigationComposeVersion = "2.7.0-alpha07" dagger-hilt = "2.48.1" +fragmentKtx = "1.8.2" biometricKtx = "1.1.0" devToolsKsp = "2.0.10-1.0.24" +coreKtx = "1.12.0" +appcompat = "1.4.1" material = "1.6.0" junit = "4.13.2" extJunit = "1.1.5" +espressoCore = "3.5.1" lifecycleRuntimeKtx = "2.7.0" +activityCompose = "1.8.2" composeBom = "2023.03.00" +composeUi = "1.6.8" +material3 = "1.6.8" hiltAndroid = "2.48.1" +hiltNavigationCompose = "1.0.0" +runner = "1.6.0-alpha04" +sonner = "0.3.8" uiToolingPreviewAndroid = "1.6.8" uiAndroid = "1.6.8" appcompatVersion = "1.7.0" @@ -36,32 +53,52 @@ runnerVersion = "1.5.2" android-maven-gradle-plugin = { module = "com.github.dcendents:android-maven-gradle-plugin", version.ref = "androidMavenGradlePlugin" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } androidx-biometric = { module = "androidx.biometric:biometric", version.ref = "biometricKtx" } +androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } androidx-core-ktx-v1131 = { module = "androidx.core:core-ktx", version.ref = "coreKtxVersion" } androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCoreVersion" } androidx-hilt-navigation-compose-v120 = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationComposeVersion" } androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose" } androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" } +androidx-material3 = { module = "androidx.compose.material3:material3" } compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" } compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } androidx-ui-graphics = { module = "androidx.compose.ui:ui-graphics" } androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" } +androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } +androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } +cmp-preference = { module = "network.chaintech:cmp-preference", version.ref = "cmpPreference" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" } +gradle-bintray-plugin = { module = "com.jfrog.bintray.gradle:gradle-bintray-plugin", version.ref = "gradleBintrayPlugin" } hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hiltCompiler" } +kotlin-bom-v180 = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlinBom" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "lifecycleViewmodelKtx" } +kvault = { module = "com.liftric:kvault", version.ref = "kvault" } multiplatform-settings-no-arg = { module = "com.russhwolf:multiplatform-settings-no-arg", version.ref = "multiplatformSettings" } kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompatVersion" } navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigationComposeVersion" } +androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" } +androidx-biometric-ktx = { group = "androidx.biometric", name = "biometric-ktx", version.ref = "biometricKtx" } +core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } junit = { group = "junit", name = "junit", version.ref = "junit" } ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "extJunit" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "composeUi" } +material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "material3" } +lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleRuntimeKtx" } +sonner = { module = "io.github.dokar3:sonner", version.ref = "sonner" } +ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "composeUi" } hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hiltAndroid" } +hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } androidx-ui-tooling-preview-android = { group = "androidx.compose.ui", name = "ui-tooling-preview-android", version.ref = "uiToolingPreviewAndroid" } androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android", version.ref = "uiAndroid" } testng = { group = "org.testng", name = "testng", version.ref = "testng" } diff --git a/graphic/demo.png b/graphic/demo.png deleted file mode 100644 index af7c9ba..0000000 Binary files a/graphic/demo.png and /dev/null differ diff --git a/mifos-passcode/.gitignore b/mifos-passcode/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/mifos-passcode/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/mifos-passcode/build.gradle b/mifos-passcode/build.gradle deleted file mode 100644 index 2fc17de..0000000 --- a/mifos-passcode/build.gradle +++ /dev/null @@ -1,90 +0,0 @@ -plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlinAndroid) -} - -ext { - bintrayRepo = 'maven' - bintrayName = 'mifos-passcode' - - publishedGroupId = 'com.mifos.mobile' - libraryName = 'mifos-passcode' - artifact = 'mifos-passcode' // artifact name and library name should be same. - - libraryDescription = 'A Library as feature of passcode' - - siteUrl = 'https://github.com/openMF/mobile-passcode' - gitUrl = 'https://github.com/openMF/mobile-passcode.git' - - libraryVersion = '1.0.0' - - developerId = 'mifos' - developerName = 'Mifos Initiative' - developerEmail = 'info@mifos.org' - - licenseName = 'The Apache Software License, Version 2.0' - licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - allLicenses = ["Apache-2.0"] -} - -android { - compileSdk 34 - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - defaultConfig { - namespace "com.mifos.mobile.passcode" - minSdk 24 - targetSdk 34 - versionCode 2 - versionName "1.0.0" - vectorDrawables.useSupportLibrary = true - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - buildFeatures { - viewBinding = true - } - kotlinOptions { - jvmTarget = '17' - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - - implementation libs.androidx.appcompat - implementation libs.material - - testImplementation libs.junit - androidTestImplementation libs.runner - androidTestImplementation libs.androidx.espresso.core - implementation libs.androidx.core.ktx.v1131 - implementation platform(libs.kotlin.bom) -} - -tasks.withType(Javadoc) { - excludes = ['**/*.kt'] - options.addStringOption('Xdoclint:none', '-quiet') - options.addStringOption('encoding', 'UTF-8') - options.addStringOption('charSet', 'UTF-8') -} - -repositories { - mavenCentral() -} -// Used this article to release the library -// https://inthecheesefactory.com/blog/how-to-upload-library-to-jcenter-maven-central-as-dependency/en - -// Add these line in local.properties to direct release on bintray -//bintray.user=YOUR_BINTRAY_USERNAME -//bintray.apikey=YOUR_BINTRAY_API_KEY -//bintray.gpg.password=YOUR_GPG_PASSWORD \ No newline at end of file diff --git a/mifos-passcode/proguard-rules.pro b/mifos-passcode/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/mifos-passcode/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/mifos-passcode/src/main/AndroidManifest.xml b/mifos-passcode/src/main/AndroidManifest.xml deleted file mode 100644 index 7f0c06c..0000000 --- a/mifos-passcode/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/BasePassCodeActivity.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/BasePassCodeActivity.kt deleted file mode 100644 index f42d852..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/BasePassCodeActivity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.mifos.mobile.passcode - -import androidx.activity.ComponentActivity -import androidx.appcompat.app.AppCompatActivity -import com.mifos.mobile.passcode.utils.ForegroundChecker -import com.mifos.mobile.passcode.utils.ForegroundChecker.Companion.get - -/** - * Created by dilpreet on 19/01/18. - */ -abstract class BasePassCodeActivity : ComponentActivity(), ForegroundChecker.Listener { - override fun onResume() { - super.onResume() - get()!!.addListener(this) - get()!!.onActivityResumed() - } - - override fun onPause() { - super.onPause() - get()!!.onActivityPaused() - } - - override fun onBecameForeground() { - MifosPassCodeActivity.startMifosPassCodeActivity( - this, passCodeClass, - false - ) - } - - abstract val passCodeClass: Class<*>? -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthCallback.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthCallback.kt deleted file mode 100644 index 9b423d6..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthCallback.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mifos.mobile.passcode - -interface FpAuthCallback { - fun onFpAuthSuccess() - fun onCancel() -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthDialog.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthDialog.kt deleted file mode 100644 index 76916c0..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthDialog.kt +++ /dev/null @@ -1,108 +0,0 @@ -package com.mifos.mobile.passcode - -import android.app.AlertDialog -import android.content.Context -import android.util.Log -import android.view.LayoutInflater -import android.widget.TextView -import android.widget.Toast -import androidx.appcompat.widget.AppCompatButton - -class FpAuthDialog(private val context: Context) { - private var dialogTitle = context.getString(R.string.fp_dialog_title) - private var dialogMessage = context.getString(R.string.fp_dialog_message) - private var dialogCancelText = context.getString(R.string.fp_dialog_cancel) - - private var layoutInflater = LayoutInflater.from(context) - private var dialogView = layoutInflater.inflate(R.layout.dialog_fingerprint_auth, null) - private var tvDialogTitle = dialogView.findViewById(R.id.fingerprint_dialog_title) - private var tvDialogMessage = dialogView.findViewById(R.id.fingerprint_dialog_message) - private var tvDialogStatus = dialogView.findViewById(R.id.fingerprint_dialog_status) - private var btnCancel = dialogView.findViewById(R.id.fingerprint_dialog_cancel) - - private var dialogBuilder = AlertDialog.Builder(context) - private var dialog: AlertDialog? = null - - private var fpAuthCallback: FpAuthCallback = object : FpAuthCallback { - override fun onFpAuthSuccess() { - Toast.makeText(context, context.getString(R.string.authentication_successful), Toast.LENGTH_SHORT).show() - } - - override fun onCancel() { - Toast.makeText(context, context.getString(R.string.authentication_cancelled), Toast.LENGTH_SHORT).show() - } - - } - private var fpAuthHelper = FpAuthHelper(context, fpAuthCallback, this) - - fun setTitle(title: String): FpAuthDialog { - dialogTitle = title - return this - } - - fun setTitle(resTitle: Int): FpAuthDialog { - dialogTitle = context.resources.getString(resTitle) - return this - } - - fun setMessage(message: String): FpAuthDialog { - dialogMessage = message - return this - } - - fun setMessage(resMessage: Int): FpAuthDialog { - dialogMessage = context.resources.getString(resMessage) - return this - } - - fun setCancelText(cancelText: String): FpAuthDialog { - dialogCancelText = cancelText - return this - } - - fun setCancelText(resCancelText: Int): FpAuthDialog { - dialogCancelText = context.resources.getString(resCancelText) - return this - } - - fun setCallback(fpAuthCallback: FpAuthCallback): FpAuthDialog { - this.fpAuthCallback = fpAuthCallback - fpAuthHelper = FpAuthHelper(context, fpAuthCallback, this) - return this - } - - internal fun setStatusText(statusText: String) { - tvDialogStatus.text = statusText - } - - internal fun setStatusIcon(resIcon: Int) { - tvDialogStatus.setCompoundDrawablesWithIntrinsicBounds(resIcon, 0, 0, 0) - } - - fun dismiss() { - fpAuthHelper.stopFpAuth() - dialog!!.dismiss() - } - - fun show() { - if (!FpAuthSupport.checkAvailabiltyAndIfFingerprintRegistered(context)) { - Log.e("FingerprintAuth", "Device not Suitable for Fingerprint Authentication") - return - } - tvDialogTitle.text = dialogTitle - tvDialogMessage.text = dialogMessage - btnCancel.text = dialogCancelText - - dialog = dialogBuilder.setView(dialogView).create() - dialog!!.setCancelable(false) - dialog!!.show() - - fpAuthHelper.startFpAuth() - - btnCancel.setOnClickListener { - fpAuthHelper.stopFpAuth() - dialog!!.dismiss() - fpAuthCallback.onCancel() - } - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthHelper.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthHelper.kt deleted file mode 100644 index 4f61947..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthHelper.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.mifos.mobile.passcode - -import android.content.Context -import android.os.Handler -import android.widget.Toast -import androidx.core.hardware.fingerprint.FingerprintManagerCompat -import androidx.core.os.CancellationSignal - -class FpAuthHelper(private val context: Context, private val fpAuthCallback: FpAuthCallback, - private val fpAuthDialog: FpAuthDialog) { - private var cancellationSignal: CancellationSignal? = null - private var handler: Handler = Handler() - - companion object { - const val AUTH_FAILED_DELAY: Long = 1000 - const val AUTH_SUCCESS_DELAY: Long = 500 - } - - private val startScanning = Runnable { - fpAuthDialog.run { - setStatusText(context.getString(R.string.touch_the_sensor)) - setStatusIcon(R.drawable.ic_fingerprint_blue_48dp) - } - } - - fun startFpAuth() { - if (!FpAuthSupport.checkAvailabiltyAndIfFingerprintRegistered(context)) { - return - } - if (cancellationSignal == null) { - cancellationSignal = CancellationSignal() - } - -// val fingerprintManager = FingerprintManagerCompat.from(context) -// -// fingerprintManager.authenticate( -// null, 0, cancellationSignal, -// object : FingerprintManagerCompat.AuthenticationCallback() { -// -// override fun onAuthenticationHelp(helpMsgId: Int, helpString: CharSequence?) { -// super.onAuthenticationHelp(helpMsgId, helpString) -// Toast.makeText(context, helpString, Toast.LENGTH_SHORT).show() -// } -// -// override fun onAuthenticationFailed() { -// super.onAuthenticationFailed() -// fpAuthDialog.run { -// setStatusIcon(R.drawable.ic_cancel_red_48dp) -// setStatusText(context.getString(R.string.finger_print_not_recognized)) -// } -// handler.postDelayed(startScanning, AUTH_FAILED_DELAY) -// } -// -// override fun onAuthenticationSucceeded(result: FingerprintManagerCompat.AuthenticationResult?) { -// super.onAuthenticationSucceeded(result) -// fpAuthDialog.run { -// setStatusIcon(R.drawable.ic_check_circle_green_48dp) -// setStatusText(context.getString(R.string.authentication_successful)) -// } -// handler.postDelayed({ -// fpAuthDialog.dismiss() -// fpAuthCallback.onFpAuthSuccess() -// }, AUTH_SUCCESS_DELAY) -// } -// }, null -// ) - } - - fun stopFpAuth() { - cancellationSignal?.run { - cancel() - cancellationSignal = null - } - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthSupport.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthSupport.kt deleted file mode 100644 index 5cf2118..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/FpAuthSupport.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.mifos.mobile.passcode - -import android.content.Context -import android.os.Build -import androidx.core.hardware.fingerprint.FingerprintManagerCompat - -object FpAuthSupport { - - @JvmStatic - fun checkAvailability(context: Context): Boolean { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - FingerprintManagerCompat.from(context).isHardwareDetected - } - - @JvmStatic - fun isFingerprintRegistered(context: Context): Boolean { - return FingerprintManagerCompat.from(context).hasEnrolledFingerprints() - } - - @JvmStatic - fun checkAvailabiltyAndIfFingerprintRegistered(context: Context): Boolean { - val fingerprintManagerCompat = FingerprintManagerCompat.from(context) - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - fingerprintManagerCompat.isHardwareDetected && - fingerprintManagerCompat.hasEnrolledFingerprints() - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeActivity.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeActivity.kt deleted file mode 100644 index 13d0eb8..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeActivity.kt +++ /dev/null @@ -1,357 +0,0 @@ -package com.mifos.mobile.passcode - -import android.content.Context -import android.content.DialogInterface -import android.content.Intent -import android.os.Bundle -import android.view.View -import android.view.animation.Animation -import android.view.animation.AnimationUtils -import android.widget.Toast -import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat -import com.mifos.mobile.passcode.FpAuthSupport.checkAvailabiltyAndIfFingerprintRegistered -import com.mifos.mobile.passcode.databinding.ActivityPassCodeBinding -import com.mifos.mobile.passcode.utils.EncryptionUtil -import com.mifos.mobile.passcode.utils.EncryptionUtil.TYPE -import com.mifos.mobile.passcode.utils.PassCodeConstants -import com.mifos.mobile.passcode.utils.PassCodeNetworkChecker.isConnected -import com.mifos.mobile.passcode.utils.PasscodePreferencesHelper - -abstract class MifosPassCodeActivity : AppCompatActivity(), PassCodeListener { - - var shakeAnimation: Animation? = null - private var counter = 0 - private var isInitialScreen = false - private var isPassCodeVerified = false - private var strPassCodeEntered: String? = null - private var passcodePreferencesHelper: PasscodePreferencesHelper? = null - private var resetPasscode = false - abstract val logo: Int - abstract val fpDialogTitle: String? - abstract fun startNextActivity() - abstract fun startLoginActivity() - abstract fun showToaster(view: View?, msg: Int) - - private lateinit var binding: ActivityPassCodeBinding - - @get:TYPE - abstract val encryptionType: Int - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityPassCodeBinding.inflate(layoutInflater) - setContentView(binding.root) - shakeAnimation = AnimationUtils.loadAnimation(this, R.anim.shake) - binding.ivLogo.setImageResource(logo) - passcodePreferencesHelper = PasscodePreferencesHelper(this) - isInitialScreen = intent.getBooleanExtra( - PassCodeConstants.PASSCODE_INITIAL_LOGIN, - false - ) - - //Show Prompt Dialog if device Support Fingerprint Authentication and has fingerprint - // registered - if (checkAvailabiltyAndIfFingerprintRegistered(this) - && passcodePreferencesHelper!!.fingerprintEnableDialogState - ) { - val builder = AlertDialog.Builder( - this, - R.style.MaterialAlertDialogStyle - ) - builder.setTitle(R.string.fingerprint) - builder.setIcon(R.drawable.ic_fingerprint_blue_48dp) - builder.setMessage(R.string.FingerprintEnableMessage) - builder.setPositiveButton("Yes", object : DialogInterface.OnClickListener { - override fun onClick(dialogInterface: DialogInterface, i: Int) { - passcodePreferencesHelper!!.fingerprintEnableDialogState = false - passcodePreferencesHelper!!.authType = "fpauth" - fpDialogTitle?.let { - FpAuthDialog(this@MifosPassCodeActivity) - .setTitle(it) - .setCallback(object : FpAuthCallback { - override fun onFpAuthSuccess() { - startHomeActivity() - } - - override fun onCancel() { - cancelFingerprintAuth() - } - }).show() - } - } - }) - builder.setNegativeButton("No") { dialogInterface, i -> - passcodePreferencesHelper!!.fingerprintEnableDialogState = false - passcodePreferencesHelper!!.authType = "passcode" - } - val alertDialog = builder.create() - alertDialog.setCancelable(false) - alertDialog.show() - } - if (passcodePreferencesHelper!!.authType.equals("passcode", ignoreCase = true)) { - resetPasscode = intent.getBooleanExtra(PassCodeConstants.RESET_PASSCODE, false) - isPassCodeVerified = false - strPassCodeEntered = "" - if (!passcodePreferencesHelper!!.passCode!!.isEmpty()) { - binding.btnSkip.visibility = View.GONE - binding.btnSave.visibility = View.GONE - binding.tvPasscode.visibility = View.GONE - binding.btnForgotPasscode.visibility = View.VISIBLE - //enabling passCodeListener only when user has already setup PassCode - binding.pvPasscode.setPassCodeListener(this) - } - if (resetPasscode) { - binding.btnSkip.visibility = View.GONE - binding.btnSave.visibility = View.GONE - binding.tvPasscode.visibility = View.VISIBLE - binding.tvPasscode.text = getString(R.string.confirm_passcode) - } - } - } - - private fun encryptPassCode(passCode: String): String? { - @TYPE val type = encryptionType - var encryptedPassCode: String? = null - when (type) { - EncryptionUtil.MOBILE_BANKING -> encryptedPassCode = - EncryptionUtil.getMobileBankingHash(passCode) - - EncryptionUtil.ANDROID_CLIENT -> encryptedPassCode = - EncryptionUtil.getAndroidClientHash(passCode) - - EncryptionUtil.FINERACT_CN -> encryptedPassCode = - EncryptionUtil.getFineractCNHash(passCode) - - EncryptionUtil.DEFAULT -> encryptedPassCode = EncryptionUtil.getDefaultHash(passCode) - } - return encryptedPassCode - } - - fun clearTokenPreferences() { - passcodePreferencesHelper!!.clear() - } - - fun skip(v: View?) { - startHomeActivity() - } - - /** - * Saves the passcode by encrypting it which we got from [MifosPassCodeView] - * - * @param view Passcode View - */ - fun savePassCode(view: View?) { - if (isPassCodeLengthCorrect) { - if (isPassCodeVerified) { - if (strPassCodeEntered!!.compareTo(binding.pvPasscode.passcode) == 0) { - passcodePreferencesHelper!!.savePassCode(encryptPassCode(binding.pvPasscode.passcode)) - startHomeActivity() - } else { - showToaster(binding.clRootview, R.string.passcode_does_not_match) - binding.pvPasscode.clearPasscodeField() - } - } else { - binding.btnSkip.visibility = View.INVISIBLE - binding.btnSave.text = getString(R.string.save) - binding.tvPasscode.text = getString(R.string.reenter_passcode) - strPassCodeEntered = binding.pvPasscode.passcode - binding.pvPasscode.clearPasscodeField() - isPassCodeVerified = true - } - } - } - - /** - * It is a callback for [MifosPassCodeView], provides with the passcode entered by user - * - * @param passcode Passcode that is entered by user. - */ - override fun passCodeEntered(passcode: String?) { - if (!isInternetAvailable) { - binding.pvPasscode.clearPasscodeField() - return - } - if (counter == 3) { - Toast.makeText( - applicationContext, R.string.incorrect_passcode_more_than_three, - Toast.LENGTH_SHORT - ).show() - clearTokenPreferences() - startLoginActivity() - return - } - if (isPassCodeLengthCorrect) { - val passwordEntered = encryptPassCode(binding.pvPasscode.passcode) - if (passcodePreferencesHelper!!.passCode == passwordEntered) { - if (resetPasscode) { - resetPasscode() - return - } - startHomeActivity() - } else { - binding.pvPasscode.startAnimation(shakeAnimation) - counter++ - binding.pvPasscode.clearPasscodeField() - showToaster(binding.clRootview, R.string.incorrect_passcode) - } - } - } - - fun forgotPassCode(v: View?) { - clearTokenPreferences() - startLoginActivity() - } - - fun cancelFingerprintAuth() { - clearTokenPreferences() - startLoginActivity() - finish() - } - - private val isInternetAvailable: Boolean - /** - * Checks for internet availability - * - * @return Returns true if connected else returns false - */ - get() = if (isConnected(this)) { - true - } else { - showToaster(binding.clRootview, R.string.no_internet_connection) - false - } - - fun clickedOne(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.one)) - } - - fun clickedTwo(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.two)) - } - - fun clickedThree(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.three)) - } - - fun clickedFour(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.four)) - } - - fun clickedFive(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.five)) - } - - fun clickedSix(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.six)) - } - - fun clickedSeven(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.seven)) - } - - fun clickedEight(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.eight)) - } - - fun clickedNine(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.nine)) - } - - fun clickedZero(v: View?) { - binding.pvPasscode.enterCode(getString(R.string.zero)) - } - - fun clickedBackSpace(v: View?) { - binding.pvPasscode.backSpace() - } - - /** - * @param view PasscodeView that changes to text if it was hidden and vice a versa - */ - fun visibilityChange(view: View?) { - binding.pvPasscode.revertPassCodeVisibility() - if (!binding.pvPasscode.passcodeVisible()) { - binding.ivVisibility.setColorFilter( - ContextCompat.getColor( - this@MifosPassCodeActivity, - R.color.light_grey - ) - ) - } else { - binding.ivVisibility.setColorFilter( - ContextCompat.getColor( - this@MifosPassCodeActivity, - R.color.gray_dark - ) - ) - } - } - - private val isPassCodeLengthCorrect: Boolean - /** - * Checks whether passcode entered is of correct length - * - * @return Returns true if passcode lenght is 4 else shows message - */ - private get() { - if (binding.pvPasscode.passcode.length == 4) { - return true - } - showToaster(binding.clRootview, R.string.error_passcode) - return false - } - - private fun startHomeActivity() { - if (isInitialScreen) { - startNextActivity() - } - finish() - } - - override fun onBackPressed() { - if (isInitialScreen) { - super.onBackPressed() - } - } - - private fun resetPasscode() { - resetPasscode = false - binding.btnSkip.visibility = View.VISIBLE - binding.btnSave.visibility = View.VISIBLE - binding.tvPasscode.setText(R.string.passcode_setup) - counter = 0 - binding.pvPasscode.clearPasscodeField() - binding.pvPasscode.setPassCodeListener(null) - passcodePreferencesHelper!!.clear() - } - - override fun onResume() { - super.onResume() - if (passcodePreferencesHelper!!.authType.equals("fpauth", ignoreCase = true)) { - FpAuthDialog(this@MifosPassCodeActivity) - .setTitle(fpDialogTitle!!) - .setCallback(object : FpAuthCallback { - override fun onFpAuthSuccess() { - startHomeActivity() - } - - override fun onCancel() { - cancelFingerprintAuth() - } - }).show() - } - } - - companion object { - @JvmOverloads - fun startMifosPassCodeActivity( - context: Context, clazz: Class<*>?, - isInitialLogin: Boolean = true - ) { - val intent = Intent(context, clazz) - intent.putExtra(PassCodeConstants.PASSCODE_INITIAL_LOGIN, isInitialLogin) - context.startActivity(intent) - } - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeView.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeView.kt deleted file mode 100644 index 279f108..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/MifosPassCodeView.kt +++ /dev/null @@ -1,133 +0,0 @@ -package com.mifos.mobile.passcode - -import android.content.Context -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.util.AttributeSet -import android.view.View - -/** - * Created by dilpreet on 15/7/17. - */ -class MifosPassCodeView : View { - private var emptyCirclePaint: Paint? = null - private var fillCirclePaint: Paint? = null - private val PASSWORD_LENGTH = 4 - private var passwordList: MutableList? = null - private var isPasscodeVisible = false - private var passCodeListener: PassCodeListener? = null - - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { - init(attrs) - } - - constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( - context, - attrs, - defStyleAttr - ) { - init(attrs) - } - - fun setPassCodeListener(passCodeListener: PassCodeListener?) { - this.passCodeListener = passCodeListener - } - - private fun init(attrs: AttributeSet?) { - val attributes = context.obtainStyledAttributes(attrs, R.styleable.MifosPassCodeView) - val defaultTextSize = (12 * context.resources.displayMetrics.density).toInt() - val color = attributes.getColor(R.styleable.MifosPassCodeView_color, Color.WHITE) - emptyCirclePaint = Paint() - emptyCirclePaint!!.color = color - emptyCirclePaint!!.isAntiAlias = true - emptyCirclePaint!!.style = Paint.Style.STROKE - emptyCirclePaint!!.strokeWidth = 1f - fillCirclePaint = Paint() - fillCirclePaint!!.color = color - fillCirclePaint!!.isAntiAlias = true - fillCirclePaint!!.textSize = - attributes.getDimensionPixelSize( - R.styleable.MifosPassCodeView_text_size, - defaultTextSize - ) - .toFloat() - fillCirclePaint!!.style = Paint.Style.FILL - attributes.recycle() - passwordList = ArrayList() - isPasscodeVisible = false - } - - override fun onDraw(canvas: Canvas) { - super.onDraw(canvas) - val stackSize = passwordList!!.size - var xPosition = width / (PASSWORD_LENGTH * 2) - for (i in 1..PASSWORD_LENGTH) { - if (stackSize >= i) { - if (!isPasscodeVisible) { - canvas.drawCircle( - xPosition.toFloat(), - (height / 2).toFloat(), - 8f, - fillCirclePaint!! - ) - } else { - canvas.drawText( - passwordList!![i - 1], xPosition.toFloat(), (height / 2 + - height / 8).toFloat(), fillCirclePaint!! - ) - } - } else { - canvas.drawCircle( - xPosition.toFloat(), - (height / 2).toFloat(), - 8f, - emptyCirclePaint!! - ) - } - xPosition += width / PASSWORD_LENGTH - } - } - - fun enterCode(character: String) { - if (passwordList!!.size < PASSWORD_LENGTH) { - passwordList!!.add(character) - invalidate() - } - if (passwordList!!.size == PASSWORD_LENGTH && passCodeListener != null) { - passCodeListener!!.passCodeEntered(passcode) - } - } - - val passcode: String - get() { - val builder = StringBuilder() - for (character in passwordList!!) { - builder.append(character) - } - return builder.toString() - } - - fun clearPasscodeField() { - passwordList!!.clear() - invalidate() - } - - fun backSpace() { - if (passwordList!!.size > 0) { - passwordList!!.removeAt(passwordList!!.size - 1) - invalidate() - } - } - - fun revertPassCodeVisibility() { - isPasscodeVisible = !isPasscodeVisible - invalidate() - } - - fun passcodeVisible(): Boolean { - return isPasscodeVisible - } - - -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/PassCodeListener.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/PassCodeListener.kt deleted file mode 100644 index 2ac613c..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/PassCodeListener.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.mifos.mobile.passcode - -interface PassCodeListener { - fun passCodeEntered(passcode: String?) -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/EncryptionUtil.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/EncryptionUtil.kt deleted file mode 100644 index af2906d..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/EncryptionUtil.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.mifos.mobile.passcode.utils - -import android.util.Log -import androidx.annotation.IntDef - -object EncryptionUtil { - - const val DEFAULT = 1 - const val MOBILE_BANKING = 2 - const val ANDROID_CLIENT = 3 - const val FINERACT_CN = 4 - - - @IntDef(DEFAULT, MOBILE_BANKING, ANDROID_CLIENT, FINERACT_CN) - @Retention(AnnotationRetention.SOURCE) - annotation class TYPE - - init { - try { - System.loadLibrary("encryption") - } catch (e: UnsatisfiedLinkError) { - Log.e("LoadJniLib", "Error: Could not load native library: ${e.message}") - } - } - - external fun getPassCodeHash(passcode: String): String - - fun getDefaultHash(passCode: String): String { - return getPassCodeHash(passCode) - } - - fun getMobileBankingHash(passCode: String): String { - return getPassCodeHash(passCode) - } - - fun getAndroidClientHash(passCode: String): String { - return getPassCodeHash(passCode) - } - - fun getFineractCNHash(passCode: String): String { - return getPassCodeHash(passCode) - } -} diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/ForegroundChecker.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/ForegroundChecker.kt deleted file mode 100644 index c88942c..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/ForegroundChecker.kt +++ /dev/null @@ -1,110 +0,0 @@ -package com.mifos.mobile.passcode.utils - -import android.content.Context -import android.os.Handler -import com.mifos.mobile.passcode.utils.ForegroundChecker - -/** - * Created by dilpreet on 18/7/17. - */ -class ForegroundChecker private constructor(context: Context) { - interface Listener { - fun onBecameForeground() - } - - /** - * Returns True if application is in foreground - * @return State of Application - */ - var isForeground = false - private set - private var paused = true - private val handler = Handler() - private var listener: Listener? = null - private var check: Runnable? = null - private var backgroundTimeStart: Long - private val passcodePreferencesHelper: PasscodePreferencesHelper - - /** - * Initializes [ForegroundChecker] - * @param context Application Context - */ - init { - backgroundTimeStart = -1 - passcodePreferencesHelper = PasscodePreferencesHelper(context) - } - - val isBackground: Boolean - /** - * Returns True if application is in background - * @return State of Application - */ - get() = !isForeground - - fun addListener(listener: Listener?) { - this.listener = listener - } - - /** - * It calls `onBecameForeground()` if `secondsInBackground` >= - * `MIN_BACKGROUND_THRESHOLD` - */ - fun onActivityResumed() { - paused = false - val wasBackground = !isForeground - isForeground = true - if (check != null) handler.removeCallbacks(check!!) - if (wasBackground) { - val secondsInBackground = ((System.currentTimeMillis() - backgroundTimeStart) / - 1000).toInt() - if (backgroundTimeStart != -1L && secondsInBackground >= MIN_BACKGROUND_THRESHOLD && listener != null && passcodePreferencesHelper.passCode?.isEmpty() == true) { - listener!!.onBecameForeground() - } - } - } - - /** - * It executes a Handler after `CHECK_DELAY` and then sets `foreground` to false - */ - fun onActivityPaused() { - paused = true - if (check != null) handler.removeCallbacks(check!!) - handler.postDelayed(object : Runnable { - override fun run() { - if (isForeground && paused) { - isForeground = false - backgroundTimeStart = System.currentTimeMillis() - } - } - }.also { check = it }, CHECK_DELAY) - } - - companion object { - const val CHECK_DELAY: Long = 500 - const val MIN_BACKGROUND_THRESHOLD = 60 - val TAG = ForegroundChecker::class.java.name - private var instance: ForegroundChecker? = null - - /** - * Used to initialize `instance` of [ForegroundChecker] - * @param context Application Content - * @return Instance of [ForegroundChecker] - */ - @JvmStatic - fun init(context: Context): ForegroundChecker? { - if (instance == null) { - instance = ForegroundChecker(context) - } - return instance - } - - /** - * Provides instance of [ForegroundChecker] - * @return Instance of [ForegroundChecker] - */ - @JvmStatic - fun get(): ForegroundChecker? { - return instance - } - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeConstants.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeConstants.kt deleted file mode 100644 index db51517..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeConstants.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mifos.mobile.passcode.utils - -/** - * Created by dilpreet on 19/01/18. - */ -object PassCodeConstants { - const val PASSCODE_INITIAL_LOGIN = "initial_login" - const val RESET_PASSCODE = "reset_passcode" -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeNetworkChecker.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeNetworkChecker.kt deleted file mode 100644 index 2dd4433..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PassCodeNetworkChecker.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.mifos.mobile.passcode.utils - -import android.content.Context -import android.net.ConnectivityManager -import android.net.NetworkInfo -import android.telephony.TelephonyManager - -/** - * Created by rishabhkhanna on 07/03/17. - */ -object PassCodeNetworkChecker { - /** - * Get the network info - * - * @param context Context - * @return NetworkInfo - */ - fun getNetworkInfo(context: Context): NetworkInfo? { - val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - return cm.activeNetworkInfo - } - - /** - * Check if there is any connectivity - * - * @param context Context - * @return state of network - */ - @JvmStatic - fun isConnected(context: Context): Boolean { - val info = getNetworkInfo(context) - return info != null && info.isConnected - } - - /** - * Check if there is any connectivity to a Wifi network - * - * @param context Context - * @return state if wifi connection - */ - fun isConnectedWifi(context: Context): Boolean { - val info = getNetworkInfo(context) - return info != null && info.isConnected && info.type == ConnectivityManager.TYPE_WIFI - } - - /** - * Check if there is any connectivity to a mobile network - * - * @param context Context - * @return mobile connected to network or not - */ - fun isConnectedMobile(context: Context): Boolean { - val info = getNetworkInfo(context) - return info != null && info.isConnected && info.type == ConnectivityManager.TYPE_MOBILE - } - - /** - * Check if there is fast connectivity - * - * @param context Context - * @return connection is fast or not - */ - fun isConnectedFast(context: Context): Boolean { - val info = getNetworkInfo(context) - return info != null && info.isConnected && - isConnectionFast(info.type, info.subtype) - } - - /** - * Check if the connection is fast - * - * @param type Type of connection - * @param subType SubType of Connection - * @return connection is fast or not - */ - fun isConnectionFast(type: Int, subType: Int): Boolean { - return if (type == ConnectivityManager.TYPE_WIFI) { - true - } else if (type == ConnectivityManager.TYPE_MOBILE) { - when (subType) { - TelephonyManager.NETWORK_TYPE_1xRTT -> false // ~ 50-100 kbps - TelephonyManager.NETWORK_TYPE_CDMA -> false // ~ 14-64 kbps - TelephonyManager.NETWORK_TYPE_EDGE -> false // ~ 50-100 kbps - TelephonyManager.NETWORK_TYPE_EVDO_0 -> true // ~ 400-1000 kbps - TelephonyManager.NETWORK_TYPE_EVDO_A -> true // ~ 600-1400 kbps - TelephonyManager.NETWORK_TYPE_GPRS -> false // ~ 100 kbps - TelephonyManager.NETWORK_TYPE_HSDPA -> true // ~ 2-14 Mbps - TelephonyManager.NETWORK_TYPE_HSPA -> true // ~ 700-1700 kbps - TelephonyManager.NETWORK_TYPE_HSUPA -> true // ~ 1-23 Mbps - TelephonyManager.NETWORK_TYPE_UMTS -> true // ~ 400-7000 kbps - TelephonyManager.NETWORK_TYPE_EHRPD -> true // ~ 1-2 Mbps - TelephonyManager.NETWORK_TYPE_EVDO_B -> true // ~ 5 Mbps - TelephonyManager.NETWORK_TYPE_HSPAP -> true // ~ 10-20 Mbps - TelephonyManager.NETWORK_TYPE_IDEN -> false // ~25 kbps - TelephonyManager.NETWORK_TYPE_LTE -> true // ~ 10+ Mbps - TelephonyManager.NETWORK_TYPE_UNKNOWN -> false - else -> false - } - } else { - false - } - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PasscodePreferencesHelper.kt b/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PasscodePreferencesHelper.kt deleted file mode 100644 index 372f263..0000000 --- a/mifos-passcode/src/main/java/com/mifos/mobile/passcode/utils/PasscodePreferencesHelper.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.mifos.mobile.passcode.utils - -import android.content.Context -import android.content.SharedPreferences -import android.preference.PreferenceManager - -/** - * Created by dilpreet on 19/01/18. - */ -class PasscodePreferencesHelper(context: Context?) { - private val sharedPreferences: SharedPreferences - private val TOKEN = "preferences_mifos_passcode_string" - private val FINGERPRINTENABLER = "fingerprint_enable_dialog" - private val AUTHTYPE = "auth_type" - - init { - sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - } - - fun savePassCode(token: String?) { - sharedPreferences.edit().putString(TOKEN, token).apply() - } - - val passCode: String? - get() = sharedPreferences.getString(TOKEN, "") - var fingerprintEnableDialogState: Boolean - get() = sharedPreferences.getBoolean(FINGERPRINTENABLER, true) - set(show) { - sharedPreferences.edit().putBoolean(FINGERPRINTENABLER, show).apply() - } - var authType: String? - get() = sharedPreferences.getString(AUTHTYPE, "") - set(authType) { - sharedPreferences.edit().putString(AUTHTYPE, authType).apply() - } - - fun clear() { - sharedPreferences.edit().clear().apply() - } -} \ No newline at end of file diff --git a/mifos-passcode/src/main/jniLibs/arm64-v8a/libencryption.so b/mifos-passcode/src/main/jniLibs/arm64-v8a/libencryption.so deleted file mode 100644 index 3beba0d..0000000 Binary files a/mifos-passcode/src/main/jniLibs/arm64-v8a/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/armeabi-v7a/libencryption.so b/mifos-passcode/src/main/jniLibs/armeabi-v7a/libencryption.so deleted file mode 100644 index f7bb7ef..0000000 Binary files a/mifos-passcode/src/main/jniLibs/armeabi-v7a/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/armeabi/libencryption.so b/mifos-passcode/src/main/jniLibs/armeabi/libencryption.so deleted file mode 100644 index 64484d8..0000000 Binary files a/mifos-passcode/src/main/jniLibs/armeabi/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/mips/libencryption.so b/mifos-passcode/src/main/jniLibs/mips/libencryption.so deleted file mode 100644 index 35f5e0b..0000000 Binary files a/mifos-passcode/src/main/jniLibs/mips/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/mips64/libencryption.so b/mifos-passcode/src/main/jniLibs/mips64/libencryption.so deleted file mode 100644 index 922e2b1..0000000 Binary files a/mifos-passcode/src/main/jniLibs/mips64/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/x86/libencryption.so b/mifos-passcode/src/main/jniLibs/x86/libencryption.so deleted file mode 100644 index 7e6ab86..0000000 Binary files a/mifos-passcode/src/main/jniLibs/x86/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/jniLibs/x86_64/libencryption.so b/mifos-passcode/src/main/jniLibs/x86_64/libencryption.so deleted file mode 100644 index 0e3461f..0000000 Binary files a/mifos-passcode/src/main/jniLibs/x86_64/libencryption.so and /dev/null differ diff --git a/mifos-passcode/src/main/res/anim/shake.xml b/mifos-passcode/src/main/res/anim/shake.xml deleted file mode 100644 index 1b5fd73..0000000 --- a/mifos-passcode/src/main/res/anim/shake.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/drawable/ic_backspace_48px.xml b/mifos-passcode/src/main/res/drawable/ic_backspace_48px.xml deleted file mode 100644 index 6be920a..0000000 --- a/mifos-passcode/src/main/res/drawable/ic_backspace_48px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mifos-passcode/src/main/res/drawable/ic_cancel_red_48dp.xml b/mifos-passcode/src/main/res/drawable/ic_cancel_red_48dp.xml deleted file mode 100644 index 73beaa6..0000000 --- a/mifos-passcode/src/main/res/drawable/ic_cancel_red_48dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/drawable/ic_check_circle_green_48dp.xml b/mifos-passcode/src/main/res/drawable/ic_check_circle_green_48dp.xml deleted file mode 100644 index fb0884a..0000000 --- a/mifos-passcode/src/main/res/drawable/ic_check_circle_green_48dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/drawable/ic_fingerprint_blue_48dp.xml b/mifos-passcode/src/main/res/drawable/ic_fingerprint_blue_48dp.xml deleted file mode 100644 index 7a75ae6..0000000 --- a/mifos-passcode/src/main/res/drawable/ic_fingerprint_blue_48dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/drawable/ic_visibility_48px.xml b/mifos-passcode/src/main/res/drawable/ic_visibility_48px.xml deleted file mode 100644 index 44f9d4f..0000000 --- a/mifos-passcode/src/main/res/drawable/ic_visibility_48px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mifos-passcode/src/main/res/layout/activity_pass_code.xml b/mifos-passcode/src/main/res/layout/activity_pass_code.xml deleted file mode 100644 index 6b15861..0000000 --- a/mifos-passcode/src/main/res/layout/activity_pass_code.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mifos-passcode/src/main/res/layout/dialog_fingerprint_auth.xml b/mifos-passcode/src/main/res/layout/dialog_fingerprint_auth.xml deleted file mode 100644 index 4d835da..0000000 --- a/mifos-passcode/src/main/res/layout/dialog_fingerprint_auth.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - diff --git a/mifos-passcode/src/main/res/values/attr.xml b/mifos-passcode/src/main/res/values/attr.xml deleted file mode 100644 index 612c58d..0000000 --- a/mifos-passcode/src/main/res/values/attr.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/values/colors.xml b/mifos-passcode/src/main/res/values/colors.xml deleted file mode 100644 index c5936fe..0000000 --- a/mifos-passcode/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #BB666666 - #03A9F4 - #ffd1d1d1 - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/values/dimens.xml b/mifos-passcode/src/main/res/values/dimens.xml deleted file mode 100644 index ac4778a..0000000 --- a/mifos-passcode/src/main/res/values/dimens.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - 16dp - 72dp - 56dp - 20dp - 8dp - 20sp - 16dp - 24dp - 20dp - 16sp - 28dp - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/values/strings.xml b/mifos-passcode/src/main/res/values/strings.xml deleted file mode 100644 index 8fadea8..0000000 --- a/mifos-passcode/src/main/res/values/strings.xml +++ /dev/null @@ -1,39 +0,0 @@ - - Mobile-Passcode - Enter 4 digit Passcode - Passcode should be of 4 digit - Incorrect Passcode - You have entered incorrect Passcode more than 3 times - Skip - Save - Proceed - Setup a passcode to login - Please re-enter your passcode - Passcode does not match. - Forgot passcode, login manually - No Internet Connection - Confirm your passcode - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 0 - MainActivity - - Touch the Sensor - Use your fingerprint to access the app - Login to Mifos - Use password instead - Touch the Sensor - Fingerprint Not Recognized - Authentication Successful - Authentication Cancelled - Fingerprint - Do you want to enable Fingerprint Authentication? - \ No newline at end of file diff --git a/mifos-passcode/src/main/res/values/styles.xml b/mifos-passcode/src/main/res/values/styles.xml deleted file mode 100644 index e52906d..0000000 --- a/mifos-passcode/src/main/res/values/styles.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -