Skip to content

Commit

Permalink
Merge pull request #142 from ergoplatform/release/2.0.x
Browse files Browse the repository at this point in the history
2.0.2215
  • Loading branch information
MrStahlfelge authored Aug 27, 2022
2 parents 7952095 + 110910d commit 15ad00c
Show file tree
Hide file tree
Showing 68 changed files with 846 additions and 443 deletions.
5 changes: 3 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 31
versionCode 2214
versionName "2.0.2214"
versionCode 2215
versionName "2.0.2215"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -72,6 +72,7 @@ android {

dependencies {
implementation project(path: ':common-jvm')
implementation project(path: ':common-compose')

def room_version = "2.4.0"

Expand Down
1 change: 1 addition & 0 deletions android/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
-keep class special.** { *; }
-keep class wrappers.** { *; }
-keep class org.ergoplatform.restapi.** { *; }
-keep class org.ergoplatform.mosaik.model.** { *; }
-keep class org.ergoplatform.appkit.** { *; }
-keep class scorex.util.encode.** { *; }
-keep class scala.util.control.** { *; }
Expand Down
21 changes: 11 additions & 10 deletions android/src/main/java/org/ergoplatform/android/Preferences.kt
Original file line number Diff line number Diff line change
@@ -1,48 +1,49 @@
package org.ergoplatform.android

import android.content.Context
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatDelegate
import org.ergoplatform.persistance.*

const val KEY_DAYNIGHTMODE = "dayNightMode"

class Preferences(val context: Context) : PreferencesProvider() {
private fun getSharedPrefs(context: Context) =
class Preferences(context: Context) : PreferencesProvider() {
private val prefs: SharedPreferences =
context.getSharedPreferences(NAME_SHAREDPREFS, Context.MODE_PRIVATE)

override fun getString(key: String, default: String): String {
return getSharedPrefs(context).getString(key, default) ?: default
return prefs.getString(key, default) ?: default
}

override fun saveString(key: String, value: String) {
getSharedPrefs(context).edit().putString(key, value).apply()
prefs.edit().putString(key, value).apply()
}

override fun getLong(key: String, default: Long): Long {
return getSharedPrefs(context).getLong(key, default)
return prefs.getLong(key, default)
}

override fun saveLong(key: String, value: Long) {
getSharedPrefs(context).edit().putLong(key, value).apply()
prefs.edit().putLong(key, value).apply()
}

override fun getFloat(key: String, default: Float): Float {
return getSharedPrefs(context).getFloat(key, default)
return prefs.getFloat(key, default)
}

override fun saveFloat(key: String, value: Float) {
getSharedPrefs(context).edit().putFloat(key, value).apply()
prefs.edit().putFloat(key, value).apply()
}

var dayNightMode: Int
get() {
return getSharedPrefs(context).getInt(
return prefs.getInt(
KEY_DAYNIGHTMODE,
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
)
}
set(mode) {
getSharedPrefs(context).edit().putInt(KEY_DAYNIGHTMODE, mode).apply()
prefs.edit().putInt(KEY_DAYNIGHTMODE, mode).apply()
AppCompatDelegate.setDefaultNightMode(mode)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.ergoplatform.android.wallet.WalletChooserCallback
import org.ergoplatform.persistance.WalletConfig
import org.ergoplatform.transactions.MessageSeverity
import org.ergoplatform.uilogic.ergoauth.ErgoAuthUiLogic
import org.ergoplatform.wallet.isReadOnly

class ErgoAuthenticationFragment : AbstractAuthenticationFragment(), WalletChooserCallback {
private var _binding: FragmentErgoAuthenticationBinding? = null
Expand Down Expand Up @@ -80,7 +81,7 @@ class ErgoAuthenticationFragment : AbstractAuthenticationFragment(), WalletChoos
}

override fun startAuthFlow() {
if (authenticationWalletConfig?.secretStorage == null) {
if (authenticationWalletConfig?.isReadOnly() != false) {
// read only wallet not supported (yet)
MaterialAlertDialogBuilder(requireContext())
.setMessage(R.string.error_wallet_type_ergoauth_not_avail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ class AppOverviewFragment : Fragment() {
}

private fun refreshLastVisited(lastVisited: List<MosaikAppEntry>) {
if (lastVisited.isNotEmpty())
binding.descEmpty.visibility = View.GONE
binding.descLastVisitedEmpty.visibility =
if (lastVisited.isEmpty()) View.VISIBLE else View.GONE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import android.view.*
import androidx.activity.OnBackPressedCallback
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.MaterialTheme
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
Expand All @@ -32,7 +32,6 @@ import org.ergoplatform.android.wallet.WalletChooserCallback
import org.ergoplatform.android.wallet.addresses.AddressChooserCallback
import org.ergoplatform.android.wallet.addresses.ChooseAddressListDialogFragment
import org.ergoplatform.mosaik.MosaikComposeConfig
import org.ergoplatform.mosaik.MosaikStyleConfig
import org.ergoplatform.mosaik.MosaikViewTree
import org.ergoplatform.mosaik.model.MosaikContext
import org.ergoplatform.persistance.WalletConfig
Expand Down Expand Up @@ -98,12 +97,12 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
val builder = MaterialAlertDialogBuilder(requireContext())
.setMessage(dialog.message)
.setPositiveButton(dialog.positiveButtonText) { _, _ ->
dialog.positiveButtonClicked?.run()
dialog.positiveButtonClicked?.invoke()
}

dialog.negativeButtonText?.let {
builder.setNegativeButton(dialog.negativeButtonText) { _, _ ->
dialog.negativeButtonClicked?.run()
dialog.negativeButtonClicked?.invoke()
}
}

Expand All @@ -120,12 +119,9 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
}
viewModel.noAppLiveData.observe(viewLifecycleOwner) { errorCause ->
binding.layoutNoApp.visibility = if (errorCause == null) View.GONE else View.VISIBLE
binding.composeView.visibility = if (errorCause == null) View.VISIBLE else View.GONE
errorCause?.let {
binding.textNoApp.text =
getString(
R.string.error_no_mosaik_app,
errorCause.javaClass.simpleName + " " + errorCause.message
)
binding.textNoApp.text = viewModel.mosaikRuntime.getUserErrorMessage(errorCause)
}
}
viewModel.showWalletOrAddressChooserEvent.observe(viewLifecycleOwner) { valueId ->
Expand Down Expand Up @@ -153,7 +149,8 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
}
viewModel.scanQrCodeEvent.observe(viewLifecycleOwner) { qrScanActionId ->
qrScanActionId?.let {
IntentIntegrator.forSupportFragment(this).initiateScan(setOf(IntentIntegrator.QR_CODE))
IntentIntegrator.forSupportFragment(this)
.initiateScan(setOf(IntentIntegrator.QR_CODE))
}
}
viewModel.showTokenInfoEvent.observe(viewLifecycleOwner) { tokenId ->
Expand All @@ -179,7 +176,8 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback

// set up Compose view
MosaikComposeConfig.apply {
val minPixelSize = (300 * binding.root.resources.displayMetrics.density).toInt()
val dpToPx = binding.root.resources.displayMetrics.density
val minPixelSize = (300 * dpToPx).toInt()
scrollMinAlpha = 0f
convertByteArrayToImageBitmap = { byteArray ->
decodeSampledBitmapFromByteArray(
Expand All @@ -188,6 +186,10 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
minPixelSize
).asImageBitmap()
}
qrCodeSize = 250.dp
val qrSizePx = (250 * dpToPx).toInt()
convertQrCodeContentToImageBitmap = { convertQrCodeToBitmap(it, qrSizePx, qrSizePx)?.asImageBitmap() }
preselectEditableInputs = false

DropDownMenu = { expanded,
dismiss,
Expand All @@ -205,25 +207,9 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
DropdownMenuItem(onClick = onClick, content = content)
}
}
binding.composeView.setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
binding.composeView.setContent {
MosaikStyleConfig.apply {
primaryLabelColor = colorResource(id = R.color.primary)
secondaryLabelColor = colorResource(id = R.color.darkgrey)
defaultLabelColor = colorResource(id = R.color.text_color)
primaryButtonTextColor = colorResource(id = R.color.textcolor)
secondaryButtonTextColor = colorResource(id = R.color.textcolor)
secondaryButtonColor = colorResource(id = R.color.secondary)
secondaryButtonTextColor = colorResource(id = R.color.text_color_ondark)
textButtonTextColor = colorResource(id = R.color.primary)
textButtonColorDisabled = secondaryLabelColor
}

MaterialTheme(
colors = MaterialTheme.colors.copy(
surface = colorResource(id = R.color.cardview_background),
isLight = resources.getBoolean(R.bool.isLight)
)
) {
AppComposeTheme {
MosaikViewTree(viewModel.mosaikRuntime.viewTree)
}
}
Expand Down Expand Up @@ -325,6 +311,7 @@ class MosaikFragment : Fragment(), WalletChooserCallback, AddressChooserCallback
private val backPressedHandler = object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
viewModel.mosaikRuntime.navigateBack()
isEnabled = viewModel.mosaikRuntime.canNavigateBack()
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class MosaikViewModel : ViewModel() {
pasteToClipboardEvent.postValue(text)
}

override fun onAddressLongPress(address: String) {
pasteToClipboard(address)
}

override fun showDialog(dialog: MosaikDialog) {
showDialogEvent.postValue(dialog)
}
Expand All @@ -70,7 +74,7 @@ class MosaikViewModel : ViewModel() {
manifestLiveData.postValue(manifest)
}

override fun noAppLoaded(cause: Throwable) {
override fun appNotLoaded(cause: Throwable) {
noAppLiveData.postValue(cause)
}

Expand Down Expand Up @@ -109,8 +113,8 @@ class MosaikViewModel : ViewModel() {
showWalletOrAddressChooserEvent.postValue(valueId)
}

override fun runTokenInformationAction(action: TokenInformationAction) {
showTokenInfoEvent.postValue(action.tokenId)
override fun runTokenInformationAction(tokenId: String) {
showTokenInfoEvent.postValue(tokenId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,54 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.stringResource
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.ergoplatform.ApiServiceManager
import org.ergoplatform.android.Preferences
import org.ergoplatform.android.databinding.FragmentConnectionSettingsBinding
import org.ergoplatform.getDefaultExplorerApiUrl
import org.ergoplatform.android.R
import org.ergoplatform.android.ui.AndroidStringProvider
import org.ergoplatform.android.ui.AppComposeTheme
import org.ergoplatform.compose.settings.ConnectionSettingsLayout
import org.ergoplatform.compose.settings.defaultPadding
import org.ergoplatform.mosaik.labelStyle
import org.ergoplatform.mosaik.model.ui.text.LabelStyle

/**
*
* Shows connection settings for Explorer API URL and Node URL
*/
class ConnectionSettingsDialogFragment : BottomSheetDialogFragment() {

private var _binding: FragmentConnectionSettingsBinding? = null

// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {

_binding = FragmentConnectionSettingsBinding.inflate(inflater, container, false)
return binding.root

}

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

val preferences = Preferences(requireContext())
binding.editNodeUrl.editText?.setText(preferences.prefNodeUrl)
binding.editExplorerApiUrl.editText?.setText(preferences.prefExplorerApiUrl)
binding.inputTokenVerificationUrl.setText(preferences.prefTokenVerificationUrl)
binding.inputIpfsGateway.setText(preferences.prefIpfsGatewayUrl)
binding.buttonApply.setOnClickListener { buttonApply() }
binding.inputIpfsGateway.setOnEditorActionListener { _, _, _ ->
buttonApply()
true
}
binding.buttonDefaults.setOnClickListener {
binding.editNodeUrl.editText?.setText(preferences.getDefaultNodeApiUrl())
binding.editExplorerApiUrl.editText?.setText(getDefaultExplorerApiUrl())
binding.inputIpfsGateway.setText(preferences.defaultIpfsGatewayUrl)
binding.inputTokenVerificationUrl.setText(preferences.defaultTokenVerificationUrl)
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
AppComposeTheme {
Column(Modifier.padding(defaultPadding)) {

Text(
text = stringResource(id = R.string.button_connection_settings),
modifier = Modifier.padding(bottom = defaultPadding),
style = labelStyle(LabelStyle.BODY1),
)

ConnectionSettingsLayout(
preferences = Preferences(requireContext()),
stringProvider = AndroidStringProvider(requireContext()),
onDismissRequest = { dismiss() }
)
}
}
}
}
}

private fun buttonApply() {
val nodeUrl = binding.editNodeUrl.editText?.text?.toString() ?: ""
val explorerApiUrl = binding.editExplorerApiUrl.editText?.text?.toString() ?: ""

val preferences = Preferences(requireContext())
preferences.prefExplorerApiUrl = explorerApiUrl
preferences.prefNodeUrl = nodeUrl
preferences.prefIpfsGatewayUrl = binding.inputIpfsGateway.text?.toString() ?: ""
preferences.prefTokenVerificationUrl =
binding.inputTokenVerificationUrl.text?.toString() ?: ""

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

dismiss()
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.ergoplatform.tokens.isSingularToken
import org.ergoplatform.utils.formatTokenPriceToString
import org.ergoplatform.wallet.addresses.getAddressLabel
import org.ergoplatform.wallet.getNumOfAddresses
import org.ergoplatform.wallet.isReadOnly


/**
Expand Down Expand Up @@ -72,7 +73,7 @@ class SendFundsFragment : SubmitTransactionFragment() {
// when wallet is loaded, wallet name is set. we can init everything wallet specific here
binding.walletName.text = getString(R.string.label_send_from, it)
binding.hintReadonly.visibility =
if (viewModel.uiLogic.wallet!!.walletConfig.secretStorage == null) View.VISIBLE else View.GONE
if (viewModel.uiLogic.wallet!!.isReadOnly()) View.VISIBLE else View.GONE
enableLayoutChangeAnimations()
})
viewModel.address.observe(viewLifecycleOwner, {
Expand Down
Loading

0 comments on commit 15ad00c

Please sign in to comment.