Skip to content

Commit

Permalink
feat(dashpay): add mix dash first warning dialog (#1309)
Browse files Browse the repository at this point in the history
* feat(dashpay): add Balance Mixing Warning before username request

* chore: remove comments and fix formatting
  • Loading branch information
HashEngineering authored Sep 30, 2024
1 parent 08ee481 commit 5875a86
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 4 deletions.
1 change: 1 addition & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<string name="button_understand">I understand</string>
<string name="button_okay">Okay</string>
<string name="button_share">Share</string>
<string name="button_skip">Skip</string>
<string name="share_address">Share Address</string>
<string name="verify">Verify</string>
<string name="receive_enter_amount_button">Specify Amount</string>
Expand Down
2 changes: 1 addition & 1 deletion wallet/res/layout/block_username_request_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
android:layout_marginStart="6dp"
android:text="@string/block"
style="@style/Body2.Medium.Red"
/>
/>

</LinearLayout>

Expand Down
100 changes: 100 additions & 0 deletions wallet/res/layout/dialog_mix_dash_first.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2024 Dash Core Group
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">

<View
android:id="@+id/drag_indicator"
android:layout_width="40dp"
android:layout_height="4dp"
android:layout_gravity="center"
android:layout_marginTop="15dp"
android:background="@drawable/rounded_background"
android:theme="@style/DragIndicatorBackground"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/light_gray" />

<ImageButton
android:id="@+id/collapse_button"
style="@style/DialogCloseButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />


<LinearLayout
android:id="@+id/text_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@id/collapse_button"
app:layout_constraintBottom_toTopOf="@+id/bottom_buttons"
>
<TextView
style="@style/Headline5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mix_dash_title"
/>
<TextView
style="@style/Body2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mix_dash_message"
/>



</LinearLayout>

<LinearLayout
android:id="@+id/bottom_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal"
>
<Button
android:id="@+id/skip_button"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="15dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
style="@style/Button.Tertiary.Blue"
android:text="@string/button_skip"
/>

<Button
android:id="@+id/mix_button"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="15dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
style="@style/Button.Primary.Blue"
android:text="@string/mix_dash_mix"
/>
</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
3 changes: 3 additions & 0 deletions wallet/res/values/strings-dashpay.xml
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,7 @@
<string name="request_username_lost_vote">Requested username has been given to someone else</string>
<string name="request_username_blocked_message">The username %s was blocked by the Dash Network. Please try again by requesting another username.</string>
<string name="request_username_lost_vote_message">Due to the voting process, the Dash Network has decided to assign the username %s to someone else. Please try again by requesting another username.</string>
<string name="mix_dash_mix">Mix Balance</string>
<string name="mix_dash_title">Mix your Dash</string>
<string name="mix_dash_message">To help prevent other people from seeing who you make payments to, it is recommended to mix your balance before you create your username.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import de.schildbach.wallet.WalletApplication
import de.schildbach.wallet.database.dao.DashPayProfileDao
import de.schildbach.wallet.database.entity.BlockchainIdentityConfig
import de.schildbach.wallet.database.entity.BlockchainIdentityData
import de.schildbach.wallet.ui.dashpay.utils.DashPayConfig
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
Expand All @@ -20,7 +21,8 @@ class CreateIdentityViewModel @Inject constructor(
private val walletApplication: WalletApplication,
private val analytics: AnalyticsService,
blockchainIdentityDataDao: BlockchainIdentityConfig,
dashPayProfileDao: DashPayProfileDao
dashPayProfileDao: DashPayProfileDao,
val dashPayConfig: DashPayConfig
) : BaseProfileViewModel(blockchainIdentityDataDao, dashPayProfileDao) {

private val _creationState = MutableStateFlow(BlockchainIdentityData.CreationState.NONE)
Expand Down Expand Up @@ -56,4 +58,6 @@ class CreateIdentityViewModel @Inject constructor(
)
}
}

suspend fun shouldShowMixDash(): Boolean = dashPayConfig.get(DashPayConfig.MIX_DASH_SHOWN)?.not() ?: true
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import android.content.Context
import androidx.datastore.preferences.SharedPreferencesMigration
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import org.dash.wallet.common.WalletDataProvider
import org.dash.wallet.common.data.BaseConfig
import javax.inject.Inject
Expand Down Expand Up @@ -53,6 +52,7 @@ open class DashPayConfig @Inject constructor(
val LAST_METADATA_PUSH = longPreferencesKey("last_metadata_push")
val HAS_DASH_PAY_INFO_SCREEN_BEEN_SHOWN = booleanPreferencesKey("has_dash_pay_info_screen_been_shown")
val VOTING_INFO_SHOWN = booleanPreferencesKey("voting_info_shown")
val MIX_DASH_SHOWN = booleanPreferencesKey("mix_dash_shown")
}

