- Update the MaterialDialogs library version.
- Add the functionality to the Settings BrainKey's View & Show button. It first fetches the brainkey from the authorities db table and then shows it in a custom MaterialDialog so that the user can view and copy it.
This commit is contained in:
parent
f45d9055c3
commit
8f0026c205
8 changed files with 112 additions and 4 deletions
|
@ -59,7 +59,7 @@ dependencies {
|
|||
implementation 'com.moldedbits.r2d2:r2d2:1.0.1'
|
||||
implementation 'com.google.zxing:core:3.3.1'
|
||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||
implementation 'com.afollestad.material-dialogs:core:2.0.0-rc1'
|
||||
implementation 'com.afollestad.material-dialogs:core:2.0.0-rc3'
|
||||
|
||||
// Android Debug Database
|
||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
|
||||
|
|
|
@ -39,14 +39,19 @@ class MainActivity : ConnectedActivity() {
|
|||
val host: NavHostFragment = supportFragmentManager
|
||||
.findFragmentById(R.id.navHostFragment) as NavHostFragment? ?: return
|
||||
|
||||
// Set up Action Bar
|
||||
// Set up Action Bar with Navigation's controller
|
||||
val navController = host.navController
|
||||
|
||||
appBarConfiguration = AppBarConfiguration(navController.graph)
|
||||
|
||||
// Sets up the ActionBar with the navigation controller so that it automatically responds to clicks on toolbar
|
||||
// menu items and shows the up navigation button on all fragments except home (Balances)
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
|
||||
mHandler = Handler()
|
||||
|
||||
// When this runnable finishes it first verifies if the auto close feature is enabled and if it is then it
|
||||
// closes the app, if not then it just restarts the Handler (timer)
|
||||
mRunnable = Runnable {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false))
|
||||
|
@ -57,11 +62,17 @@ class MainActivity : ConnectedActivity() {
|
|||
startHandler()
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts the Handler (timer) each time there is user's interaction
|
||||
*/
|
||||
override fun onUserInteraction() {
|
||||
super.onUserInteraction()
|
||||
restartHandler()
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops and then restarts the Handler
|
||||
*/
|
||||
private fun restartHandler() {
|
||||
stopHandler()
|
||||
startHandler()
|
||||
|
|
|
@ -12,6 +12,9 @@ interface AuthorityDao {
|
|||
@Insert
|
||||
fun insert(authority: Authority)
|
||||
|
||||
@Query("SELECT * FROM authorities WHERE user_id=:userId LIMIT 1")
|
||||
fun get(userId: String): Single<Authority>
|
||||
|
||||
@Query("SELECT * FROM authorities")
|
||||
fun getAll(): LiveData<List<Authority>>
|
||||
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
package cy.agorise.bitsybitshareswallet.fragments
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context.CLIPBOARD_SERVICE
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.customview.customView
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import cy.agorise.bitsybitshareswallet.utils.CryptoUtils
|
||||
import cy.agorise.graphenej.BrainKey
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.fragment_settings.*
|
||||
|
||||
class SettingsFragment : Fragment() {
|
||||
private val TAG = this.javaClass.simpleName
|
||||
|
||||
private var mDisposables = CompositeDisposable()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -28,8 +42,14 @@ class SettingsFragment : Fragment() {
|
|||
initAutoCloseSwitch()
|
||||
|
||||
initNightModeSwitch()
|
||||
|
||||
btnViewBrainKey.setOnClickListener { getBrainkey(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the relevant preference from the SharedPreferences and configures the corresponding switch accordingly,
|
||||
* and adds a listener to the said switch to store the preference in case the user changes it.
|
||||
*/
|
||||
private fun initAutoCloseSwitch() {
|
||||
val autoCloseOn = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false)
|
||||
|
@ -42,6 +62,11 @@ class SettingsFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the relevant preference from the SharedPreferences and configures the corresponding switch accordingly,
|
||||
* and adds a listener to the said switch to store the preference in case the user changes it. Also makes a call to
|
||||
* recreate the activity and apply the selected theme.
|
||||
*/
|
||||
private fun initNightModeSwitch() {
|
||||
val nightModeOn = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false)
|
||||
|
@ -57,5 +82,55 @@ class SettingsFragment : Fragment() {
|
|||
activity?.recreate()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the brainKey from the authorities db table for the current user account and if it is not null it passes
|
||||
* the brainKey to a method to show it in a nice MaterialDialog
|
||||
*/
|
||||
private fun getBrainkey(view: View) {
|
||||
val userId = PreferenceManager.getDefaultSharedPreferences(view.context)
|
||||
.getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") ?: ""
|
||||
|
||||
val authorityRepository = AuthorityRepository(view.context)
|
||||
|
||||
mDisposables.add(authorityRepository.get(userId)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { authority ->
|
||||
if (authority != null) {
|
||||
val plainBrainKey = CryptoUtils.decrypt(view.context, authority.encryptedBrainKey)
|
||||
val plainSequenceNumber = CryptoUtils.decrypt(view.context, authority.encryptedSequenceNumber)
|
||||
val sequenceNumber = Integer.parseInt(plainSequenceNumber)
|
||||
val brainKey = BrainKey(plainBrainKey, sequenceNumber)
|
||||
showBrainKeyDialog(view, brainKey)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the plain brainkey in a dialog so that the user can view and Copy it.
|
||||
*/
|
||||
private fun showBrainKeyDialog(view: View, brainKey: BrainKey) {
|
||||
MaterialDialog(view.context).show {
|
||||
title(text = "BrainKey")
|
||||
message(text = brainKey.brainKey)
|
||||
customView(R.layout.dialog_copy_brainkey)
|
||||
cancelable(false)
|
||||
positiveButton(android.R.string.copy) {
|
||||
Toast.makeText(it.context, "Copied to clipboard", Toast.LENGTH_SHORT).show()
|
||||
val clipboard = it.context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("label", brainKey.brainKey)
|
||||
clipboard.primaryClip = clip
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
if (!mDisposables.isDisposed) mDisposables.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,8 @@ class TransfersLoader(private var mContext: Context?): ServiceConnection {
|
|||
Log.e(TAG, "AEADBadTagException. Class: " + e.javaClass + ", Msg: " + e.message)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
)
|
||||
mDisposables.add(RxBus.getBusInstance()
|
||||
.asFlowable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -145,7 +146,8 @@ class TransfersLoader(private var mContext: Context?): ServiceConnection {
|
|||
responseMap.clear()
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
)
|
||||
} else {
|
||||
// If there is no current user, we should not do anything
|
||||
mState = State.CANCELLED
|
||||
|
|
|
@ -20,6 +20,10 @@ class AuthorityRepository internal constructor(context: Context) {
|
|||
insertAsyncTask(mAuthorityDao).execute(authority)
|
||||
}
|
||||
|
||||
fun get(userId: String): Single<Authority> {
|
||||
return mAuthorityDao.get(userId)
|
||||
}
|
||||
|
||||
fun getWIF(userId: String, authorityType: Int): Single<String> {
|
||||
return mAuthorityDao.getWIF(userId, authorityType)
|
||||
}
|
||||
|
|
11
app/src/main/res/layout/dialog_copy_brainkey.xml
Normal file
11
app/src/main/res/layout/dialog_copy_brainkey.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/msg__brainkey_info"
|
||||
android:textSize="13sp"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingStart="@dimen/activity_horizontal_margin"
|
||||
android:paddingEnd="@dimen/activity_horizontal_margin"/>
|
|
@ -66,6 +66,8 @@
|
|||
<string name="msg__brainkey_description">BrainKey. Account recovery words that can be captured or copied, but not
|
||||
edited.
|
||||
</string>
|
||||
<string name="msg__brainkey_info">Print this out, or write it down. Anyone with access to your recovery key will
|
||||
have access to funds within this wallet.</string>
|
||||
<string name="btn__view_and_copy"><![CDATA[View & Copy]]></string>
|
||||
<string name="title__bugs_or_ideas">Bugs or Ideas?</string>
|
||||
<string name="msg__bugs_or_ideas">Telegram chat: http://t.me/Agorise\nEmail: Agorise@protonmail.ch\nOpen Source:
|
||||
|
|
Loading…
Reference in a new issue