diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..e3181f81
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,14 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "gradle"
+ directory: "/"
+ schedule:
+ interval: "daily"
+
+ commit-message:
+ prefix: "[Android]"
diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml
new file mode 100644
index 00000000..14b613a4
--- /dev/null
+++ b/.github/workflows/android.yaml
@@ -0,0 +1,43 @@
+name: Android CI
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: ๐งฑ Set Up JDK
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+
+ - name: Grant Gradlew rights
+ run: chmod +x gradlew
+
+ - name: ๐งช Run Tests
+ run: ./gradlew test
+
+ - name: ๐ Build Project with Spotless Check
+ run: ./gradlew spotlessCheck
+
+ - name: โณ Build with Gradle
+ run: ./gradlew build
+
+ - name: ๐ Build APK
+ run: bash ./gradlew assembleProductionDebug --stacktrace
+
+ - name: ๐ Upload APK ๐ฑ
+ uses: actions/upload-artifact@v2
+ with:
+ name: app
+ path: app/build/outputs/apk/production/debug/*.apk
+ retention-days: 3
diff --git a/.github/workflows/detekt-analysis.yml b/.github/workflows/detekt-analysis.yml
new file mode 100644
index 00000000..994634a5
--- /dev/null
+++ b/.github/workflows/detekt-analysis.yml
@@ -0,0 +1,103 @@
+# This workflow performs a static analysis of your Kotlin source code using
+# Detekt.
+#
+# Scans are triggered:
+# 1. On every push to default and protected branches
+# 2. On every Pull Request targeting the default branch
+# 3. On a weekly schedule
+# 4. Manually, on demand, via the "workflow_dispatch" event
+#
+# The workflow should work with no modifications, but you might like to use a
+# later version of the Detekt CLI by modifing the $DETEKT_RELEASE_TAG
+# environment variable.
+name: Scan with Detekt
+
+on:
+ # Triggers the workflow on push or pull request events but only for default and protected branches
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+ schedule:
+ - cron: '19 0 * * 2'
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+env:
+ # Release tag associated with version of Detekt to be installed
+ # SARIF support (required for this workflow) was introduced in Detekt v1.15.0
+ DETEKT_RELEASE_TAG: v1.15.0
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ # This workflow contains a single job called "scan"
+ scan:
+ name: Scan
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v2
+
+ # Gets the download URL associated with the $DETEKT_RELEASE_TAG
+ - name: Get Detekt download URL
+ id: detekt_info
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ DETEKT_DOWNLOAD_URL=$( gh api graphql --field tagName=$DETEKT_RELEASE_TAG --raw-field query='
+ query getReleaseAssetDownloadUrl($tagName: String!) {
+ repository(name: "detekt", owner: "detekt") {
+ release(tagName: $tagName) {
+ releaseAssets(name: "detekt", first: 1) {
+ nodes {
+ downloadUrl
+ }
+ }
+ }
+ }
+ }
+ ' | \
+ jq --raw-output '.data.repository.release.releaseAssets.nodes[0].downloadUrl' )
+ echo "::set-output name=download_url::$DETEKT_DOWNLOAD_URL"
+
+ # Sets up the detekt cli
+ - name: Setup Detekt
+ run: |
+ dest=$( mktemp -d )
+ curl --request GET \
+ --url ${{ steps.detekt_info.outputs.download_url }} \
+ --silent \
+ --location \
+ --output $dest/detekt
+ chmod a+x $dest/detekt
+ echo $dest >> $GITHUB_PATH
+
+ # Performs static analysis using Detekt
+ - name: Run Detekt
+ continue-on-error: true
+ run: |
+ detekt --input ${{ github.workspace }} --report sarif:${{ github.workspace }}/detekt.sarif.json
+
+ # Modifies the SARIF output produced by Detekt so that absolute URIs are relative
+ # This is so we can easily map results onto their source files
+ # This can be removed once relative URI support lands in Detekt: https://git.io/JLBbA
+ - name: Make artifact location URIs relative
+ continue-on-error: true
+ run: |
+ echo "$(
+ jq \
+ --arg github_workspace ${{ github.workspace }} \
+ '. | ( .runs[].results[].locations[].physicalLocation.artifactLocation.uri |= if test($github_workspace) then .[($github_workspace | length | . + 1):] else . end )' \
+ ${{ github.workspace }}/detekt.sarif.json
+ )" > ${{ github.workspace }}/detekt.sarif.json
+
+ # Uploads results to GitHub repository using the upload-sarif action
+ - uses: github/codeql-action/upload-sarif@v1
+ with:
+ # Path to SARIF file relative to the root of the repository
+ sarif_file: ${{ github.workspace }}/detekt.sarif.json
+ checkout_path: ${{ github.workspace }}
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index c6e0331b..e522106a 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -12,6 +12,8 @@
+
+
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 04ae1a58..5aab48e5 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -31,5 +31,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f4f23d8b..f33200d4 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,14 +5,23 @@
+
+
-
+
+
-
-
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 801a11db..aa98f22f 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,16 @@
-# KeyPass : Offline Password Manager
+ KeyPass : Offline Password Manager
+
-
+
+
+
+
-
-
-| | | | | |
-|--|--|--|--|--|
-| | | | |
+
@@ -18,11 +20,12 @@
- [x] Open Source : Code is accessible to every one
- [x] Encrypted Backup and Restore
- [x] Dark Mode Support
-- [x] Material Design
+- [x] Material Design 3
- [x] Screenshot Blocked
- [x] Authenticate with device credentials (pin, pattern, biometrics)
- [x] Auto Backup
- [x] TOTP
+- [ ] Jetpack Compose
## ๐ ๏ธ Language, Tools & Frameworks Used
@@ -37,4 +40,29 @@
## Download Links
-
+
+
+
+```
+MIT License
+
+Copyright (c) 2021 Yogesh Choudhary Paliyal
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
diff --git a/app/build.gradle b/app/build.gradle
index 164c3386..2ae7ed80 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@ android {
applicationId appPackageId
minSdkVersion 22
targetSdkVersion 31
- versionCode 1400
- versionName "1.4.0"
+ versionCode 1401
+ versionName "1.4.1"
testInstrumentationRunner "com.yogeshpaliyal.keypass.CustomTestRunner"
}
@@ -73,11 +73,13 @@ android {
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.31"
- implementation 'androidx.core:core-ktx:1.6.0'
- implementation 'androidx.appcompat:appcompat:1.3.1'
- implementation 'com.google.android.material:material:1.4.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
+ implementation project(":common")
+
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.6.0"
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.appcompat:appcompat:1.4.0'
+ implementation 'com.google.android.material:material:1.6.0-alpha01'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
implementation 'androidx.preference:preference-ktx:1.1.1'
testImplementation 'junit:junit:4.13.2'
@@ -106,26 +108,11 @@ dependencies {
implementation "androidx.room:room-ktx:$room_version"
- implementation 'com.github.yogeshpaliyal:Android-Universal-Recycler-View-Adapter:2.2.0'
+ implementation 'com.yogeshpaliyal:universal-adapter:3.0.0'
implementation "androidx.biometric:biometric:1.1.0"
- implementation "androidx.preference:preference-ktx:1.1.1"
-
-
- implementation "androidx.work:work-runtime-ktx:2.6.0"
-
-
-
-
- //Androidx Security
- implementation "androidx.security:security-crypto:1.1.0-alpha03"
-
-
- implementation 'com.google.code.gson:gson:2.8.8'
-
-
// dependency injection
implementation("com.google.dagger:hilt-android:$hilt_version")
kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
@@ -136,24 +123,39 @@ dependencies {
// zxing library
// implementation "com.googl.ezxing:android-core:3.4.1"
- implementation 'com.journeyapps:zxing-android-embedded:4.2.0'
-
-
- // apache common codec
- implementation "commons-codec:commons-codec:1.15"
-
-
+ implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
// For instrumented tests.
- androidTestImplementation("com.google.dagger:hilt-android-testing:2.38.1")
+ androidTestImplementation("com.google.dagger:hilt-android-testing:2.40.5")
// ...with Kotlin.
- kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.38.1")
+ kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.40")
// For Robolectric tests.
- testImplementation("com.google.dagger:hilt-android-testing:2.38.1")
+ testImplementation("com.google.dagger:hilt-android-testing:2.40.5")
// ...with Kotlin.
- kaptTest("com.google.dagger:hilt-android-compiler:2.38.1")
+ kaptTest("com.google.dagger:hilt-android-compiler:2.40")
+ // jetpack compose
+ implementation 'androidx.compose.ui:ui:1.0.5'
+
+ implementation 'com.google.code.gson:gson:2.8.9'
+
+
+ implementation 'androidx.compose.ui:ui-tooling:1.0.5'
+ // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
+ implementation 'androidx.compose.foundation:foundation:1.0.5'
+ // Material Design
+ implementation 'androidx.compose.material:material:1.0.5'
+ // Material design icons
+ implementation 'androidx.compose.material:material-icons-core:1.0.5'
+ implementation 'androidx.compose.material:material-icons-extended:1.0.5'
+ // Integration with activities
+ implementation 'androidx.activity:activity-compose:1.4.0'
+ // Integration with ViewModels
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0'
+ // Integration with observables
+ implementation 'androidx.compose.runtime:runtime-livedata:1.0.5'
+
}
diff --git a/app/src/androidTest/java/com/yogeshpaliyal/keypass/CustomTestRunner.kt b/app/src/androidTest/java/com/yogeshpaliyal/keypass/CustomTestRunner.kt
index 641b70a5..f2e487d4 100644
--- a/app/src/androidTest/java/com/yogeshpaliyal/keypass/CustomTestRunner.kt
+++ b/app/src/androidTest/java/com/yogeshpaliyal/keypass/CustomTestRunner.kt
@@ -11,4 +11,4 @@ class CustomTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt
index 67887acd..8f8a9144 100644
--- a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt
+++ b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt
@@ -1,6 +1,5 @@
package com.yogeshpaliyal.keypass.ui.nav
-import androidx.test.espresso.Espresso.onData
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
@@ -8,24 +7,15 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
-import androidx.test.ext.junit.rules.activityScenarioRule
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.LargeTest
-import com.yogeshpaliyal.keypass.AppDatabase
+import com.yogeshpaliyal.common.AppDatabase
+import com.yogeshpaliyal.common.data.AccountModel
import com.yogeshpaliyal.keypass.R
-import com.yogeshpaliyal.keypass.data.AccountModel
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
-import dagger.hilt.android.testing.HiltTestApplication
-import org.hamcrest.CoreMatchers.not
import org.junit.Assert.*
-
import org.junit.Before
-import org.junit.FixMethodOrder
import org.junit.Rule
import org.junit.Test
-import org.junit.runner.OrderWith
-import org.junit.runner.RunWith
import javax.inject.Inject
@HiltAndroidTest
@@ -35,10 +25,9 @@ class DashboardActivityTest {
@get:Rule(order = 1)
var activityScenarioRule = ActivityScenarioRule(DashboardActivity::class.java)
-
@Inject
- lateinit var appDatabase: AppDatabase
+ lateinit var appDatabase: com.yogeshpaliyal.common.AppDatabase
@Before
fun setUp() {
@@ -46,8 +35,7 @@ class DashboardActivityTest {
appDatabase.clearAllTables()
}
-
- private fun getDummyAccount() : AccountModel{
+ private fun getDummyAccount(): AccountModel {
val accountModel = AccountModel()
accountModel.title = "Github ${System.currentTimeMillis()}"
accountModel.username = "yogeshpaliyal"
@@ -59,14 +47,14 @@ class DashboardActivityTest {
}
@Test
- fun addAccountAndDetailAndDeleteTest(){
+ fun addAccountAndDetailAndDeleteTest() {
val accountModel = getDummyAccount()
addAccount(accountModel)
checkAccountDetail(accountModel)
deleteAccount(accountModel)
}
- private fun addAccount(accountModel: AccountModel){
+ private fun addAccount(accountModel: AccountModel) {
// Navigate to add screen
onView(withId(R.id.btnAdd)).perform(click())
@@ -90,9 +78,7 @@ class DashboardActivityTest {
onView(withText(accountModel.username)).check(matches(isDisplayed()))
}
-
-
- private fun checkAccountDetail(accountModel: AccountModel){
+ private fun checkAccountDetail(accountModel: AccountModel) {
// Navigate to account detail
onView(withText(accountModel.username)).perform(click())
@@ -109,10 +95,9 @@ class DashboardActivityTest {
onView(withId(R.id.etWebsite)).check(matches(withText(accountModel.password)))
onView(withId(R.id.etNotes)).check(matches(withText(accountModel.notes)))
-
}
- private fun deleteAccount(accountModel: AccountModel){
+ private fun deleteAccount(accountModel: AccountModel) {
// delete account
onView(withId(R.id.action_delete)).perform(click())
@@ -121,8 +106,4 @@ class DashboardActivityTest {
// is not showing in listing
onView(withText(accountModel.username)).check(doesNotExist())
}
-
-
-
-
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt b/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt
index 0fc2525b..e5c7bc40 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt
@@ -6,6 +6,7 @@ import android.util.Log
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import com.yogeshpaliyal.keypass.ui.CrashActivity
+import com.google.android.material.color.DynamicColors
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
import kotlin.system.exitProcess
@@ -31,6 +32,8 @@ class MyApplication : Application(), Configuration.Provider {
startActivity(intent)
exitProcess(1)
}
+
+ DynamicColors.applyToActivitiesIfAvailable(this)
}
override fun getWorkManagerConfiguration(): Configuration {
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/data/MyAccountModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/data/MyAccountModel.kt
new file mode 100644
index 00000000..7c644481
--- /dev/null
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/data/MyAccountModel.kt
@@ -0,0 +1,36 @@
+package com.yogeshpaliyal.keypass.data
+
+import com.google.gson.Gson
+import com.yogeshpaliyal.common.data.AccountModel
+import com.yogeshpaliyal.keypass.R
+import com.yogeshpaliyal.keypass.constants.AccountType
+import com.yogeshpaliyal.universalAdapter.listener.UniversalViewType
+import com.yogeshpaliyal.universalAdapter.model.BaseDiffUtil
+
+class MyAccountModel : AccountModel(), BaseDiffUtil, UniversalViewType {
+ override fun getDiffId(): Any? {
+ return id
+ }
+
+ override fun getDiffBody(): Any? {
+ return if (type == AccountType.TOTP) {
+ super.getDiffBody()
+ } else {
+ Gson().toJson(this)
+ }
+ }
+
+ override fun getLayoutId(): Int = if (type == AccountType.TOTP) R.layout.item_totp else R.layout.item_accounts
+
+ fun map(accountModel: AccountModel) {
+ this.id = accountModel.id
+ this.title = accountModel.title
+ this.uniqueId = accountModel.uniqueId
+ this.username = accountModel.username
+ this.password = accountModel.password
+ this.site = accountModel.site
+ this.notes = accountModel.notes
+ this.tags = accountModel.tags
+ this.type = accountModel.type
+ }
+}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/data/TOtpModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/data/TOtpModel.kt
deleted file mode 100644
index 6a90c3b4..00000000
--- a/app/src/main/java/com/yogeshpaliyal/keypass/data/TOtpModel.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.yogeshpaliyal.keypass.data
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import com.google.gson.annotations.Expose
-import com.google.gson.annotations.SerializedName
-import com.yogeshpaliyal.keypass.R
-import com.yogeshpaliyal.universal_adapter.listener.UniversalViewType
-import com.yogeshpaliyal.universal_adapter.model.BaseDiffUtil
-
-@Entity(tableName = "totps")
-data class TOtpModel(
- @PrimaryKey(autoGenerate = true)
- @ColumnInfo(name = "id")
- @SerializedName("id")
- var id: Long? = null,
-
- @ColumnInfo(name = "unique_id")
- @SerializedName("unique_id")
- var uniqueId: String? = null,
-
- @Expose
- @SerializedName("account_name")
- val accountName: String? = null
-
-) : BaseDiffUtil, UniversalViewType {
- override fun getLayoutId() = R.layout.item_totp
-}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPActivity.kt
index 274488e7..c68c1ab8 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPActivity.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPActivity.kt
@@ -12,9 +12,9 @@ import androidx.lifecycle.Observer
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.google.zxing.integration.android.IntentIntegrator
+import com.yogeshpaliyal.common.utils.TOTPHelper
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.ActivityAddTotpactivityBinding
-import com.yogeshpaliyal.keypass.utils.TOTPHelper
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -85,7 +85,7 @@ class AddTOTPActivity : AppCompatActivity() {
}
}
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (accountId != null)
menuInflater.inflate(R.menu.menu_delete, menu)
return super.onCreateOptionsMenu(menu)
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPViewModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPViewModel.kt
index 285be56e..d85efa41 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPViewModel.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/AddTOTPViewModel.kt
@@ -4,18 +4,17 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.yogeshpaliyal.keypass.AppDatabase
+import com.yogeshpaliyal.common.data.AccountModel
+import com.yogeshpaliyal.common.utils.Event
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.constants.AccountType
-import com.yogeshpaliyal.keypass.data.AccountModel
-import com.yogeshpaliyal.keypass.utils.Event
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
-class AddTOTPViewModel @Inject constructor(private val appDatabase: AppDatabase) : ViewModel() {
+class AddTOTPViewModel @Inject constructor(private val appDatabase: com.yogeshpaliyal.common.AppDatabase) : ViewModel() {
private val _goBack = MutableLiveData>()
val goBack: LiveData> = _goBack
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt
index 3654a100..a0ef03f5 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt
@@ -12,7 +12,8 @@ import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.yogeshpaliyal.keypass.AppDatabase
+import com.yogeshpaliyal.common.AppDatabase
+import com.yogeshpaliyal.common.utils.*
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.BackupActivityBinding
import com.yogeshpaliyal.keypass.databinding.LayoutBackupKeypharseBinding
@@ -60,7 +61,7 @@ class BackupActivity : AppCompatActivity() {
lateinit var sp: SharedPreferences
@Inject
- lateinit var appDb: AppDatabase
+ lateinit var appDb: com.yogeshpaliyal.common.AppDatabase
private val CHOOSE_BACKUPS_LOCATION_REQUEST_CODE = 26212
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt
index ba64df2f..b7f73214 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt
@@ -8,9 +8,9 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.yogeshpaliyal.common.utils.PasswordGenerator
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.FragmentDetailBinding
-import com.yogeshpaliyal.keypass.utils.PasswordGenerator
import dagger.hilt.android.AndroidEntryPoint
/*
@@ -107,7 +107,7 @@ class DetailActivity : AppCompatActivity() {
}.show()
}
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.bottom_app_bar_detail, menu)
return super.onCreateOptionsMenu(menu)
}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt
index 22f8233e..d77e1014 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt
@@ -6,9 +6,8 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
-import com.yogeshpaliyal.keypass.AppDatabase
-import com.yogeshpaliyal.keypass.data.AccountModel
-import com.yogeshpaliyal.keypass.worker.executeAutoBackup
+import com.yogeshpaliyal.common.data.AccountModel
+import com.yogeshpaliyal.common.worker.executeAutoBackup
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -22,7 +21,7 @@ import javax.inject.Inject
* created on 31-01-2021 11:52
*/
@HiltViewModel
-class DetailViewModel @Inject constructor(val app: Application, val appDb: AppDatabase, val sp: SharedPreferences) : AndroidViewModel(app) {
+class DetailViewModel @Inject constructor(val app: Application, val appDb: com.yogeshpaliyal.common.AppDatabase, val sp: SharedPreferences) : AndroidViewModel(app) {
private val _accountModel by lazy { MutableLiveData() }
val accountModel: LiveData = _accountModel
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/generate/GeneratePasswordActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/generate/GeneratePasswordActivity.kt
index d5d59037..e44e8b4a 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/generate/GeneratePasswordActivity.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/generate/GeneratePasswordActivity.kt
@@ -5,10 +5,9 @@ import android.content.ClipboardManager
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.content.getSystemService
+import com.yogeshpaliyal.common.utils.PasswordGenerator
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.ActivityGeneratePasswordBinding
-import com.yogeshpaliyal.keypass.utils.PasswordGenerator
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -35,12 +34,14 @@ class GeneratePasswordActivity : AppCompatActivity() {
private fun generatePassword() {
val password = PasswordGenerator(
- binding.sliderPasswordLength.value.toInt(), binding.cbCapAlphabets.isChecked,
- binding.cbLowerAlphabets.isChecked,
- binding.cbSymbols.isChecked,
- binding.cbNumbers.isChecked
+ length = binding.sliderPasswordLength.value.toInt(),
+ includeUpperCaseLetters = binding.cbCapAlphabets.isChecked,
+ includeLowerCaseLetters = binding.cbLowerAlphabets.isChecked,
+ includeSymbols = binding.cbSymbols.isChecked,
+ includeNumbers = binding.cbNumbers.isChecked
).generatePassword()
binding.etPassword.setText(password)
+ binding.etPassword.setSelection(password.length)
}
}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/DashboardViewModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/DashboardViewModel.kt
index ec749f06..d4f9d699 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/DashboardViewModel.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/DashboardViewModel.kt
@@ -2,8 +2,8 @@ package com.yogeshpaliyal.keypass.ui.home
import android.app.Application
import androidx.lifecycle.*
-import com.yogeshpaliyal.keypass.AppDatabase
-import com.yogeshpaliyal.keypass.data.AccountModel
+import com.yogeshpaliyal.common.AppDatabase
+import com.yogeshpaliyal.common.data.AccountModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@@ -17,7 +17,7 @@ import javax.inject.Inject
* created on 30-01-2021 23:02
*/
@HiltViewModel
-class DashboardViewModel @Inject constructor(application: Application, val appDb: AppDatabase) :
+class DashboardViewModel @Inject constructor(application: Application, val appDb: com.yogeshpaliyal.common.AppDatabase) :
AndroidViewModel(application) {
val keyword by lazy {
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/HomeFragment.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/HomeFragment.kt
index 349082ff..30248aac 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/HomeFragment.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/home/HomeFragment.kt
@@ -11,16 +11,17 @@ import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
+import com.yogeshpaliyal.common.data.AccountModel
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.constants.AccountType
-import com.yogeshpaliyal.keypass.data.AccountModel
+import com.yogeshpaliyal.keypass.data.MyAccountModel
import com.yogeshpaliyal.keypass.databinding.FragmentHomeBinding
import com.yogeshpaliyal.keypass.listener.AccountsClickListener
import com.yogeshpaliyal.keypass.ui.addTOTP.AddTOTPActivity
import com.yogeshpaliyal.keypass.ui.detail.DetailActivity
-import com.yogeshpaliyal.universal_adapter.adapter.UniversalAdapterViewType
-import com.yogeshpaliyal.universal_adapter.adapter.UniversalRecyclerAdapter
-import com.yogeshpaliyal.universal_adapter.utils.Resource
+import com.yogeshpaliyal.universalAdapter.adapter.UniversalAdapterViewType
+import com.yogeshpaliyal.universalAdapter.adapter.UniversalRecyclerAdapter
+import com.yogeshpaliyal.universalAdapter.utils.Resource
import dagger.hilt.android.AndroidEntryPoint
/*
@@ -38,7 +39,7 @@ class HomeFragment : Fragment() {
}
private val mAdapter by lazy {
- UniversalRecyclerAdapter.Builder(
+ UniversalRecyclerAdapter.Builder(
this,
content = UniversalAdapterViewType.Content(
R.layout.item_accounts,
@@ -65,7 +66,8 @@ class HomeFragment : Fragment() {
)
val clip = ClipData.newPlainText("KeyPass", model.password)
clipboard?.setPrimaryClip(clip)
- Toast.makeText(context, getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show()
+ Toast.makeText(context, getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT)
+ .show()
}
}
@@ -79,8 +81,10 @@ class HomeFragment : Fragment() {
}
private val observer = Observer> {
- val newList = it.map {
- it.copy(id = it.id, title = it.title, uniqueId = it.uniqueId, username = it.username, it.password, it.site, it.notes, it.tags, it.type)
+ val newList = it.map { accountModel ->
+ MyAccountModel().also {
+ it.map(accountModel)
+ }
}
mAdapter.updateData(Resource.success(ArrayList(newList)))
}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavDrawerFragment.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavDrawerFragment.kt
index 176eba20..8bf9bb17 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavDrawerFragment.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavDrawerFragment.kt
@@ -8,7 +8,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.activity.OnBackPressedCallback
-import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.observe
@@ -19,9 +18,9 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HALF_EX
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
import com.google.android.material.bottomsheet.BottomSheetBehavior.from
import com.google.android.material.shape.MaterialShapeDrawable
+import com.yogeshpaliyal.common.utils.themeColor
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.FragmentBottomNavDrawerBinding
-import com.yogeshpaliyal.keypass.utils.themeColor
import dagger.hilt.android.AndroidEntryPoint
import kotlin.LazyThreadSafetyMode.NONE
@@ -55,7 +54,7 @@ class BottomNavDrawerFragment :
0
).apply {
fillColor = ColorStateList.valueOf(
- foregroundContext.themeColor(R.attr.colorPrimarySurface)
+ foregroundContext.themeColor(R.attr.colorSurface)
)
elevation = resources.getDimension(R.dimen.plane_16)
shadowCompatibilityMode = MaterialShapeDrawable.SHADOW_COMPAT_MODE_NEVER
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavViewModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavViewModel.kt
index 87420e40..47446e57 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavViewModel.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavViewModel.kt
@@ -5,7 +5,7 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
-import com.yogeshpaliyal.keypass.AppDatabase
+import com.yogeshpaliyal.common.AppDatabase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@@ -18,7 +18,7 @@ import javax.inject.Inject
* created on 31-01-2021 14:11
*/
@HiltViewModel
-class BottomNavViewModel @Inject constructor (application: Application, val appDb: AppDatabase) : AndroidViewModel(application) {
+class BottomNavViewModel @Inject constructor (application: Application, val appDb: com.yogeshpaliyal.common.AppDatabase) : AndroidViewModel(application) {
private val _navigationList: MutableLiveData> = MutableLiveData()
private val tagsDb = appDb.getDao().getTags()
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavigationDrawerCallback.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavigationDrawerCallback.kt
index c3aad646..a8cc77a3 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavigationDrawerCallback.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/BottomNavigationDrawerCallback.kt
@@ -5,7 +5,7 @@ import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.R
import com.google.android.material.bottomsheet.BottomSheetBehavior
-import com.yogeshpaliyal.keypass.utils.normalize
+import com.yogeshpaliyal.common.utils.normalize
import kotlin.math.max
/**
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/NavigationModelItem.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/NavigationModelItem.kt
index 69d5cc6e..4d52db3b 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/NavigationModelItem.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/NavigationModelItem.kt
@@ -3,7 +3,7 @@ package com.yogeshpaliyal.keypass.ui.nav
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.recyclerview.widget.DiffUtil
-import com.yogeshpaliyal.keypass.data.StringDiffUtil
+import com.yogeshpaliyal.common.data.StringDiffUtil
/**
* A sealed class which encapsulates all objects [NavigationAdapter] is able to display.
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/OnSlideAction.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/OnSlideAction.kt
index 5ce9571d..14da6462 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/OnSlideAction.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/OnSlideAction.kt
@@ -7,8 +7,8 @@ import androidx.core.view.marginTop
import androidx.core.view.updatePadding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.shape.MaterialShapeDrawable
+import com.yogeshpaliyal.common.utils.normalize
import com.yogeshpaliyal.keypass.R
-import com.yogeshpaliyal.keypass.utils.normalize
/**
* An action to be performed when a bottom sheet's slide offset is changed.
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/settings/MySettingsFragment.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/settings/MySettingsFragment.kt
index 6adb2129..0c9ab9b2 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/settings/MySettingsFragment.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/settings/MySettingsFragment.kt
@@ -1,7 +1,10 @@
package com.yogeshpaliyal.keypass.ui.settings
import android.app.Activity
-import android.content.*
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Intent
+import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
@@ -11,15 +14,14 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.yogeshpaliyal.keypass.AppDatabase
+import com.yogeshpaliyal.common.db_helper.createBackup
+import com.yogeshpaliyal.common.db_helper.restoreBackup
+import com.yogeshpaliyal.common.utils.*
import com.yogeshpaliyal.keypass.BuildConfig
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.databinding.LayoutBackupKeypharseBinding
import com.yogeshpaliyal.keypass.databinding.LayoutRestoreKeypharseBinding
-import com.yogeshpaliyal.keypass.db_helper.createBackup
-import com.yogeshpaliyal.keypass.db_helper.restoreBackup
import com.yogeshpaliyal.keypass.ui.backup.BackupActivity
-import com.yogeshpaliyal.keypass.utils.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -30,7 +32,7 @@ class MySettingsFragment : PreferenceFragmentCompat() {
private val CHOOSE_RESTORE_FILE_REQUEST_CODE = 26213
@Inject
- lateinit var appDb: AppDatabase
+ lateinit var appDb: com.yogeshpaliyal.common.AppDatabase
@Inject
lateinit var sp: SharedPreferences
@@ -42,7 +44,10 @@ class MySettingsFragment : PreferenceFragmentCompat() {
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
when (preference?.key) {
"feedback" -> {
- context?.email(getString(R.string.feedback_to_keypass), "yogeshpaliyal.foss@gmail.com")
+ context?.email(
+ getString(R.string.feedback_to_keypass),
+ "yogeshpaliyal.foss@gmail.com"
+ )
return true
}
@@ -144,7 +149,11 @@ class MySettingsFragment : PreferenceFragmentCompat() {
"Restore"
) { dialog, which ->
lifecycleScope.launch {
- val result = appDb.restoreBackup(binding.etKeyPhrase.text.toString(), contentResolver, selectedFile)
+ val result = appDb.restoreBackup(
+ binding.etKeyPhrase.text.toString(),
+ contentResolver,
+ selectedFile
+ )
if (result) {
dialog?.dismiss()
Toast.makeText(
@@ -187,9 +196,16 @@ class MySettingsFragment : PreferenceFragmentCompat() {
binding.txtCode.setOnClickListener {
val clipboard =
getSystemService(requireContext(), ClipboardManager::class.java)
- val clip = ClipData.newPlainText(getString(R.string.app_name), binding.txtCode.text)
+ val clip = ClipData.newPlainText(
+ getString(R.string.app_name),
+ binding.txtCode.text
+ )
clipboard?.setPrimaryClip(clip)
- Toast.makeText(context, getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show()
+ Toast.makeText(
+ context,
+ getString(R.string.copied_to_clipboard),
+ Toast.LENGTH_SHORT
+ ).show()
}
MaterialAlertDialogBuilder(requireContext()).setView(binding.root)
.setPositiveButton(
@@ -198,7 +214,11 @@ class MySettingsFragment : PreferenceFragmentCompat() {
dialog?.dismiss()
}.show()
} else {
- Toast.makeText(context, getString(R.string.backup_completed), Toast.LENGTH_SHORT).show()
+ Toast.makeText(
+ context,
+ getString(R.string.backup_completed),
+ Toast.LENGTH_SHORT
+ ).show()
}
}
}
diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/utils/BindingAdapter.kt b/app/src/main/java/com/yogeshpaliyal/keypass/utils/BindingAdapter.kt
index f8ae92fb..da4688da 100644
--- a/app/src/main/java/com/yogeshpaliyal/keypass/utils/BindingAdapter.kt
+++ b/app/src/main/java/com/yogeshpaliyal/keypass/utils/BindingAdapter.kt
@@ -27,6 +27,7 @@ import androidx.annotation.DrawableRes
import androidx.core.view.updateLayoutParams
import androidx.databinding.BindingAdapter
import com.google.android.material.elevation.ElevationOverlayProvider
+import com.yogeshpaliyal.common.utils.getDrawableOrNull
@BindingAdapter(
"popupElevationOverlay"
diff --git a/app/src/main/res/color/color_navigation_drawer_menu_item.xml b/app/src/main/res/color/color_navigation_drawer_menu_item.xml
index e81edf7e..c714257d 100644
--- a/app/src/main/res/color/color_navigation_drawer_menu_item.xml
+++ b/app/src/main/res/color/color_navigation_drawer_menu_item.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/color_on_primary_surface_divider.xml b/app/src/main/res/color/color_on_primary_surface_divider.xml
index 90ab853a..3e4b2b99 100644
--- a/app/src/main/res/color/color_on_primary_surface_divider.xml
+++ b/app/src/main/res/color/color_on_primary_surface_divider.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_undraw_empty_street_sfxm.xml b/app/src/main/res/drawable/ic_undraw_empty_street_sfxm.xml
index 2dc6f0a6..9dc244ee 100644
--- a/app/src/main/res/drawable/ic_undraw_empty_street_sfxm.xml
+++ b/app/src/main/res/drawable/ic_undraw_empty_street_sfxm.xml
@@ -14,10 +14,10 @@
android:fillColor="#e6e6e6"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
@@ -41,10 +41,10 @@
android:fillColor="#e6e6e6"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
@@ -68,10 +68,10 @@
android:fillColor="#e6e6e6"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
@@ -86,119 +86,119 @@
android:fillColor="#fff"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorTertiaryContainer"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
+ android:fillColor="?attr/colorPrimary"/>
diff --git a/app/src/main/res/layout/activity_dashboard.xml b/app/src/main/res/layout/activity_dashboard.xml
index 23ebb227..7629c10f 100644
--- a/app/src/main/res/layout/activity_dashboard.xml
+++ b/app/src/main/res/layout/activity_dashboard.xml
@@ -93,7 +93,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottomAppBar"
- app:srcCompat="@drawable/asl_add_save" />
+ app:srcCompat="@drawable/asl_add_save"
+ app:shapeAppearanceOverlay="@style/ShapeAppearance.KeyPass.Cirle"/>
diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml
index 48c8e1fd..fd769a05 100644
--- a/app/src/main/res/layout/fragment_detail.xml
+++ b/app/src/main/res/layout/fragment_detail.xml
@@ -1,210 +1,207 @@
+
+
+ type="com.yogeshpaliyal.common.data.AccountModel" />
-
-
-
+ android:layout_height="match_parent">
-
-
+ android:layout_height="match_parent"
+ android:fillViewport="true"
+ android:paddingHorizontal="@dimen/grid_0_5"
+ android:paddingVertical="@dimen/grid_0_5"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="wrap_content">
-
+
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
-
-
+
-
+
-
+
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_accounts.xml b/app/src/main/res/layout/item_accounts.xml
index 27af0eae..91dd2df6 100644
--- a/app/src/main/res/layout/item_accounts.xml
+++ b/app/src/main/res/layout/item_accounts.xml
@@ -3,14 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
-
+
+ type="MyAccountModel" />
+ type="com.yogeshpaliyal.keypass.listener.AccountsClickListener<MyAccountModel>" />
diff --git a/app/src/main/res/layout/item_totp.xml b/app/src/main/res/layout/item_totp.xml
index 6be030f9..c358a571 100644
--- a/app/src/main/res/layout/item_totp.xml
+++ b/app/src/main/res/layout/item_totp.xml
@@ -3,14 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
-
+
+ type="MyAccountModel" />
+ type="com.yogeshpaliyal.keypass.listener.AccountsClickListener<MyAccountModel>" />
+ android:layout_marginHorizontal="@dimen/grid_0_5"
+ app:layout_constraintBottom_toBottomOf="parent">
diff --git a/app/src/main/res/layout/nav_email_folder_item_layout.xml b/app/src/main/res/layout/nav_email_folder_item_layout.xml
index 5df2cb6c..ceee112f 100644
--- a/app/src/main/res/layout/nav_email_folder_item_layout.xml
+++ b/app/src/main/res/layout/nav_email_folder_item_layout.xml
@@ -33,16 +33,15 @@
android:layout_height="@dimen/navigation_drawer_menu_item_height"
android:paddingLeft="@dimen/grid_4"
android:paddingRight="@dimen/grid_4"
- android:background="?attr/selectableItemBackground"
android:gravity="center_vertical|start"
android:onClick="@{() -> navListener.onNavEmailFolderClicked(navEmailFolder)}"
android:ellipsize="end"
android:lines="1"
android:text="@{navEmailFolder.category}"
- android:textColor="@color/color_on_primary_surface_emphasis_medium"
+ android:textColor="?attr/colorOnSurface"
android:textAppearance="?attr/textAppearanceSubtitle1"
app:drawableStartCompat="@drawable/ic_twotone_folder"
- app:drawableTint="@color/color_on_primary_surface_emphasis_medium"
+ app:drawableTint="?attr/colorOnSurface"
android:drawablePadding="@dimen/grid_4"
tools:text="Pine Elementary" />
diff --git a/app/src/main/res/layout/nav_menu_item_layout.xml b/app/src/main/res/layout/nav_menu_item_layout.xml
index 373630ae..e4b2714e 100644
--- a/app/src/main/res/layout/nav_menu_item_layout.xml
+++ b/app/src/main/res/layout/nav_menu_item_layout.xml
@@ -32,7 +32,6 @@
android:layout_height="@dimen/navigation_drawer_menu_item_height"
android:paddingLeft="@dimen/grid_4"
android:paddingRight="@dimen/grid_4"
- android:background="?attr/selectableItemBackground"
android:gravity="center_vertical|start"
android:onClick="@{() -> navListener.onNavMenuItemClicked(navMenuItem)}"
android:ellipsize="end"
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index a6ed40ce..d54286e8 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,12 +1,16 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index a5bbce94..e90ed4cd 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,8 +1,10 @@
-
+
\ No newline at end of file
diff --git a/common/src/main/res/values/colors.xml b/common/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f8c6127d
--- /dev/null
+++ b/common/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml
new file mode 100644
index 00000000..aad35971
--- /dev/null
+++ b/common/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ common
+
\ No newline at end of file
diff --git a/common/src/main/res/values/themes.xml b/common/src/main/res/values/themes.xml
new file mode 100644
index 00000000..f4b31fd8
--- /dev/null
+++ b/common/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/common/src/test/java/com/yogeshpaliyal/common/ExampleUnitTest.kt b/common/src/test/java/com/yogeshpaliyal/common/ExampleUnitTest.kt
new file mode 100644
index 00000000..8f2ace3d
--- /dev/null
+++ b/common/src/test/java/com/yogeshpaliyal/common/ExampleUnitTest.kt
@@ -0,0 +1,16 @@
+package com.yogeshpaliyal.common
+
+import org.junit.Assert.*
+import org.junit.Test
+
+/**
+ * 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)
+ }
+}
diff --git a/fastlane/metadata/android/en-US/changelogs/1401.txt b/fastlane/metadata/android/en-US/changelogs/1401.txt
new file mode 100644
index 00000000..c9c92a01
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1401.txt
@@ -0,0 +1,2 @@
+Now supports Material YOU
+Crash fix in Generate password
\ No newline at end of file
diff --git a/keypasscompose/.gitignore b/keypasscompose/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/keypasscompose/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/keypasscompose/build.gradle b/keypasscompose/build.gradle
new file mode 100644
index 00000000..556e4e13
--- /dev/null
+++ b/keypasscompose/build.gradle
@@ -0,0 +1,68 @@
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
+
+android {
+ compileSdk 31
+
+ defaultConfig {
+ applicationId "com.yogeshpaliyal.keypasscompose"
+ minSdk 21
+ targetSdk 31
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ useIR = true
+ }
+ buildFeatures {
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion compose_version
+ kotlinCompilerVersion '1.5.21'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+ implementation project(":common")
+
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.appcompat:appcompat:1.4.0'
+ implementation 'com.google.android.material:material:1.6.0-alpha01'
+ implementation "androidx.compose.ui:ui:1.1.0-beta02"
+ implementation "androidx.compose.material:material:1.0.5"
+ implementation "androidx.compose.ui:ui-tooling-preview:1.0.5"
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
+ implementation 'androidx.activity:activity-compose:1.4.0'
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.0.5"
+ debugImplementation "androidx.compose.ui:ui-tooling:1.0.5"
+
+ implementation 'androidx.compose.material3:material3:1.0.0-alpha02'
+}
\ No newline at end of file
diff --git a/keypasscompose/proguard-rules.pro b/keypasscompose/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/keypasscompose/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/keypasscompose/src/androidTest/java/com/yogeshpaliyal/keypasscompose/ExampleInstrumentedTest.kt b/keypasscompose/src/androidTest/java/com/yogeshpaliyal/keypasscompose/ExampleInstrumentedTest.kt
new file mode 100644
index 00000000..74ce5d3e
--- /dev/null
+++ b/keypasscompose/src/androidTest/java/com/yogeshpaliyal/keypasscompose/ExampleInstrumentedTest.kt
@@ -0,0 +1,22 @@
+package com.yogeshpaliyal.keypasscompose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.*
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * 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.yogeshpaliyal.keypasscompose", appContext.packageName)
+ }
+}
diff --git a/keypasscompose/src/main/AndroidManifest.xml b/keypasscompose/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..be22dea9
--- /dev/null
+++ b/keypasscompose/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/MainActivity.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/MainActivity.kt
new file mode 100644
index 00000000..9156c16b
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/MainActivity.kt
@@ -0,0 +1,83 @@
+package com.yogeshpaliyal.keypasscompose
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.FabPosition
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Add
+import androidx.compose.material.icons.filled.Menu
+import androidx.compose.material.icons.filled.Star
+import androidx.compose.material3.*
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import com.yogeshpaliyal.keypasscompose.ui.theme.KeyPassTheme
+import com.yogeshpaliyal.keypasscompose.ui.theme.Material3BottomAppBar
+import com.yogeshpaliyal.keypasscompose.ui.theme.Material3Scaffold
+
+class MainActivity : ComponentActivity() {
+ @OptIn(ExperimentalMaterial3Api::class)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ KeyPassTheme {
+ // A surface container using the 'background' color from the theme
+ Surface(color = MaterialTheme.colorScheme.background) {
+ Material3Scaffold(
+ bottomBar = {
+ Material3BottomAppBar(cutoutShape = RoundedCornerShape(50)) {
+ IconButton(
+ onClick = {
+ /* doSomething() */
+ }
+ ) {
+ Icon(Icons.Filled.Menu, "")
+ }
+
+ Spacer(Modifier.weight(1f, true))
+ IconButton(
+ onClick = {
+ /* doSomething() */
+ }
+ ) {
+ Icon(Icons.Filled.Star, "")
+ }
+ }
+ },
+ floatingActionButton = {
+ FloatingActionButton(
+ onClick = {
+ },
+ contentColor = Color.White,
+ shape = RoundedCornerShape(50)
+ ) {
+ Icon(Icons.Filled.Add, "")
+ }
+ },
+ floatingActionButtonPosition = FabPosition.Center,
+ isFloatingActionButtonDocked = true
+ ) {
+ }
+ Greeting("Android")
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun Greeting(name: String) {
+ Text(text = "Hello $name!")
+}
+
+@Preview(showBackground = true)
+@Composable
+fun DefaultPreview() {
+ KeyPassTheme {
+ Greeting("Android")
+ }
+}
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Color.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Color.kt
new file mode 100644
index 00000000..5490a31b
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.yogeshpaliyal.keypasscompose.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Material3Components.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Material3Components.kt
new file mode 100644
index 00000000..fdb36f8d
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Material3Components.kt
@@ -0,0 +1,62 @@
+package com.yogeshpaliyal.keypasscompose.ui.theme
+
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.material.*
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.contentColorFor
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.unit.Dp
+
+@Composable
+fun Material3BottomAppBar(
+ modifier: Modifier = Modifier,
+ backgroundColor: Color = MaterialTheme.colorScheme.surface,
+ contentColor: Color = contentColorFor(backgroundColor),
+ cutoutShape: Shape? = null,
+ elevation: Dp = AppBarDefaults.BottomAppBarElevation,
+ contentPadding: PaddingValues = AppBarDefaults.ContentPadding,
+ content: @Composable RowScope.() -> Unit
+) {
+ BottomAppBar(
+ modifier,
+ backgroundColor,
+ contentColor,
+ cutoutShape,
+ elevation,
+ contentPadding,
+ content
+ )
+}
+
+@Composable
+fun Material3Scaffold(
+ modifier: Modifier = Modifier,
+ scaffoldState: ScaffoldState = rememberScaffoldState(),
+ topBar: @Composable () -> Unit = {},
+ bottomBar: @Composable () -> Unit = {},
+ snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
+ floatingActionButton: @Composable () -> Unit = {},
+ floatingActionButtonPosition: FabPosition = FabPosition.End,
+ isFloatingActionButtonDocked: Boolean = false,
+ drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
+ drawerGesturesEnabled: Boolean = true,
+ drawerShape: Shape = androidx.compose.material.MaterialTheme.shapes.large,
+ drawerElevation: Dp = DrawerDefaults.Elevation,
+ drawerBackgroundColor: Color = MaterialTheme.colorScheme.surface,
+ drawerContentColor: Color = contentColorFor(
+ drawerBackgroundColor
+ ),
+ drawerScrimColor: Color = DrawerDefaults.scrimColor,
+ backgroundColor: Color = MaterialTheme.colorScheme.background,
+ contentColor: Color = contentColorFor(
+ backgroundColor
+ ),
+ content: @Composable (PaddingValues) -> Unit
+) {
+ Scaffold(modifier, scaffoldState, topBar, bottomBar, snackbarHost, floatingActionButton, floatingActionButtonPosition, isFloatingActionButtonDocked, drawerContent, drawerGesturesEnabled, drawerShape, drawerElevation, drawerBackgroundColor, drawerContentColor, drawerScrimColor, backgroundColor, contentColor, content)
+}
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Shape.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Shape.kt
new file mode 100644
index 00000000..8a765e43
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Shape.kt
@@ -0,0 +1 @@
+package com.yogeshpaliyal.keypasscompose.ui.theme
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Theme.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Theme.kt
new file mode 100644
index 00000000..62879834
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Theme.kt
@@ -0,0 +1,43 @@
+package com.yogeshpaliyal.keypasscompose.ui.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
+
+private val DarkColorPalette = darkColorScheme(
+ primary = Purple200,
+ primaryContainer = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColorScheme(
+ primary = Purple500,
+ primaryContainer = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun KeyPassTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colorScheme = colors,
+ typography = Typography,
+ content = content
+ )
+}
diff --git a/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Type.kt b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Type.kt
new file mode 100644
index 00000000..b07440d3
--- /dev/null
+++ b/keypasscompose/src/main/java/com/yogeshpaliyal/keypasscompose/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.yogeshpaliyal.keypasscompose.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ bodyMedium = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
diff --git a/keypasscompose/src/main/res/drawable-v24/ic_launcher_foreground.xml b/keypasscompose/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..2b068d11
--- /dev/null
+++ b/keypasscompose/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/drawable/ic_launcher_background.xml b/keypasscompose/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..07d5da9c
--- /dev/null
+++ b/keypasscompose/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/keypasscompose/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher.webp b/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher.webp b/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher.webp b/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/keypasscompose/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/keypasscompose/src/main/res/values-night/themes.xml b/keypasscompose/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..082368cd
--- /dev/null
+++ b/keypasscompose/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/values/colors.xml b/keypasscompose/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f8c6127d
--- /dev/null
+++ b/keypasscompose/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/values/strings.xml b/keypasscompose/src/main/res/values/strings.xml
new file mode 100644
index 00000000..ade25ba3
--- /dev/null
+++ b/keypasscompose/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ KeyPass Compose
+
\ No newline at end of file
diff --git a/keypasscompose/src/main/res/values/themes.xml b/keypasscompose/src/main/res/values/themes.xml
new file mode 100644
index 00000000..f3ffd182
--- /dev/null
+++ b/keypasscompose/src/main/res/values/themes.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/keypasscompose/src/test/java/com/yogeshpaliyal/keypasscompose/ExampleUnitTest.kt b/keypasscompose/src/test/java/com/yogeshpaliyal/keypasscompose/ExampleUnitTest.kt
new file mode 100644
index 00000000..5393aaa5
--- /dev/null
+++ b/keypasscompose/src/test/java/com/yogeshpaliyal/keypasscompose/ExampleUnitTest.kt
@@ -0,0 +1,16 @@
+package com.yogeshpaliyal.keypasscompose
+
+import org.junit.Assert.*
+import org.junit.Test
+
+/**
+ * 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)
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index ba3e874a..89491b54 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,4 @@
include ':app'
-rootProject.name = "KeyPass"
\ No newline at end of file
+rootProject.name = "KeyPass"
+include ':common'
+include ':keypasscompose'
diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US
index 68b0d191..c9c92a01 100644
--- a/whatsnew/whatsnew-en-US
+++ b/whatsnew/whatsnew-en-US
@@ -1 +1,2 @@
-New Feature -> Time based OTP Added
\ No newline at end of file
+Now supports Material YOU
+Crash fix in Generate password
\ No newline at end of file