Skip to content

Commit

Permalink
Merge pull request #1182 from soramitsu/staging
Browse files Browse the repository at this point in the history
Staging to master
  • Loading branch information
Deneath authored Jul 22, 2024
2 parents f660b3e + b21bc0a commit 664277d
Show file tree
Hide file tree
Showing 58 changed files with 937 additions and 352 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import jp.co.soramitsu.wallet.impl.data.buyToken.ExternalProvider
import jp.co.soramitsu.wallet.impl.domain.interfaces.WalletRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.withContext

Expand All @@ -42,8 +40,6 @@ class RootInteractor(
}

suspend fun runBalancesUpdate(): Flow<Updater.SideEffect> = withContext(Dispatchers.Default) {
// await all accounts initialized
accountRepository.allMetaAccountsFlow().filter { accounts -> accounts.all { it.initialized } }.filter { it.isNotEmpty() }.first()
return@withContext updateSystem.start().inBackground()
}

Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ apply plugin: "org.sonarqube"
buildscript {
ext {
// App version
versionName = '3.5.6'
versionCode = 188
versionName = '3.6.1'
versionCode = 192

// SDK and tools
compileSdkVersion = 34
minSdkVersion = 24
targetSdkVersion = 33
targetSdkVersion = 34

composeCompilerVersion = '1.5.11'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jp.co.soramitsu.common.base

import android.annotation.SuppressLint
import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand Down Expand Up @@ -83,6 +84,15 @@ abstract class BaseComposeBottomSheetDialogFragment<T : BaseViewModel> : BottomS
isHideable = errorDialogState.isHideable
)
}
view.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
// r will be populated with the coordinates of your view that area still visible.
view.getWindowVisibleDisplayFrame(r)
val heightDiff: Int = view.rootView.height - (r.bottom - r.top)

// if more than 100 pixels, its probably a keyboard...
viewModel.isSoftKeyboardOpenFlow.value = heightDiff > 500
}
}

