Skip to content

Commit 664277d

Browse files
authored
Merge pull request #1182 from soramitsu/staging
Staging to master
2 parents f660b3e + b21bc0a commit 664277d

File tree

58 files changed

+937
-352
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+937
-352
lines changed

app/src/main/java/jp/co/soramitsu/app/root/domain/RootInteractor.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import jp.co.soramitsu.wallet.impl.data.buyToken.ExternalProvider
1717
import jp.co.soramitsu.wallet.impl.domain.interfaces.WalletRepository
1818
import kotlinx.coroutines.Dispatchers
1919
import kotlinx.coroutines.flow.Flow
20-
import kotlinx.coroutines.flow.filter
21-
import kotlinx.coroutines.flow.first
2220
import kotlinx.coroutines.flow.flowOf
2321
import kotlinx.coroutines.withContext
2422

@@ -42,8 +40,6 @@ class RootInteractor(
4240
}
4341

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

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ apply plugin: "org.sonarqube"
55
buildscript {
66
ext {
77
// App version
8-
versionName = '3.5.6'
9-
versionCode = 188
8+
versionName = '3.6.1'
9+
versionCode = 192
1010

1111
// SDK and tools
1212
compileSdkVersion = 34
1313
minSdkVersion = 24
14-
targetSdkVersion = 33
14+
targetSdkVersion = 34
1515

1616
composeCompilerVersion = '1.5.11'
1717

common/src/main/java/jp/co/soramitsu/common/base/BaseComposeBottomSheetDialogFragment.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package jp.co.soramitsu.common.base
22

33
import android.annotation.SuppressLint
4+
import android.graphics.Rect
45
import android.os.Bundle
56
import android.view.LayoutInflater
67
import android.view.View
@@ -83,6 +84,15 @@ abstract class BaseComposeBottomSheetDialogFragment<T : BaseViewModel> : BottomS
8384
isHideable = errorDialogState.isHideable
8485
)
8586
}
87+
view.viewTreeObserver.addOnGlobalLayoutListener {
88+
val r = Rect()
89+
// r will be populated with the coordinates of your view that area still visible.
90+
view.getWindowVisibleDisplayFrame(r)
91+
val heightDiff: Int = view.rootView.height - (r.bottom - r.top)
92+
93+
// if more than 100 pixels, its probably a keyboard...
94+
viewModel.isSoftKeyboardOpenFlow.value = heightDiff > 500
95+
}
8696
}
8797

