diff --git a/.idea/misc.xml b/.idea/misc.xml index ce927002..3e591463 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,13 +5,10 @@ - + - - - - + diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/constants/IntentKeys.kt b/app/src/main/java/com/yogeshpaliyal/keypass/constants/IntentKeys.kt new file mode 100644 index 00000000..fb89aca0 --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/keypass/constants/IntentKeys.kt @@ -0,0 +1,5 @@ +package com.yogeshpaliyal.keypass.constants + +object IntentKeys { + const val SCANNED_TEXT = "scanned_text" +} \ No newline at end of file diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/constants/RequestCodes.kt b/app/src/main/java/com/yogeshpaliyal/keypass/constants/RequestCodes.kt new file mode 100644 index 00000000..ff4e1ac1 --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/keypass/constants/RequestCodes.kt @@ -0,0 +1,5 @@ +package com.yogeshpaliyal.keypass.constants + +object RequestCodes { + const val SCANNER = 342 +} \ No newline at end of file diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt b/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt index b4c7201b..4e75d7bd 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt @@ -16,29 +16,29 @@ import kotlinx.coroutines.flow.Flow abstract class DbDao { @Insert(onConflict = OnConflictStrategy.REPLACE) - abstract fun insertOrUpdateAccount(accountModel: AccountModel) + abstract suspend fun insertOrUpdateAccount(vararg accountModel: AccountModel) @Insert(onConflict = OnConflictStrategy.REPLACE) - abstract fun insertOrUpdateAccount(accountModel: List) + abstract suspend fun insertOrUpdateAccount(accountModel: List) @Query("SELECT * FROM account ORDER BY title ASC") abstract fun getAllAccounts(): LiveData> @Query("SELECT * FROM account ORDER BY title ASC") - abstract fun getAllAccountsList(): List + abstract suspend fun getAllAccountsList(): List @Query("SELECT * FROM account WHERE CASE WHEN :tag IS NOT NULL THEN tags = :tag ELSE 1 END AND ((username LIKE '%'||:query||'%' ) OR (title LIKE '%'||:query||'%' ) OR (notes LIKE '%'||:query||'%' )) ORDER BY title ASC") abstract fun getAllAccounts(query: String?, tag: String?): LiveData> @Query("SELECT * FROM account WHERE id = :id") - abstract fun getAccount(id: Long?): AccountModel? + abstract suspend fun getAccount(id: Long?): AccountModel? @Query("SELECT DISTINCT tags FROM account") abstract fun getTags(): Flow> @Query("DELETE from account WHERE id = :id") - abstract fun deleteAccount(id: Long?) + abstract suspend fun deleteAccount(id: Long?) @Delete - abstract fun deleteAccount(accountModel: AccountModel) + abstract suspend fun deleteAccount(accountModel: AccountModel) } 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 2a8cc4bf..6b005486 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 @@ -5,7 +5,11 @@ import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.viewModels +import androidx.lifecycle.Observer +import com.google.android.material.snackbar.Snackbar import com.yogeshpaliyal.keypass.R +import com.yogeshpaliyal.keypass.constants.IntentKeys +import com.yogeshpaliyal.keypass.constants.RequestCodes import com.yogeshpaliyal.keypass.databinding.ActivityAddTotpactivityBinding import dagger.hilt.android.AndroidEntryPoint @@ -41,5 +45,18 @@ class AddTOTPActivity : AppCompatActivity() { ScannerActivity.start(this) } + mViewModel.error.observe(this, Observer { + it?.getContentIfNotHandled()?.let { + Snackbar.make(binding.root, it, Snackbar.LENGTH_SHORT).show() + } + }) + + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == RequestCodes.SCANNER && resultCode == RESULT_OK){ + mViewModel.setSecretKey(data?.extras?.getString(IntentKeys.SCANNED_TEXT) ?: "") + } } } \ No newline at end of file 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 4fb4f814..fd71fd4d 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 @@ -1,10 +1,53 @@ package com.yogeshpaliyal.keypass.ui.addTOTP +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.yogeshpaliyal.keypass.AppDatabase +import com.yogeshpaliyal.keypass.R +import com.yogeshpaliyal.keypass.data.AccountModel +import com.yogeshpaliyal.keypass.utils.Event import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class AddTOTPViewModel @Inject constructor(): ViewModel() { +class AddTOTPViewModel @Inject constructor(private val appDatabase: AppDatabase): ViewModel() { + + + private val _goBack = MutableLiveData>() + val goBack : LiveData> = _goBack + + private val _error = MutableLiveData>() + val error : LiveData> = _error + + val secretKey = MutableLiveData("") + + val accountName = MutableLiveData("") + + fun saveAccount(){ + viewModelScope.launch { + val secretKey = secretKey.value + val accountName = accountName.value + + if (accountName.isNullOrEmpty()){ + _error.postValue(Event(R.string.alert_black_secret_key)) + return@launch + } + + if (accountName.isNullOrEmpty()){ + _error.postValue(Event(R.string.alert_black_secret_key)) + return@launch + } + + val accountModel = AccountModel(password = secretKey, title = accountName) + appDatabase.getDao().insertOrUpdateAccount(accountModel) + } + } + + fun setSecretKey(secretKey: String){ + this.secretKey.value = secretKey + } } \ No newline at end of file diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/ScannerActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/ScannerActivity.kt index 9c1d951d..8cca71f0 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/ScannerActivity.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/addTOTP/ScannerActivity.kt @@ -1,6 +1,7 @@ package com.yogeshpaliyal.keypass.ui.addTOTP import android.Manifest +import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -11,6 +12,8 @@ import androidx.appcompat.app.AppCompatActivity import com.budiyev.android.codescanner.CodeScanner import com.budiyev.android.codescanner.DecodeCallback import com.budiyev.android.codescanner.ErrorCallback +import com.yogeshpaliyal.keypass.constants.IntentKeys +import com.yogeshpaliyal.keypass.constants.RequestCodes import com.yogeshpaliyal.keypass.databinding.ActivityScannerBinding import dagger.hilt.android.AndroidEntryPoint @@ -25,9 +28,9 @@ class ScannerActivity : AppCompatActivity() { companion object{ @JvmStatic - fun start(context: Context) { - val starter = Intent(context, ScannerActivity::class.java) - context.startActivity(starter) + fun start(activity: Activity) { + val starter = Intent(activity, ScannerActivity::class.java) + activity.startActivityForResult(starter,RequestCodes.SCANNER) } } @@ -50,17 +53,21 @@ class ScannerActivity : AppCompatActivity() { } else { codeScanner?.startPreview() // Callbacks - codeScanner?.decodeCallback = DecodeCallback { + codeScanner?.decodeCallback = DecodeCallback { result -> runOnUiThread { - Toast.makeText(this, "Scan result: ${it.text}", Toast.LENGTH_LONG).show() + setResult(RESULT_OK, Intent().also { + it.putExtra(IntentKeys.SCANNED_TEXT, result.text) + }) + finish() + //Toast.makeText(this, "Scan result: ${it.text}", Toast.LENGTH_LONG).show() } } codeScanner?.errorCallback = ErrorCallback { // or ErrorCallback.SUPPRESS runOnUiThread { - Toast.makeText( + /* Toast.makeText( this, "Camera initialization error: ${it.message}", Toast.LENGTH_LONG - ).show() + ).show()*/ } } } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivity.kt index 4b32d2e0..c600d174 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivity.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivity.kt @@ -40,7 +40,7 @@ class DashboardActivity : private val mViewModel by viewModels() - val currentNavigationFragment: Fragment? + private val currentNavigationFragment: Fragment? get() = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) ?.childFragmentManager ?.fragments diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/utils/Event.kt b/app/src/main/java/com/yogeshpaliyal/keypass/utils/Event.kt new file mode 100644 index 00000000..93bf840a --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/keypass/utils/Event.kt @@ -0,0 +1,27 @@ +package com.yogeshpaliyal.keypass.utils + +/*Used as a wrapper for data that is exposed via a LiveData that represents an + event.*/ + +open class Event(private val content: T) { + + var hasBeenHandled = false + private set // Allow external read but not write + + /** + * Returns the content and prevents its use again. + */ + fun getContentIfNotHandled(): T? { + return if (hasBeenHandled) { + null + } else { + hasBeenHandled = true + content + } + } + + /** + * Returns the content, even if it's already been handled. + */ + fun peekContent(): T = content +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_totpactivity.xml b/app/src/main/res/layout/activity_add_totpactivity.xml index 8b734ad1..56a81d70 100644 --- a/app/src/main/res/layout/activity_add_totpactivity.xml +++ b/app/src/main/res/layout/activity_add_totpactivity.xml @@ -41,6 +41,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Secret Key" + android:text="@{mViewModel.secretKey}" android:id="@+id/etSecretKey"/> @@ -58,6 +59,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/account_name" + android:text="@{mViewModel.accountName}" android:id="@+id/etAccount"/> @@ -69,6 +71,8 @@ app:layout_constraintBottom_toBottomOf="parent" android:layout_margin="@dimen/grid_2" android:text="Save" + android:id="@+id/btnSave" + android:onClick="@{()->mViewModel.saveAccount()}" app:icon="@drawable/ic_round_done_24" android:textColor="?attr/colorOnSecondary"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f13198c5..8d74ecac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,4 +64,6 @@ Enabled Override Auto Backup File Scanner + Please enter secret key + Please enter account name \ No newline at end of file