protected fun showErrorDialog(
Expand Down
12 changes: 12 additions & 0 deletions common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import androidx.lifecycle.lifecycleScope
import jp.co.soramitsu.common.R
import jp.co.soramitsu.common.presentation.ErrorDialog
import jp.co.soramitsu.common.utils.Event
import jp.co.soramitsu.common.utils.EventCollector
import jp.co.soramitsu.common.utils.EventObserver
import jp.co.soramitsu.common.utils.bindTo
import jp.co.soramitsu.common.utils.dp
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.launch

abstract class BaseFragment<T : BaseViewModel> : Fragment {

Expand Down Expand Up @@ -90,6 +92,16 @@ abstract class BaseFragment<T : BaseViewModel> : Fragment {
)
}

inline fun <V> Flow<Event<V>>.collectEvent(crossinline observer: (V) -> Unit) {
lifecycleScope.launch {
collect(
EventCollector {
observer.invoke(it)
}
)
}
}

inline fun <V> Flow<V>.observe(noinline collector: suspend (V) -> Unit) {
lifecycleScope.launchWhenResumed {
collect(FlowCollector(collector))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import jp.co.soramitsu.common.validation.ValidationSystem
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.shareIn

Expand All @@ -36,6 +37,8 @@ open class BaseViewModel : ViewModel(), CoroutineScope {
private val _messageLiveData = MutableLiveData<Event<String>>()
val messageLiveData: LiveData<Event<String>> = _messageLiveData

open val isSoftKeyboardOpenFlow: MutableStateFlow<Boolean> = MutableStateFlow(false)

fun showMessage(text: String) {
_messageLiveData.value = Event(text)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ data class EnterAmountViewState(
val buttonState: ButtonViewState
)

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun EnterAmountScreen(
state: EnterAmountViewState,
isSoftKeyboardOpen: Boolean = false,
onNavigationClick: () -> Unit,
onAmountInput: (BigDecimal?) -> Unit,
onQuickAmountInput: ((Double) -> Unit)? = null,
onNextClick: () -> Unit
) {
val keyboardController = LocalSoftwareKeyboardController.current
Expand Down Expand Up @@ -56,6 +57,15 @@ fun EnterAmountScreen(
.height(48.dp)
)
MarginVertical(margin = 16.dp)
if (onQuickAmountInput != null && isSoftKeyboardOpen) {
QuickInput(
values = QuickAmountInput.entries.toTypedArray(),
onQuickAmountInput = {
keyboardController?.hide()
onQuickAmountInput(it)
}
)
}
}
}
}
Expand All @@ -82,7 +92,7 @@ private fun EnterAmountScreenPreview() {
)
FearlessTheme {
BottomSheetScreen {
EnterAmountScreen(state, {}, {}, {})
EnterAmountScreen(state, false, {}, {}, {}, {})
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package jp.co.soramitsu.common.compose.component

import android.content.Context
import android.graphics.Rect
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
Expand All @@ -9,16 +13,24 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import jp.co.soramitsu.common.R
import jp.co.soramitsu.common.compose.theme.backgroundBlack


interface QuickInput {
val label: String
val value: Double
Expand All @@ -37,52 +49,82 @@ enum class QuickAmountInput(
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun QuickInput(
values: Array<out QuickInput>,
modifier: Modifier = Modifier,
values: Array<out QuickInput> = QuickAmountInput.entries.toTypedArray(),
onQuickAmountInput: (amount: Double) -> Unit = {},
onDoneClick: () -> Unit = {}
) {
// todo temporary disable it till the business logic will be refactored
// val keyboardController = LocalSoftwareKeyboardController.current
// Row(
// modifier = modifier
// .background(color = backgroundBlack.copy(alpha = 0.75f))
// .height(44.dp)
// .padding(horizontal = 10.dp)
// ) {
// values.map {
// Box(
// modifier = Modifier
// .fillMaxHeight()
// .clickable {
// onQuickAmountInput(it.value)
// }
// ) {
// B1(
// text = it.label,
// modifier = Modifier
// .align(Alignment.Center)
// .padding(horizontal = 6.dp)
// )
// }
// }
// Spacer(modifier = Modifier.weight(1f))
// Box(
// modifier = Modifier
// .fillMaxHeight()
// .clickable {
// keyboardController?.hide()
// onDoneClick()
// }
// ) {
// H5(
// text = stringResource(id = R.string.common_done),
// modifier = Modifier
// .align(Alignment.Center)
// .padding(horizontal = 6.dp)
// )
// }
// }
var isKeyboardVisible by remember { mutableStateOf(false) }
val rootView = LocalView.current
val localContext = LocalContext.current

DisposableEffect(rootView) {
val rect = Rect()
rootView.getWindowVisibleDisplayFrame(rect)
var previousHeight: Int = rect.height()
val listener = ViewTreeObserver.OnGlobalLayoutListener {
val newHeight: Int = rootView.height

if (previousHeight < newHeight) {
// content decreased - keyboard is shown? check input method
isKeyboardVisible = false
} else if(previousHeight > newHeight) {
val isAcceptingText = (localContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).isAcceptingText
if (isAcceptingText) {
// yeah - this is a keyboard
isKeyboardVisible = true
}
}


previousHeight = newHeight
}
rootView.viewTreeObserver.addOnGlobalLayoutListener(listener)
onDispose {
rootView.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
}

val keyboardController = LocalSoftwareKeyboardController.current
Row(
modifier = modifier
.background(color = backgroundBlack.copy(alpha = 0.75f))
.height(44.dp)
.padding(horizontal = 10.dp)
) {
values.map {
Box(
modifier = Modifier
.fillMaxHeight()
.clickable {
onQuickAmountInput(it.value)
}
) {
B1(
text = it.label,
modifier = Modifier
.align(Alignment.Center)
.padding(horizontal = 6.dp)
)
}
}
Spacer(modifier = Modifier.weight(1f))
Box(
modifier = Modifier
.fillMaxHeight()
.clickable {
keyboardController?.hide()
onDoneClick()
}
) {
H5(
text = stringResource(id = R.string.common_done),
modifier = Modifier
.align(Alignment.Center)
.padding(horizontal = 6.dp)
)
}
}
}

private enum class TestQuickInput(
Expand Down
9 changes: 9 additions & 0 deletions common/src/main/java/jp/co/soramitsu/common/utils/Event.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jp.co.soramitsu.common.utils

import androidx.lifecycle.Observer
import kotlinx.coroutines.flow.FlowCollector

open class Event<out T>(private val content: T) {

Expand All @@ -26,3 +27,11 @@ class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Obser
}
}
}

class EventCollector<T>(private val onEventUnhandledContent: (T) -> Unit) : FlowCollector<Event<T>> {
override suspend fun emit(value: Event<T>) {
value.getContentIfNotHandled()?.let { content ->
onEventUnhandledContent(content)
}
}
}
5 changes: 4 additions & 1 deletion common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
<string name="common_assets_filters_fiat">Fiat balance</string>
<string name="common_assets_filters_name">Name</string>
<string name="common_assets_filters_popularity">Popularity</string>
<string name="common_attention">Attention</string>
<string name="common_available_format">Available: %s</string>
<string name="common_available_networks">Available networks</string>
<string name="common_backup_your_wallet">Wallet backup</string>
Expand Down Expand Up @@ -533,6 +534,7 @@
<string name="nft_collection_title">Collection</string>
<string name="nft_creator_title">Creator</string>
<string name="nft_list_empty_message">There aren\'t any NFTs yet. Buy or mint NFTs to see them here.</string>
<string name="nft_load_error">Failed to load NFTs</string>
<string name="nft_owner_title">Owned</string>
<string name="nft_stub_text">NFTs are going to be here soon</string>
<string name="nft_stub_title">Sumimasen!</string>
Expand Down Expand Up @@ -759,6 +761,7 @@
<string name="social_media">Social Media</string>
<string name="sora_bridge_amount_less_fee">The amount you\'re trying to transfer is insufficient to cover the transaction fees on the %s network. Although the transaction won\'t process, you\'ll still be charged the fees on the Sora network.</string>
<string name="sora_bridge_low_amount_format_alert">Currently, there\'s a min. amount %s for bridging to ensure the stability and security of the SORA Network. We appreciate your understanding.</string>
<string name="sora_bridge_low_amount_format_alert_2">Currently, there\'s a min. amount %s for bridging to ensure the stability and security. We appreciate your understanding.</string>
<string name="sora_card_annual_service_fee">€0 annual service fee</string>
<string name="sora_card_blacklisted_countires_title">Excluded of application</string>
<string name="sora_card_blacklisted_countires_warning"><![CDATA[Residents from <b>certain countries<br>can not apply</b> for SORA Card at this moment<br><a href=\"https://soracard.com/blacklist/\">See the list</a>]]></string>
Expand Down Expand Up @@ -1145,4 +1148,4 @@
<string name="what_accounts_for_export">What accounts in the wallet do you want to export?</string>
<string name="yesterday">Yesterday</string>
<string name="your_collator">Your collator</string>
</resources>
</resources>
5 changes: 2 additions & 3 deletions core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ abstract class ChainDao {
explorersToRemove: List<ChainExplorerLocal>
) {
insertChainExplorers(explorersToAdd)
updateChainExplorers(explorersToAdd)
deleteChainExplorers(explorersToAdd)
updateChainExplorers(explorersToUpdate)
deleteChainExplorers(explorersToRemove)
}


@Delete
protected abstract suspend fun deleteChains(chains: List<ChainLocal>)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package jp.co.soramitsu.account.impl.domain
import jp.co.soramitsu.account.api.domain.interfaces.AssetNotNeedAccountUseCase
import jp.co.soramitsu.common.domain.SelectedFiat
import jp.co.soramitsu.common.model.AssetKey
import jp.co.soramitsu.core.models.Asset
import jp.co.soramitsu.coredb.dao.AssetDao
import jp.co.soramitsu.coredb.dao.TokenPriceDao
import jp.co.soramitsu.coredb.dao.emptyAccountIdValue
Expand All @@ -22,7 +23,8 @@ class AssetNotNeedAccountUseCaseImpl(
override suspend fun markChainAssetsNotNeed(chainId: ChainId, metaId: Long) {
val chainAssets = chainRegistry.getChain(chainId).assets
chainAssets.forEach {
val priceId = it.priceProvider?.id?.takeIf { selectedFiat.isUsd() } ?: it.priceId
// todo make better way to check that we support price provider
val priceId = it.priceProvider?.takeIf { selectedFiat.isUsd() && it.type == Asset.PriceProviderType.Chainlink}?.id ?: it.priceId
updateAssetNotNeed(metaId, chainId, it.id, priceId)
}
}
Expand Down
Loading

0 comments on commit 664277d

Please sign in to comment.