8898
protected fun showErrorDialog(

common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import androidx.lifecycle.lifecycleScope
1212
import jp.co.soramitsu.common.R
1313
import jp.co.soramitsu.common.presentation.ErrorDialog
1414
import jp.co.soramitsu.common.utils.Event
15+
import jp.co.soramitsu.common.utils.EventCollector
1516
import jp.co.soramitsu.common.utils.EventObserver
1617
import jp.co.soramitsu.common.utils.bindTo
1718
import jp.co.soramitsu.common.utils.dp
1819
import kotlinx.coroutines.flow.Flow
1920
import kotlinx.coroutines.flow.FlowCollector
21+
import kotlinx.coroutines.launch
2022

2123
abstract class BaseFragment<T : BaseViewModel> : Fragment {
2224

@@ -90,6 +92,16 @@ abstract class BaseFragment<T : BaseViewModel> : Fragment {
9092
)
9193
}
9294

95+
inline fun <V> Flow<Event<V>>.collectEvent(crossinline observer: (V) -> Unit) {
96+
lifecycleScope.launch {
97+
collect(
98+
EventCollector {
99+
observer.invoke(it)
100+
}
101+
)
102+
}
103+
}
104+
93105
inline fun <V> Flow<V>.observe(noinline collector: suspend (V) -> Unit) {
94106
lifecycleScope.launchWhenResumed {
95107
collect(FlowCollector(collector))

common/src/main/java/jp/co/soramitsu/common/base/BaseViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import jp.co.soramitsu.common.validation.ValidationSystem
1717
import kotlin.coroutines.CoroutineContext
1818
import kotlinx.coroutines.CoroutineScope
1919
import kotlinx.coroutines.flow.Flow
20+
import kotlinx.coroutines.flow.MutableStateFlow
2021
import kotlinx.coroutines.flow.SharingStarted
2122
import kotlinx.coroutines.flow.shareIn
2223

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

40+
open val isSoftKeyboardOpenFlow: MutableStateFlow<Boolean> = MutableStateFlow(false)
41+
3942
fun showMessage(text: String) {
4043
_messageLiveData.value = Event(text)
4144
}

common/src/main/java/jp/co/soramitsu/common/compose/component/EnterAmountScreen.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ data class EnterAmountViewState(
2323
val buttonState: ButtonViewState
2424
)
2525

26-
@OptIn(ExperimentalComposeUiApi::class)
2726
@Composable
2827
fun EnterAmountScreen(
2928
state: EnterAmountViewState,
29+
isSoftKeyboardOpen: Boolean = false,
3030
onNavigationClick: () -> Unit,
3131
onAmountInput: (BigDecimal?) -> Unit,
32+
onQuickAmountInput: ((Double) -> Unit)? = null,
3233
onNextClick: () -> Unit
3334
) {
3435
val keyboardController = LocalSoftwareKeyboardController.current
@@ -56,6 +57,15 @@ fun EnterAmountScreen(
5657
.height(48.dp)
5758
)
5859
MarginVertical(margin = 16.dp)
60+
if (onQuickAmountInput != null && isSoftKeyboardOpen) {
61+
QuickInput(
62+
values = QuickAmountInput.entries.toTypedArray(),
63+
onQuickAmountInput = {
64+
keyboardController?.hide()
65+
onQuickAmountInput(it)
66+
}
67+
)
68+
}
5969
}
6070
}
6171
}
@@ -82,7 +92,7 @@ private fun EnterAmountScreenPreview() {
8292
)
8393
FearlessTheme {
8494
BottomSheetScreen {
85-
EnterAmountScreen(state, {}, {}, {})
95+
EnterAmountScreen(state, false, {}, {}, {}, {})
8696
}
8797
}
8898
}

common/src/main/java/jp/co/soramitsu/common/compose/component/QuickInput.kt

Lines changed: 84 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package jp.co.soramitsu.common.compose.component
22

3+
import android.content.Context
4+
import android.graphics.Rect
5+
import android.view.ViewTreeObserver
6+
import android.view.inputmethod.InputMethodManager
37
import androidx.compose.foundation.background
48
import androidx.compose.foundation.clickable
59
import androidx.compose.foundation.layout.Box
@@ -9,16 +13,24 @@ import androidx.compose.foundation.layout.fillMaxHeight
913
import androidx.compose.foundation.layout.height
1014
import androidx.compose.foundation.layout.padding
1115
import androidx.compose.runtime.Composable
16+
import androidx.compose.runtime.DisposableEffect
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.runtime.setValue
1221
import androidx.compose.ui.Alignment
1322
import androidx.compose.ui.ExperimentalComposeUiApi
1423
import androidx.compose.ui.Modifier
24+
import androidx.compose.ui.platform.LocalContext
1525
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
26+
import androidx.compose.ui.platform.LocalView
1627
import androidx.compose.ui.res.stringResource
1728
import androidx.compose.ui.tooling.preview.Preview
1829
import androidx.compose.ui.unit.dp
1930
import jp.co.soramitsu.common.R
2031
import jp.co.soramitsu.common.compose.theme.backgroundBlack
2132