open suspend fun areNotificationsDisabled(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2024 Dash Core Group
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.schildbach.wallet.ui.more

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import de.schildbach.wallet.ui.CreateUsernameActivity
import de.schildbach.wallet.ui.coinjoin.CoinJoinActivity
import de.schildbach.wallet_test.R
import de.schildbach.wallet_test.databinding.DialogMixDashFirstBinding
import kotlinx.coroutines.launch
import org.dash.wallet.common.ui.dialogs.OffsetDialogFragment
import org.dash.wallet.common.ui.viewBinding

@AndroidEntryPoint
class MixDashFirstDialogFragment : OffsetDialogFragment(R.layout.dialog_mix_dash_first) {
private val binding by viewBinding(DialogMixDashFirstBinding::bind)
val viewModel by viewModels<MixDashFirstViewModel>()
private val settingsViewModel: SettingsViewModel by viewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.skipButton.setOnClickListener {
startActivity(Intent(requireContext(), CreateUsernameActivity::class.java))
viewModel.setMixDashShown()
dismiss()
}

binding.mixButton.setOnClickListener {
lifecycleScope.launch {
val shouldShowFirstTimeInfo = settingsViewModel.shouldShowCoinJoinInfo()

if (shouldShowFirstTimeInfo) {
settingsViewModel.setCoinJoinInfoShown()
}

val intent = Intent(requireActivity(), CoinJoinActivity::class.java)
intent.putExtra(CoinJoinActivity.FIRST_TIME_EXTRA, shouldShowFirstTimeInfo)
startActivity(intent)
viewModel.setMixDashShown()
dismiss()
}
}
}
}
45 changes: 45 additions & 0 deletions wallet/src/de/schildbach/wallet/ui/more/MixDashFirstViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2024 Dash Core Group
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.schildbach.wallet.ui.more

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import de.schildbach.wallet.Constants
import de.schildbach.wallet.ui.dashpay.utils.DashPayConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.bitcoinj.core.Address
import org.bitcoinj.script.ScriptPattern
import org.bitcoinj.wallet.KeyChain
import org.dash.wallet.common.WalletDataProvider
import org.dash.wallet.common.services.BlockchainStateProvider
import org.dash.wallet.common.util.Constants.DASH_CURRENCY
import org.slf4j.LoggerFactory
import javax.inject.Inject

@HiltViewModel
class MixDashFirstViewModel @Inject constructor(
private val dashPayConfig: DashPayConfig,
) : ViewModel() {
fun setMixDashShown() {
viewModelScope.launch(Dispatchers.IO) {
dashPayConfig.set(DashPayConfig.MIX_DASH_SHOWN, true)
}
}
}
15 changes: 14 additions & 1 deletion wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import de.schildbach.wallet.ui.EditProfileActivity
import de.schildbach.wallet.ui.LockScreenActivity
import de.schildbach.wallet.ui.ReportIssueDialogBuilder
import de.schildbach.wallet.ui.SettingsActivity
import de.schildbach.wallet.ui.coinjoin.CoinJoinLevelViewModel
import de.schildbach.wallet.ui.dashpay.CreateIdentityViewModel
import de.schildbach.wallet.ui.dashpay.EditProfileViewModel
import de.schildbach.wallet.ui.dashpay.utils.display
Expand All @@ -52,7 +53,9 @@ import de.schildbach.wallet.ui.invite.InvitesHistoryActivity
import de.schildbach.wallet.ui.main.MainViewModel
import de.schildbach.wallet_test.R
import de.schildbach.wallet_test.databinding.FragmentMoreBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.bitcoinj.core.NetworkParameters
import org.dash.wallet.common.Configuration
import org.dash.wallet.common.WalletDataProvider
Expand Down Expand Up @@ -86,6 +89,7 @@ class MoreFragment : Fragment(R.layout.fragment_more) {
private val editProfileViewModel: EditProfileViewModel by viewModels()
private val createInviteViewModel: CreateInviteViewModel by viewModels()
private val createIdentityViewModel: CreateIdentityViewModel by viewModels()
private val coinJoinViewModel: CoinJoinLevelViewModel by viewModels()

@Inject lateinit var packageInfoProvider: PackageInfoProvider
@Inject lateinit var configuration: Configuration
Expand Down Expand Up @@ -172,7 +176,14 @@ class MoreFragment : Fragment(R.layout.fragment_more) {
binding.errorUpdatingProfile.cancel.setOnClickListener { dismissProfileError() }
binding.editUpdateSwitcher.isVisible = false
binding.joinDashpayBtn.setOnClickListener {
startActivity(Intent(requireContext(), CreateUsernameActivity::class.java))
lifecycleScope.launch {
val shouldShowMixDashDialog = withContext(Dispatchers.IO) { createIdentityViewModel.shouldShowMixDash() }
if (coinJoinViewModel.isMixing || !shouldShowMixDashDialog) {
startActivity(Intent(requireContext(), CreateUsernameActivity::class.java))
} else {
MixDashFirstDialogFragment().show(requireActivity())
}
}
}
binding.usernameVoting.isVisible = Constants.SUPPORTS_PLATFORM
binding.usernameVoting.setOnClickListener {
Expand Down Expand Up @@ -214,6 +225,8 @@ class MoreFragment : Fragment(R.layout.fragment_more) {
binding.requestedUsernameTitle.text = getString(R.string.requesting_your_username_title)
binding.requestedUsernameSubtitle.text = getString(R.string.requesting_your_username_message, username)
binding.retryRequestButton.isVisible = false
binding.requestedUsernameArrow.isVisible = false
binding.requestedUsernameContainer.isEnabled = false
}
}
} else if (it.creationState == BlockchainIdentityData.CreationState.VOTING) {
Expand Down

0 comments on commit 5875a86

Please sign in to comment.