diff --git a/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt index 85fc1e4..68fffb3 100644 --- a/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt @@ -1,6 +1,8 @@ package cash.z.ecc.android.di.module import android.content.Context +import cash.z.ecc.android.ext.Const +import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.sdk.Initializer import dagger.Module import dagger.Provides @@ -8,10 +10,17 @@ import dagger.Reusable @Module class InitializerModule { - private val host = "lightwalletd.electriccoin.co" - private val port = 9067 + + companion object { + const val defaultHost = "lightwalletd.electriccoin.co" + const val defaultPort = 9067 + } + + // TODO: Read SecurePrefs +// private val host: String = sharedPreferences.getString(Const.Pref.SERVER_NAME, defaultHost) ?: defaultHost +// private val port: Int = sharedPreferences.getInt(Const.Pref.SERVER_PORT, defaultPort) @Provides @Reusable - fun provideInitializer(appContext: Context) = Initializer(appContext, host, port) + fun provideInitializer(appContext: Context) = Initializer(appContext, defaultHost, defaultPort) } diff --git a/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsSynchronizerModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsSynchronizerModule.kt index 73399d3..bebc16c 100644 --- a/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsSynchronizerModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsSynchronizerModule.kt @@ -13,6 +13,7 @@ import cash.z.ecc.android.ui.profile.ProfileViewModel import cash.z.ecc.android.ui.receive.ReceiveViewModel import cash.z.ecc.android.ui.scan.ScanViewModel import cash.z.ecc.android.ui.send.SendViewModel +import cash.z.ecc.android.ui.settings.SettingsViewModel import dagger.Binds import dagger.Module import dagger.multibindings.IntoMap @@ -58,6 +59,12 @@ abstract class ViewModelsSynchronizerModule { @IntoMap @ViewModelKey(ProfileViewModel::class) abstract fun bindProfileViewModel(implementation: ProfileViewModel): ViewModel + + @SynchronizerScope + @Binds + @IntoMap + @ViewModelKey(SettingsViewModel::class) + abstract fun bindSettingsViewModel(implementation: SettingsViewModel): ViewModel /** * Factory for view models that are not created until the Synchronizer exists. Only VMs that diff --git a/app/src/main/java/cash/z/ecc/android/ext/Const.kt b/app/src/main/java/cash/z/ecc/android/ext/Const.kt index 690b8ea..5ab2a86 100644 --- a/app/src/main/java/cash/z/ecc/android/ext/Const.kt +++ b/app/src/main/java/cash/z/ecc/android/ext/Const.kt @@ -17,5 +17,7 @@ object Const { object Pref { const val FIRST_USE_VIEW_TX = "const.pref.first_use_view_tx" const val FEEDBACK_ENABLED = "const.pref.feedback_enabled" + const val SERVER_NAME = "const.pref.server_name" + const val SERVER_PORT = "const.pref.server_port" } } diff --git a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt index 220681a..517239c 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt @@ -38,6 +38,7 @@ class ProfileFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.hitAreaSettings.onClickNavTo(R.id.action_nav_profile_to_nav_settings) binding.hitAreaClose.onClickNavBack() { tapped(PROFILE_CLOSE) } binding.buttonBackup.onClickNavTo(R.id.action_nav_profile_to_nav_backup) { tapped(PROFILE_BACKUP) } binding.buttonFeedback.onClickNavTo(R.id.action_nav_profile_to_nav_feedback) { diff --git a/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsFragment.kt new file mode 100644 index 0000000..fd9b62f --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsFragment.kt @@ -0,0 +1,76 @@ +package cash.z.ecc.android.ui.settings + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import cash.z.ecc.android.di.viewmodel.viewModel +import cash.z.ecc.android.databinding.FragmentSettingsBinding +import cash.z.ecc.android.ext.onClickNavBack +import cash.z.ecc.android.ui.base.BaseFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +class SettingsFragment : BaseFragment() { + + private val viewModel: SettingsViewModel by viewModel() + + override fun inflate(inflater: LayoutInflater): FragmentSettingsBinding = + FragmentSettingsBinding.inflate(inflater) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + getCurrentServer() + binding.hitAreaClose.onClickNavBack() + binding.buttonUpdate.setOnClickListener(View.OnClickListener { + validateServerHost(view) + }) + binding.buttonReset.setOnClickListener(View.OnClickListener { + resetServer() + showUpdateServerDialog(view) + }) + } + + private fun getCurrentServer() { + binding.inputTextLightwalletdServer.setText(viewModel.getServerHost()) + binding.inputTextLightwalletdPort.setText(viewModel.getServerPort().toString()) + } + + private fun resetServer() { + } + + private fun validateServerHost(view: View) { + var isError = false + if (binding.inputTextLightwalletdServer.text.toString().contains("http")) { + binding.lightwalletdServer.error = "Please remove http:// or https://" + isError = true + } else { + binding.lightwalletdServer.error = null + } + if (Integer.valueOf(binding.inputTextLightwalletdPort.text.toString()) > 65535) { + binding.lightwalletdPort.error = "Please enter port number below 65535" + isError = true + } else { + binding.lightwalletdPort.error = null + } + if (!isError) { + showUpdateServerDialog(view) + } + } + + private fun showUpdateServerDialog(view: View) { + MaterialAlertDialogBuilder(view.context) + .setTitle("Modify lightwalletd Server?") + .setMessage("WARNING: Entering an invalid or compromised lighthttpd server might result in misconfiguration or loss of funds.") + .setCancelable(false) + .setPositiveButton("Update") { dialog, _ -> + dialog.dismiss() + updateServer() + } + .setNegativeButton("Cancel") { dialog, _ -> + dialog.dismiss() + } + .show() + } + + private fun updateServer() { + } +} diff --git a/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsViewModel.kt new file mode 100644 index 0000000..5806497 --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/ui/settings/SettingsViewModel.kt @@ -0,0 +1,30 @@ +package cash.z.ecc.android.ui.settings + +import androidx.lifecycle.ViewModel +import cash.z.ecc.android.di.module.InitializerModule +import cash.z.ecc.android.sdk.Synchronizer +import cash.z.ecc.android.sdk.ext.twig +import javax.inject.Inject + +class SettingsViewModel @Inject constructor() : ViewModel() { + + @Inject + lateinit var synchronizer: Synchronizer + + fun updateServer(host: String, port: Int) { + // TODO: Update the SecurePrefs here + } + + fun getServerHost(): String { + return InitializerModule.defaultHost + } + + fun getServerPort(): Int { + return InitializerModule.defaultPort + } + + override fun onCleared() { + super.onCleared() + twig("SettingsViewModel cleared!") + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/ic_settings.xml b/app/src/main/res/drawable-anydpi/ic_settings.xml new file mode 100644 index 0000000..a03a209 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_settings.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 21ce9dc..43d11df 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -311,6 +311,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:elevation="6dp" + app:tint="@color/colorAccent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="H,1:1" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index dafabe2..4609a32 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -35,6 +35,33 @@ android:orientation="vertical" app:layout_constraintGuide_percent="0.85" /> + + + + + app:layout_constraintStart_toStartOf="parent" /> + + app:layout_constraintStart_toStartOf="parent" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml new file mode 100644 index 0000000..f77a35e --- /dev/null +++ b/app/src/main/res/layout/fragment_settings.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index cae3d83..f31f7f3 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -69,11 +69,18 @@ + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1050b6d..0536081 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,6 +40,21 @@ My balance was . . . I\'d like . . . + + Shielded User + Send Feedback + Backup Wallet + See Application Logs + ECC Wallet + v1.0.0-alpha05 + + + Change lightwalletd server: + Server Address + Server Port + Update + Reset to Default Host + Don\'t show me again Potential Privacy Risk @@ -51,5 +66,4 @@ ECC Wallet a178e1ef062133fc121079cb12fa43c7 -