33+
2234
interface QuickInput {
2335
val label: String
2436
val value: Double
@@ -37,52 +49,82 @@ enum class QuickAmountInput(
3749
@OptIn(ExperimentalComposeUiApi::class)
3850
@Composable
3951
fun QuickInput(
40-
values: Array<out QuickInput>,
4152
modifier: Modifier = Modifier,
53+
values: Array<out QuickInput> = QuickAmountInput.entries.toTypedArray(),
4254
onQuickAmountInput: (amount: Double) -> Unit = {},
4355
onDoneClick: () -> Unit = {}
4456
) {
45-
// todo temporary disable it till the business logic will be refactored
46-
// val keyboardController = LocalSoftwareKeyboardController.current
47-
// Row(
48-
// modifier = modifier
49-
// .background(color = backgroundBlack.copy(alpha = 0.75f))
50-
// .height(44.dp)
51-
// .padding(horizontal = 10.dp)
52-
// ) {
53-
// values.map {
54-
// Box(
55-
// modifier = Modifier
56-
// .fillMaxHeight()
57-
// .clickable {
58-
// onQuickAmountInput(it.value)
59-
// }
60-
// ) {
61-
// B1(
62-
// text = it.label,
63-
// modifier = Modifier
64-
// .align(Alignment.Center)
65-
// .padding(horizontal = 6.dp)
66-
// )
67-
// }
68-
// }
69-
// Spacer(modifier = Modifier.weight(1f))
70-
// Box(
71-
// modifier = Modifier
72-
// .fillMaxHeight()
73-
// .clickable {
74-
// keyboardController?.hide()
75-
// onDoneClick()
76-
// }
77-
// ) {
78-
// H5(
79-
// text = stringResource(id = R.string.common_done),
80-
// modifier = Modifier
81-
// .align(Alignment.Center)
82-
// .padding(horizontal = 6.dp)
83-
// )
84-
// }
85-
// }
57+
var isKeyboardVisible by remember { mutableStateOf(false) }
58+
val rootView = LocalView.current
59+
val localContext = LocalContext.current
60+
61+
DisposableEffect(rootView) {
62+
val rect = Rect()
63+
rootView.getWindowVisibleDisplayFrame(rect)
64+
var previousHeight: Int = rect.height()
65+
val listener = ViewTreeObserver.OnGlobalLayoutListener {
66+
val newHeight: Int = rootView.height
67+
68+
if (previousHeight < newHeight) {
69+
// content decreased - keyboard is shown? check input method
70+
isKeyboardVisible = false
71+
} else if(previousHeight > newHeight) {
72+
val isAcceptingText = (localContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).isAcceptingText
73+
if (isAcceptingText) {
74+
// yeah - this is a keyboard
75+
isKeyboardVisible = true
76+
}
77+
}
78+
79+
80+
previousHeight = newHeight
81+
}
82+
rootView.viewTreeObserver.addOnGlobalLayoutListener(listener)
83+
onDispose {
84+
rootView.viewTreeObserver.removeOnGlobalLayoutListener(listener)
85+
}
86+
}
87+
88+
val keyboardController = LocalSoftwareKeyboardController.current
89+
Row(
90+
modifier = modifier
91+
.background(color = backgroundBlack.copy(alpha = 0.75f))
92+
.height(44.dp)
93+
.padding(horizontal = 10.dp)
94+
) {
95+
values.map {
96+
Box(
97+
modifier = Modifier
98+
.fillMaxHeight()
99+
.clickable {
100+
onQuickAmountInput(it.value)
101+
}
102+
) {
103+
B1(
104+
text = it.label,
105+
modifier = Modifier
106+
.align(Alignment.Center)
107+
.padding(horizontal = 6.dp)
108+
)
109+
}
110+
}
111+
Spacer(modifier = Modifier.weight(1f))
112+
Box(
113+
modifier = Modifier
114+
.fillMaxHeight()
115+
.clickable {
116+
keyboardController?.hide()
117+
onDoneClick()
118+
}
119+
) {
120+
H5(
121+
text = stringResource(id = R.string.common_done),
122+
modifier = Modifier
123+
.align(Alignment.Center)
124+
.padding(horizontal = 6.dp)
125+
)
126+
}
127+
}
86128
}
87129

88130
private enum class TestQuickInput(

common/src/main/java/jp/co/soramitsu/common/utils/Event.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package jp.co.soramitsu.common.utils
22

33
import androidx.lifecycle.Observer
4+
import kotlinx.coroutines.flow.FlowCollector
45

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

@@ -26,3 +27,11 @@ class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Obser
2627
}
2728
}
2829
}
30+
31+
class EventCollector<T>(private val onEventUnhandledContent: (T) -> Unit) : FlowCollector<Event<T>> {
32+
override suspend fun emit(value: Event<T>) {
33+
value.getContentIfNotHandled()?.let { content ->
34+
onEventUnhandledContent(content)
35+
}
36+
}
37+
}

