Skip to content

Commit

Permalink
Merge pull request #85 from ergoplatform/develop
Browse files Browse the repository at this point in the history
Version 1.6.2204
  • Loading branch information
MrStahlfelge authored Jan 28, 2022
2 parents 77162af + 6d33336 commit c0fc2f0
Show file tree
Hide file tree
Showing 89 changed files with 4,010 additions and 974 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Features:
* Displays and sends tokens and NFT
* Your secrets are stored password-encrypted or authentication-protected
* Show wallet balance, configurable comparison fiat currency
* Cold wallet capable ([more information](https://github.com/ergoplatform/ergo-wallet-app/wiki/Cold-wallet))
* ErgoPay support

You need at least Android 7 or iOS 13 to run Ergo Wallet.

Expand Down Expand Up @@ -43,6 +45,18 @@ The APK file can be installed on your Android device. If you sideload for the fi
* [Android](android/BUILD.md)
* [iOS](ios/BUILD.md)

### Translations

Every translation is welcome! There is a single
[strings file to translate](https://github.com/ergoplatform/ergo-wallet-app/blob/develop/android/src/main/res/values/strings.xml)
to your language.

Either send me the translated file on Discord or Telegram, or open a PR here. For this, move the
file to a values-xx directory where xx is your language's ISO code.
([Spanish example](https://github.com/ergoplatform/ergo-wallet-app/tree/develop/android/src/main/res/values-es))

Thanks in advance!

### Tip the developer

If you want to tip the developer for making this app, thanks in advance! Send your tips to
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId "org.ergoplatform.android"
minSdkVersion 24
targetSdkVersion 30
versionCode 2203
versionName "1.5.2203"
versionCode 2204
versionName "1.6.2204"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
3 changes: 2 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
<category android:name="android.intent.category.BROWSABLE" />
<!-- URI schemes not supported by nav component at the moment (2.3.5) -->
<!-- PaymentRequest.PAYMENT_URI_SCHEME -->
<data android:scheme="ergoplatform" />
<data android:scheme="ergo" />
<data android:scheme="ergopay" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
Expand Down
51 changes: 45 additions & 6 deletions android/src/main/java/org/ergoplatform/android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.zxing.integration.android.IntentIntegrator
import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent
import org.ergoplatform.isPaymentRequestUrl
import org.ergoplatform.android.transactions.ChooseSpendingWalletFragmentDialog
import org.ergoplatform.android.ui.AndroidStringProvider
import org.ergoplatform.android.ui.postDelayed
import org.ergoplatform.uilogic.MainAppUiLogic

class MainActivity : AppCompatActivity() {

Expand Down Expand Up @@ -41,11 +46,45 @@ class MainActivity : AppCompatActivity() {
}
}

private fun handleIntent(navController: NavController) {
intent.dataString?.let {
if (isPaymentRequestUrl(it)) {
navController.navigate(R.id.chooseSpendingWalletFragmentDialog)
fun scanQrCode() {
IntentIntegrator(this).initiateScan(setOf(IntentIntegrator.QR_CODE))
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
if (result != null) {
result.contents?.let {
// post on Main thread, otherwise navigate() not working
postDelayed(0) { handleRequests(it, true) }
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}

private fun handleRequests(
data: String,
fromQrCode: Boolean,
optNavController: NavController? = null
) {
val navController = optNavController ?: findNavController(R.id.nav_host_fragment)

MainAppUiLogic.handleRequests(data, fromQrCode, AndroidStringProvider(this), {
navController.navigate(
R.id.chooseSpendingWalletFragmentDialog,
ChooseSpendingWalletFragmentDialog.buildArgs(it)
)
}, {
MaterialAlertDialogBuilder(this)
.setMessage(it)
.setPositiveButton(R.string.zxing_button_ok, null)
.show()
})
}

private fun handleIntent(navController: NavController? = null) {
intent.dataString?.let {
handleRequests(it, false, navController)
}
}

Expand All @@ -55,6 +94,6 @@ class MainActivity : AppCompatActivity() {

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
handleIntent(findNavController(R.id.nav_host_fragment))
handleIntent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.ergoplatform.NodeConnector
import org.ergoplatform.ErgoApiService
import org.ergoplatform.android.Preferences
import org.ergoplatform.android.databinding.FragmentConnectionSettingsBinding
import org.ergoplatform.getDefaultExplorerApiUrl
Expand Down Expand Up @@ -58,7 +58,7 @@ class ConnectionSettingsDialogFragment : BottomSheetDialogFragment() {
preferences.prefNodeUrl = nodeUrl

// reset api service of NodeConnector to load new settings
NodeConnector.getInstance().resetApiService()
ErgoApiService.resetApiService()

dismiss()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.ergoplatform.android.databinding.FragmentSendFundsWalletChooserBindin
import org.ergoplatform.android.databinding.FragmentSendFundsWalletChooserItemBinding
import org.ergoplatform.android.ui.FullScreenFragmentDialog
import org.ergoplatform.android.ui.navigateSafe
import org.ergoplatform.transactions.isErgoPaySigningRequest
import org.ergoplatform.parsePaymentRequest
import org.ergoplatform.wallet.getBalanceForAllAddresses

Expand All @@ -39,18 +40,25 @@ class ChooseSpendingWalletFragmentDialog : FullScreenFragmentDialog() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val query = requireActivity().intent.dataString
val query = arguments?.getString(ARG_QUERY)

if (query == null) {
dismiss()
return
}

val content = parsePaymentRequest(query)
binding.receiverAddress.text = content?.address
val amount = content?.amount ?: ErgoAmount.ZERO
binding.grossAmount.amount = amount.toDouble()
binding.grossAmount.visibility = if (amount.nanoErgs > 0) View.VISIBLE else View.GONE
if (isErgoPaySigningRequest(query)) {
binding.grossAmount.visibility = View.GONE
binding.textviewTo.visibility = View.GONE
binding.receiverAddress.visibility = View.GONE
binding.labelTitle.setText(R.string.title_ergo_pay_request)
} else {
val content = parsePaymentRequest(query)
binding.receiverAddress.text = content?.address
val amount = content?.amount ?: ErgoAmount.ZERO
binding.grossAmount.setAmount(amount.toBigDecimal())
binding.grossAmount.visibility = if (amount.nanoErgs > 0) View.VISIBLE else View.GONE
}

AppDatabase.getInstance(requireContext()).walletDao().getWalletsWithStates()
.observe(viewLifecycleOwner, {
Expand All @@ -59,34 +67,41 @@ class ChooseSpendingWalletFragmentDialog : FullScreenFragmentDialog() {

if (wallets.size == 1) {
// immediately switch to send funds screen
navigateToSendFundsScreen(wallets.first().walletConfig.id, query)
navigateToNextScreen(wallets.first().walletConfig.id, query)
}
wallets.sortedBy { it.walletConfig.displayName }.forEach { wallet ->
val itemBinding = FragmentSendFundsWalletChooserItemBinding.inflate(
layoutInflater, binding.listWallets, true
)

itemBinding.walletBalance.amount =
ErgoAmount(wallet.getBalanceForAllAddresses()).toDouble()
itemBinding.walletBalance.setAmount(
ErgoAmount(wallet.getBalanceForAllAddresses()).toBigDecimal()
)
itemBinding.walletName.text = wallet.walletConfig.displayName

itemBinding.root.setOnClickListener {
navigateToSendFundsScreen(wallet.walletConfig.id, query)
navigateToNextScreen(wallet.walletConfig.id, query)
}
}
})
}

private fun navigateToSendFundsScreen(walletId: Int, paymentRequest: String) {
private fun navigateToNextScreen(walletId: Int, request: String) {
val navBuilder = NavOptions.Builder()
val navOptions =
navBuilder.setPopUpTo(R.id.chooseSpendingWalletFragmentDialog, true).build()

NavHostFragment.findNavController(requireParentFragment())
.navigateSafe(
ChooseSpendingWalletFragmentDialogDirections.actionChooseSpendingWalletFragmentDialogToSendFundsFragment(
paymentRequest, walletId
), navOptions
if (isErgoPaySigningRequest(request))
ChooseSpendingWalletFragmentDialogDirections.actionChooseSpendingWalletFragmentDialogToErgoPaySigningFragment(
request, walletId
)
else
ChooseSpendingWalletFragmentDialogDirections.actionChooseSpendingWalletFragmentDialogToSendFundsFragment(
request, walletId
),
navOptions
)
}

Expand All @@ -102,4 +117,14 @@ class ChooseSpendingWalletFragmentDialog : FullScreenFragmentDialog() {
super.onDestroyView()
_binding = null
}

companion object {
private const val ARG_QUERY = "ARG_QUERY"

fun buildArgs(query: String): Bundle {
val args = Bundle()
args.putString(ARG_QUERY, query)
return args
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,9 @@ import androidx.navigation.fragment.navArgs
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.snackbar.Snackbar
import com.google.zxing.integration.android.IntentIntegrator
import org.ergoplatform.ErgoAmount
import org.ergoplatform.android.R
import org.ergoplatform.android.databinding.EntryTransactionBoxBinding
import org.ergoplatform.android.databinding.EntryWalletTokenBinding
import org.ergoplatform.android.databinding.FragmentColdWalletSigningBinding
import org.ergoplatform.android.ui.*
import org.ergoplatform.explorer.client.model.AssetInstanceInfo
import org.ergoplatform.transactions.QR_DATA_LENGTH_LIMIT
import org.ergoplatform.transactions.QR_DATA_LENGTH_LOW_RES
import org.ergoplatform.transactions.coldSigningResponseToQrChunks
Expand Down Expand Up @@ -64,7 +60,7 @@ class ColdWalletSigningFragment : AbstractAuthenticationFragment() {

viewModel.signingResult.observe(viewLifecycleOwner, {
if (it?.success == true && viewModel.signedQrCode != null) {
binding.transactionInfo.visibility = View.GONE
binding.transactionInfo.root.visibility = View.GONE
binding.cardSigningResult.visibility = View.VISIBLE
binding.cardScanMore.visibility = View.GONE

Expand Down Expand Up @@ -94,7 +90,7 @@ class ColdWalletSigningFragment : AbstractAuthenticationFragment() {
})

// Button click listeners
binding.buttonSignTx.setOnClickListener {
binding.transactionInfo.buttonSignTx.setOnClickListener {
viewModel.wallet?.let {
startAuthFlow(it.walletConfig)
}
Expand Down Expand Up @@ -162,24 +158,10 @@ class ColdWalletSigningFragment : AbstractAuthenticationFragment() {
}

transactionInfo?.reduceBoxes()?.let {
binding.transactionInfo.visibility = View.VISIBLE
binding.transactionInfo.root.visibility = View.VISIBLE
binding.cardScanMore.visibility = View.GONE

binding.layoutInboxes.apply {
removeAllViews()

it.inputs.forEach { input ->
bindBoxView(this, input.value, input.address ?: input.boxId, input.assets)
}
}

binding.layoutOutboxes.apply {
removeAllViews()

it.outputs.forEach { output ->
bindBoxView(this, output.value, output.address, output.assets)
}
}
binding.transactionInfo.bindTransactionInfo(it, layoutInflater)
}
}

Expand All @@ -194,40 +176,6 @@ class ColdWalletSigningFragment : AbstractAuthenticationFragment() {
)
}

private fun bindBoxView(
container: ViewGroup,
value: Long?,
address: String,
assets: List<AssetInstanceInfo>?
) {
val boxBinding = EntryTransactionBoxBinding.inflate(layoutInflater, container, true)
boxBinding.boxErgAmount.text = getString(
R.string.label_erg_amount,
ErgoAmount(value ?: 0).toStringTrimTrailingZeros()
)
boxBinding.boxErgAmount.visibility =
if (value == null || value == 0L) View.GONE else View.VISIBLE
boxBinding.labelBoxAddress.text = address
boxBinding.labelBoxAddress.setOnClickListener {
boxBinding.labelBoxAddress.maxLines =
if (boxBinding.labelBoxAddress.maxLines == 1) 10 else 1
}

boxBinding.boxTokenEntries.apply {
removeAllViews()
visibility = View.GONE

assets?.forEach {
visibility = View.VISIBLE
val tokenBinding =
EntryWalletTokenBinding.inflate(layoutInflater, this, true)
// we use the token id here, we don't have the name in the cold wallet context
tokenBinding.labelTokenName.text = it.tokenId
tokenBinding.labelTokenVal.text = it.amount.toString()
}
}
}

override fun proceedAuthFlowWithPassword(password: String): Boolean {
return viewModel.signTxWithPassword(password, AndroidStringProvider(requireContext()))
}
Expand Down
Loading

0 comments on commit c0fc2f0

Please sign in to comment.