common/src/main/res/values/strings.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
<string name="common_assets_filters_fiat">Fiat balance</string>
163163
<string name="common_assets_filters_name">Name</string>
164164
<string name="common_assets_filters_popularity">Popularity</string>
165+
<string name="common_attention">Attention</string>
165166
<string name="common_available_format">Available: %s</string>
166167
<string name="common_available_networks">Available networks</string>
167168
<string name="common_backup_your_wallet">Wallet backup</string>
@@ -533,6 +534,7 @@
533534
<string name="nft_collection_title">Collection</string>
534535
<string name="nft_creator_title">Creator</string>
535536
<string name="nft_list_empty_message">There aren\'t any NFTs yet. Buy or mint NFTs to see them here.</string>
537+
<string name="nft_load_error">Failed to load NFTs</string>
536538
<string name="nft_owner_title">Owned</string>
537539
<string name="nft_stub_text">NFTs are going to be here soon</string>
538540
<string name="nft_stub_title">Sumimasen!</string>
@@ -759,6 +761,7 @@
759761
<string name="social_media">Social Media</string>
760762
<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>
761763
<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>
764+
<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>
762765
<string name="sora_card_annual_service_fee">€0 annual service fee</string>
763766
<string name="sora_card_blacklisted_countires_title">Excluded of application</string>
764767
<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>
@@ -1145,4 +1148,4 @@
11451148
<string name="what_accounts_for_export">What accounts in the wallet do you want to export?</string>
11461149
<string name="yesterday">Yesterday</string>
11471150
<string name="your_collator">Your collator</string>
1148-
</resources>
1151+
</resources>

core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,10 @@ abstract class ChainDao {
7171
explorersToRemove: List<ChainExplorerLocal>
7272
) {
7373
insertChainExplorers(explorersToAdd)
74-
updateChainExplorers(explorersToAdd)
75-
deleteChainExplorers(explorersToAdd)
74+
updateChainExplorers(explorersToUpdate)
75+
deleteChainExplorers(explorersToRemove)
7676
}
7777

78-
7978
@Delete
8079
protected abstract suspend fun deleteChains(chains: List<ChainLocal>)
8180

feature-account-impl/src/main/java/jp/co/soramitsu/account/impl/domain/AssetNotNeedAccountUseCaseImpl.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package jp.co.soramitsu.account.impl.domain
33
import jp.co.soramitsu.account.api.domain.interfaces.AssetNotNeedAccountUseCase
44
import jp.co.soramitsu.common.domain.SelectedFiat
55
import jp.co.soramitsu.common.model.AssetKey
6+
import jp.co.soramitsu.core.models.Asset
67
import jp.co.soramitsu.coredb.dao.AssetDao
78
import jp.co.soramitsu.coredb.dao.TokenPriceDao
89
import jp.co.soramitsu.coredb.dao.emptyAccountIdValue
@@ -22,7 +23,8 @@ class AssetNotNeedAccountUseCaseImpl(
2223
override suspend fun markChainAssetsNotNeed(chainId: ChainId, metaId: Long) {
2324
val chainAssets = chainRegistry.getChain(chainId).assets
2425
chainAssets.forEach {
25-
val priceId = it.priceProvider?.id?.takeIf { selectedFiat.isUsd() } ?: it.priceId
26+
// todo make better way to check that we support price provider
27+
val priceId = it.priceProvider?.takeIf { selectedFiat.isUsd() && it.type == Asset.PriceProviderType.Chainlink}?.id ?: it.priceId
2628
updateAssetNotNeed(metaId, chainId, it.id, priceId)
2729
}
2830
}

0 commit comments

Comments
 (0)