Updated on 2026-08-14
This commit is contained in:
parent
ae0783b253
commit
b5dde35172
12 changed files with 545 additions and 77 deletions
|
|
@ -2,6 +2,8 @@ package com.tangem.feature.learn2earn.presentation
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import com.tangem.feature.learn2earn.presentation.webView.Learn2earnWebViewActivity
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -10,7 +12,12 @@ class Learn2earnRouter(
|
|||
private val context: Context,
|
||||
) {
|
||||
|
||||
fun openWebView() {
|
||||
context.startActivity(Intent(context, Learn2earnWebViewActivity::class.java))
|
||||
fun openWebView(uri: Uri, rawHeaders: ArrayList<String>) {
|
||||
val intent = Intent(context, Learn2earnWebViewActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(Learn2earnWebViewActivity.EXTRA_WEB_URI, uri.toString())
|
||||
.putStringArrayListExtra(Learn2earnWebViewActivity.EXTRA_WEB_HEADERS, rawHeaders)
|
||||
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,16 @@
|
|||
package com.tangem.feature.learn2earn.presentation
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.feature.learn2earn.domain.api.Learn2earnInteractor
|
||||
import com.tangem.feature.learn2earn.domain.models.RedirectConsequences
|
||||
import com.tangem.feature.learn2earn.domain.models.WebViewHelper
|
||||
import com.tangem.feature.learn2earn.domain.api.WebViewResult
|
||||
import com.tangem.feature.learn2earn.domain.api.WebViewResultHandler
|
||||
import com.tangem.feature.learn2earn.domain.models.PromotionError
|
||||
import com.tangem.feature.learn2earn.presentation.ui.state.*
|
||||
import com.tangem.lib.crypto.models.errors.UserCancelledException
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -20,39 +25,156 @@ class Learn2earnViewModel @Inject constructor(
|
|||
private val interactor: Learn2earnInteractor,
|
||||
private val router: Learn2earnRouter,
|
||||
private val dispatchers: AppCoroutineDispatcherProvider,
|
||||
) : ViewModel(), WebViewHelper {
|
||||
) : ViewModel() {
|
||||
|
||||
var webViewUri: Uri = Uri.parse("https://localhost")
|
||||
var uiState: Learn2earnState by mutableStateOf(
|
||||
Learn2earnState.init(
|
||||
uiActions = UiActions(
|
||||
buttonStoryClick = ::buttonStoryClick,
|
||||
buttonMainClick = ::buttonMainClick,
|
||||
),
|
||||
),
|
||||
)
|
||||
private set
|
||||
|
||||
fun isNeedToShowViewOnStoriesScreen(): Boolean = interactor.isNeedToShowViewOnStoriesScreen()
|
||||
|
||||
fun onStoriesClick() {
|
||||
webViewUri = interactor.buildUriForStories()
|
||||
router.openWebView()
|
||||
init {
|
||||
uiState = uiState.updateStoriesVisibility(interactor.isNeedToShowViewOnStoriesScreen())
|
||||
}
|
||||
|
||||
fun isNeedToShowViewOnWalletScreen(walletId: String, callback: (Boolean) -> Unit) {
|
||||
fun onMainScreenCreated() {
|
||||
updateMainScreenViews()
|
||||
}
|
||||
|
||||
private fun updateMainScreenViews() {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val isNeedToShow = interactor.isNeedToShowViewOnWalletScreen(walletId)
|
||||
withContext(dispatchers.main) {
|
||||
callback(isNeedToShow)
|
||||
if (interactor.isNeedToShowViewOnMainScreen()) {
|
||||
updateUi {
|
||||
uiState.changeGetBounsDescription(getBonusDescription())
|
||||
.updateGetBonusVisibility(isVisible = true)
|
||||
}
|
||||
} else {
|
||||
updateUi { uiState.updateGetBonusVisibility(isVisible = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onMainPageClick(walletId: String, cardId: String, cardPubKey: String) {
|
||||
webViewUri = interactor.buildUriForMainPage(walletId, cardId, cardPubKey)
|
||||
router.openWebView()
|
||||
private fun buttonStoryClick() {
|
||||
router.openWebView(interactor.buildUriForNewUser(), interactor.getBasicAuthHeaders())
|
||||
}
|
||||
|
||||
// region WebViewHelper
|
||||
override fun handleWebViewRedirect(uri: Uri): RedirectConsequences {
|
||||
return interactor.handleWebViewRedirect(uri)
|
||||
private fun buttonMainClick() {
|
||||
if (!interactor.isUserHadPromoCode() && !interactor.isUserRegisteredInPromotion()) {
|
||||
subscribeToWebViewResultEvents()
|
||||
router.openWebView(interactor.buildUriForOldUser(), interactor.getBasicAuthHeaders())
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
updateUi { uiState.updateProgress(showProgress = true) }
|
||||
|
||||
runCatching { interactor.requestAward() }
|
||||
.onSuccess { requestAwardResult ->
|
||||
requestAwardResult.fold(
|
||||
onSuccess = {
|
||||
val onHideDialog = {
|
||||
uiState = uiState.updateGetBonusVisibility(isVisible = false)
|
||||
.hideDialog()
|
||||
}
|
||||
val successDialog = MainScreenState.Dialog.Claimed(
|
||||
onOk = onHideDialog,
|
||||
onDismissRequest = onHideDialog,
|
||||
)
|
||||
updateUi { uiState.showDialog(successDialog) }
|
||||
},
|
||||
onFailure = {
|
||||
val errorDialog = createErrorDialog(it.toDomainError())
|
||||
updateUi {
|
||||
uiState.updateProgress(showProgress = false)
|
||||
.showDialog(errorDialog)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
.onFailure { exception ->
|
||||
updateUi { uiState.updateProgress(showProgress = false) }
|
||||
if (exception is UserCancelledException) return@launch
|
||||
|
||||
val errorDialog = createErrorDialog(exception.toDomainError())
|
||||
updateUi { uiState.showDialog(errorDialog) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getWebViewHeaders(): Map<String, String> {
|
||||
return interactor.getBasicAuthHeaders()
|
||||
private fun getBonusDescription(): MainScreenState.Description {
|
||||
return if (interactor.isUserRegisteredInPromotion()) {
|
||||
MainScreenState.Description.GetBonus
|
||||
} else {
|
||||
MainScreenState.Description.Learn(interactor.getAwardAmount())
|
||||
}
|
||||
}
|
||||
// endregion WebViewHelper
|
||||
|
||||
private fun createErrorDialog(error: PromotionError): MainScreenState.Dialog {
|
||||
return when (error) {
|
||||
is PromotionError.CodeWasNotAppliedInShop -> {
|
||||
val onHideDialog = { uiState = uiState.hideDialog() }
|
||||
MainScreenState.Dialog.PromoCodeNotRegistered(
|
||||
onOk = {
|
||||
uiState = uiState.hideDialog()
|
||||
subscribeToWebViewResultEvents()
|
||||
router.openWebView(interactor.buildUriForNewUser(), interactor.getBasicAuthHeaders())
|
||||
},
|
||||
onCancel = onHideDialog,
|
||||
onDismissRequest = onHideDialog,
|
||||
)
|
||||
}
|
||||
is PromotionError.CodeNotFound,
|
||||
is PromotionError.CodeWasAlreadyUsed,
|
||||
is PromotionError.CardAlreadyHasAward,
|
||||
is PromotionError.WalletAlreadyHasAward,
|
||||
is PromotionError.ProgramNotFound,
|
||||
is PromotionError.ProgramWasEnd,
|
||||
-> {
|
||||
val onHideDialog = {
|
||||
uiState = uiState.hideDialog()
|
||||
.updateGetBonusVisibility(isVisible = false)
|
||||
}
|
||||
MainScreenState.Dialog.Error(
|
||||
error = error,
|
||||
onOk = onHideDialog,
|
||||
onDismissRequest = onHideDialog,
|
||||
)
|
||||
}
|
||||
is PromotionError.UnknownError, PromotionError.NetworkUnreachable -> {
|
||||
val onHideDialog = { uiState = uiState.hideDialog() }
|
||||
MainScreenState.Dialog.Error(
|
||||
error = error,
|
||||
onOk = onHideDialog,
|
||||
onDismissRequest = onHideDialog,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeToWebViewResultEvents() {
|
||||
interactor.webViewResultHandler = object : WebViewResultHandler {
|
||||
override fun handleResult(result: WebViewResult) {
|
||||
interactor.webViewResultHandler = null
|
||||
when (result) {
|
||||
WebViewResult.ReadyForAward -> updateMainScreenViews()
|
||||
WebViewResult.PromoCodeReceived -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateUi(updateBlock: suspend () -> Learn2earnState) {
|
||||
withContext(dispatchers.io) {
|
||||
val newState = updateBlock.invoke()
|
||||
withContext(dispatchers.main) { uiState = newState }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Throwable.toDomainError(): PromotionError {
|
||||
return this as? PromotionError ?: PromotionError.UnknownError(message ?: "Unknown error")
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.Image
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -13,22 +14,27 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerH4
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemTypography
|
||||
import com.tangem.feature.learn2earn.impl.R
|
||||
import com.tangem.feature.learn2earn.presentation.ui.component.GradientCircle
|
||||
import com.tangem.feature.learn2earn.presentation.ui.state.MainScreenState
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun GetBonusAlert(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
internal fun GetBonusView(state: MainScreenState, modifier: Modifier = Modifier) {
|
||||
if (!state.isVisible) return
|
||||
|
||||
val shape = TangemTheme.shapes.roundedCornersMedium
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clickable(onClick = state.onClick)
|
||||
.height(TangemTheme.dimens.size96)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.action,
|
||||
|
|
@ -40,21 +46,33 @@ fun GetBonusAlert(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
|||
modifier = Modifier.fillMaxHeight(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.size16),
|
||||
painter = painterResource(id = R.drawable.img_1inch_logo_42_40),
|
||||
contentDescription = null,
|
||||
)
|
||||
Box(modifier = Modifier.padding(horizontal = TangemTheme.dimens.size16)) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.img_1inch_logo_42_40),
|
||||
alpha = state.logoAlphaValue,
|
||||
contentDescription = null,
|
||||
)
|
||||
if (state.showProgress) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(size = TangemTheme.dimens.size28),
|
||||
color = Color.White,
|
||||
strokeWidth = TangemTheme.dimens.size2,
|
||||
)
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(end = TangemTheme.dimens.size40),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.main_learn_title),
|
||||
text = state.description.title.resolveReference(),
|
||||
style = TangemTypography.body1,
|
||||
color = TangemTheme.colors.text.primary2,
|
||||
)
|
||||
SpacerH4()
|
||||
Text(
|
||||
text = stringResource(id = R.string.main_learn_subtitle),
|
||||
text = state.description.subtitle.resolveReference(),
|
||||
style = TangemTypography.caption,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
|
|
@ -64,8 +82,7 @@ fun GetBonusAlert(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
|||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size40)
|
||||
.padding(end = TangemTheme.dimens.size16)
|
||||
.align(Alignment.CenterEnd)
|
||||
.clickable(onClick = onClick),
|
||||
.align(Alignment.CenterEnd),
|
||||
painter = painterResource(id = R.drawable.ic_chevron_right_24),
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(Color.Gray),
|
||||
|
|
@ -112,9 +129,7 @@ private fun OneInchStoriesContentPreview_Light() {
|
|||
TangemTheme(
|
||||
isDark = false,
|
||||
) {
|
||||
GetBonusAlert(
|
||||
onClick = {},
|
||||
)
|
||||
GetBonusView(makePreviewState())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +139,13 @@ private fun OneInchStoriesContentPreview_Dark() {
|
|||
TangemTheme(
|
||||
isDark = true,
|
||||
) {
|
||||
GetBonusAlert(
|
||||
onClick = {},
|
||||
)
|
||||
GetBonusView(makePreviewState())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun makePreviewState(): MainScreenState = MainScreenState(
|
||||
isVisible = true,
|
||||
onClick = {},
|
||||
description = MainScreenState.Description.Learn("0"),
|
||||
showProgress = false,
|
||||
)
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package com.tangem.feature.learn2earn.presentation.ui
|
||||
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.TextButton
|
||||
import com.tangem.feature.learn2earn.impl.R
|
||||
import com.tangem.feature.learn2earn.presentation.ui.state.MainScreenState
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun Learn2earnDialogs(dialog: MainScreenState.Dialog?) {
|
||||
when (dialog) {
|
||||
is MainScreenState.Dialog.Claimed -> ClaimedDialog(dialog)
|
||||
is MainScreenState.Dialog.PromoCodeNotRegistered -> PromoCodeNotRegisteredDialog(dialog)
|
||||
is MainScreenState.Dialog.Error -> ErrorDialog(dialog)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ClaimedDialog(dialog: MainScreenState.Dialog.Claimed) {
|
||||
AlertDialog(
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.common_success))
|
||||
},
|
||||
text = {
|
||||
Text(text = stringResource(id = R.string.main_promotion_credited))
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
text = stringResource(id = R.string.common_ok),
|
||||
onClick = dialog.onOk,
|
||||
)
|
||||
},
|
||||
onDismissRequest = dialog.onDismissRequest,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PromoCodeNotRegisteredDialog(dialog: MainScreenState.Dialog.PromoCodeNotRegistered) {
|
||||
AlertDialog(
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.common_error))
|
||||
},
|
||||
text = {
|
||||
Text(text = stringResource(id = R.string.main_promotion_no_purchase))
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
text = stringResource(id = R.string.common_cancel),
|
||||
onClick = dialog.onCancel,
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
text = stringResource(id = R.string.common_buy),
|
||||
onClick = dialog.onOk,
|
||||
)
|
||||
},
|
||||
onDismissRequest = dialog.onDismissRequest,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ErrorDialog(dialog: MainScreenState.Dialog.Error) {
|
||||
AlertDialog(
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.common_error))
|
||||
},
|
||||
text = {
|
||||
Text(text = dialog.error.description)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
text = stringResource(id = R.string.common_ok),
|
||||
onClick = dialog.onOk,
|
||||
)
|
||||
},
|
||||
onDismissRequest = dialog.onDismissRequest,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.feature.learn2earn.presentation.ui
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.learn2earn.presentation.Learn2earnViewModel
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun Learn2earnMainPageScreen(viewModel: Learn2earnViewModel, modifier: Modifier = Modifier) {
|
||||
GetBonusView(
|
||||
state = viewModel.uiState.mainScreenState,
|
||||
modifier = modifier
|
||||
.padding(horizontal = TangemTheme.dimens.size16)
|
||||
.padding(vertical = TangemTheme.dimens.size8),
|
||||
)
|
||||
Learn2earnDialogs(viewModel.uiState.mainScreenState.dialog)
|
||||
}
|
||||
|
|
@ -24,9 +24,8 @@ import com.tangem.feature.learn2earn.presentation.ui.component.GradientCircle
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
// TODO: 1inch: make function as internal after adding feature interface
|
||||
@Composable
|
||||
fun StoriesScreen(onLearnClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
fun Learn2earnStoriesScreen(onLearnClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
ContentBackground(
|
||||
modifier = Modifier
|
||||
|
|
@ -111,7 +110,7 @@ private fun OneInchStoriesContentPreview_Light() {
|
|||
TangemTheme(
|
||||
isDark = false,
|
||||
) {
|
||||
StoriesScreen(
|
||||
Learn2earnStoriesScreen(
|
||||
onLearnClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -123,7 +122,7 @@ private fun OneInchStoriesContentPreview_Dark() {
|
|||
TangemTheme(
|
||||
isDark = true,
|
||||
) {
|
||||
StoriesScreen(
|
||||
Learn2earnStoriesScreen(
|
||||
onLearnClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.tangem.feature.learn2earn.presentation.ui.state
|
||||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.feature.learn2earn.domain.models.PromotionError
|
||||
import com.tangem.feature.learn2earn.impl.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class Learn2earnState(
|
||||
val storyScreenState: StoryScreenState,
|
||||
val mainScreenState: MainScreenState,
|
||||
) {
|
||||
companion object
|
||||
}
|
||||
|
||||
data class StoryScreenState(
|
||||
val isVisible: Boolean,
|
||||
val onClick: () -> Unit,
|
||||
)
|
||||
|
||||
data class MainScreenState(
|
||||
val isVisible: Boolean,
|
||||
val onClick: () -> Unit,
|
||||
val description: Description,
|
||||
val showProgress: Boolean,
|
||||
val logoAlphaValue: Float = 1f,
|
||||
val dialog: Dialog? = null,
|
||||
) {
|
||||
|
||||
sealed class Description(val title: TextReference, val subtitle: TextReference) {
|
||||
|
||||
class Learn(awardAmount: String) : Description(
|
||||
TextReference.Res(R.string.main_learn_title),
|
||||
TextReference.Res(R.string.main_learn_subtitle, listOf(awardAmount)),
|
||||
)
|
||||
|
||||
object GetBonus : Description(
|
||||
TextReference.Res(R.string.main_get_bonus_title),
|
||||
TextReference.Res(R.string.main_get_bonus_subtitle),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Dialog {
|
||||
|
||||
data class Claimed(
|
||||
val onOk: () -> Unit,
|
||||
val onDismissRequest: () -> Unit,
|
||||
) : Dialog()
|
||||
|
||||
data class PromoCodeNotRegistered(
|
||||
val onOk: () -> Unit,
|
||||
val onCancel: () -> Unit,
|
||||
val onDismissRequest: () -> Unit,
|
||||
) : Dialog()
|
||||
|
||||
data class Error(
|
||||
val error: PromotionError,
|
||||
val onOk: () -> Unit,
|
||||
val onDismissRequest: () -> Unit,
|
||||
) : Dialog()
|
||||
}
|
||||
}
|
||||
|
||||
class UiActions(
|
||||
val buttonStoryClick: () -> Unit,
|
||||
val buttonMainClick: () -> Unit,
|
||||
)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.tangem.feature.learn2earn.presentation.ui.state
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal fun Learn2earnState.Companion.init(uiActions: UiActions): Learn2earnState {
|
||||
return Learn2earnState(
|
||||
storyScreenState = StoryScreenState(
|
||||
isVisible = false,
|
||||
onClick = uiActions.buttonStoryClick,
|
||||
),
|
||||
mainScreenState = MainScreenState(
|
||||
isVisible = false,
|
||||
onClick = uiActions.buttonMainClick,
|
||||
description = MainScreenState.Description.Learn("0"),
|
||||
showProgress = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun Learn2earnState.updateStoriesVisibility(isVisible: Boolean): Learn2earnState {
|
||||
return if (storyScreenState.isVisible == isVisible) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
storyScreenState = storyScreenState.copy(
|
||||
isVisible = isVisible,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Learn2earnState.updateGetBonusVisibility(isVisible: Boolean): Learn2earnState {
|
||||
return if (mainScreenState.isVisible == isVisible) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
mainScreenState = mainScreenState.copy(
|
||||
isVisible = isVisible,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Learn2earnState.changeGetBounsDescription(description: MainScreenState.Description,): Learn2earnState {
|
||||
return if (mainScreenState.description == description) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
mainScreenState = mainScreenState.copy(
|
||||
description = description,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Learn2earnState.showDialog(dialog: MainScreenState.Dialog): Learn2earnState {
|
||||
return if (mainScreenState.dialog == dialog) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
mainScreenState = mainScreenState.copy(
|
||||
dialog = dialog,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Learn2earnState.hideDialog(): Learn2earnState {
|
||||
return if (mainScreenState.dialog == null) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
mainScreenState = mainScreenState.copy(
|
||||
dialog = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
internal fun Learn2earnState.updateProgress(showProgress: Boolean): Learn2earnState {
|
||||
return if (mainScreenState.showProgress == showProgress) {
|
||||
this
|
||||
} else {
|
||||
copy(
|
||||
mainScreenState = mainScreenState.copy(
|
||||
showProgress = showProgress,
|
||||
logoAlphaValue = if (showProgress) 0.2f else 1f,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,11 @@
|
|||
package com.tangem.feature.learn2earn.presentation
|
||||
package com.tangem.feature.learn2earn.presentation.webView
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.ActionBar
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.tangem.feature.learn2earn.domain.models.RedirectConsequences
|
||||
import com.tangem.feature.learn2earn.domain.models.WebViewHelper
|
||||
import com.tangem.feature.learn2earn.impl.R
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
|
|
@ -19,7 +15,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
@AndroidEntryPoint
|
||||
class Learn2earnWebViewActivity : AppCompatActivity() {
|
||||
|
||||
private val learn2earnViewModel by viewModels<Learn2earnViewModel>()
|
||||
private val viewModel by viewModels<WebViewViewModel>()
|
||||
|
||||
private lateinit var actionBar: ActionBar
|
||||
private lateinit var webView: WebView
|
||||
|
|
@ -28,24 +24,27 @@ class Learn2earnWebViewActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_web_view)
|
||||
|
||||
val webViewData = viewModel.extractData(intent)
|
||||
|
||||
setSupportActionBar(findViewById(R.id.toolbar))
|
||||
actionBar = supportActionBar!!
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
actionBar.setDisplayShowHomeEnabled(true)
|
||||
actionBar.title = learn2earnViewModel.webViewUri.authority
|
||||
|
||||
actionBar.title = webViewData.uri.authority
|
||||
webView = findViewById(R.id.web_view)
|
||||
|
||||
webView.settings.javaScriptEnabled = true
|
||||
webView.settings.domStorageEnabled = true
|
||||
webView.settings.loadsImagesAutomatically = true
|
||||
|
||||
webView.webViewClient = Learn2earnWebViewClient(
|
||||
helper = learn2earnViewModel,
|
||||
helper = viewModel,
|
||||
headers = webViewData.headers,
|
||||
finishSessionHandler = { finish() },
|
||||
)
|
||||
webView.loadUrl(
|
||||
learn2earnViewModel.webViewUri.toString(),
|
||||
learn2earnViewModel.getWebViewHeaders(),
|
||||
webViewData.uri.toString(),
|
||||
webViewData.headers,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -66,25 +65,9 @@ class Learn2earnWebViewActivity : AppCompatActivity() {
|
|||
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
private class Learn2earnWebViewClient(
|
||||
private val helper: WebViewHelper,
|
||||
private val finishSessionHandler: () -> Unit,
|
||||
) : WebViewClient() {
|
||||
|
||||
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
||||
when (helper.handleWebViewRedirect(request.url)) {
|
||||
RedirectConsequences.NOTHING -> Unit
|
||||
RedirectConsequences.PROCEED -> {
|
||||
val headers = helper.getWebViewHeaders().toMutableMap()
|
||||
request.requestHeaders?.let { headers.putAll(it) }
|
||||
view.loadUrl(request.url.toString(), headers)
|
||||
}
|
||||
RedirectConsequences.FINISH_SESSION -> {
|
||||
finishSessionHandler.invoke()
|
||||
}
|
||||
}
|
||||
return true
|
||||
companion object {
|
||||
const val EXTRA_WEB_URI = "webViewUri"
|
||||
const val EXTRA_WEB_HEADERS = "webViewHeaders"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.feature.learn2earn.presentation.webView
|
||||
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import com.tangem.feature.learn2earn.domain.api.RedirectConsequences
|
||||
import com.tangem.feature.learn2earn.domain.api.WebViewRedirectHandler
|
||||
import timber.log.Timber
|
||||
|
||||
internal class Learn2earnWebViewClient(
|
||||
private val helper: WebViewRedirectHandler,
|
||||
private val headers: Map<String, String>,
|
||||
private val finishSessionHandler: () -> Unit,
|
||||
) : WebViewClient() {
|
||||
|
||||
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
||||
Timber.d("url: ${request.url}")
|
||||
when (helper.handleRedirect(request.url)) {
|
||||
RedirectConsequences.PROCEED -> {
|
||||
val mergedHeaders = headers.toMutableMap()
|
||||
request.requestHeaders?.let { mergedHeaders.putAll(it) }
|
||||
view.loadUrl(request.url.toString(), mergedHeaders)
|
||||
}
|
||||
RedirectConsequences.FINISH_SESSION -> {
|
||||
finishSessionHandler.invoke()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.feature.learn2earn.presentation.webView
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.tangem.feature.learn2earn.domain.HeadersConverter
|
||||
import com.tangem.feature.learn2earn.domain.api.RedirectConsequences
|
||||
import com.tangem.feature.learn2earn.domain.api.WebViewRedirectHandler
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@HiltViewModel
|
||||
class WebViewViewModel @Inject constructor(
|
||||
private val handler: WebViewRedirectHandler,
|
||||
) : ViewModel(), WebViewRedirectHandler {
|
||||
|
||||
override fun handleRedirect(uri: Uri): RedirectConsequences {
|
||||
return handler.handleRedirect(uri)
|
||||
}
|
||||
|
||||
fun extractData(intent: Intent): WebViewData {
|
||||
val uriString = intent.getStringExtra(Learn2earnWebViewActivity.EXTRA_WEB_URI)!!
|
||||
val rawHeaders = intent.getStringArrayListExtra(Learn2earnWebViewActivity.EXTRA_WEB_HEADERS) ?: ArrayList()
|
||||
|
||||
return WebViewData(
|
||||
uri = Uri.parse(uriString),
|
||||
headers = HeadersConverter().convertBack(rawHeaders),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class WebViewData(
|
||||
val uri: Uri,
|
||||
val headers: Map<String, String>,
|
||||
)
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
android:id="@+id/app_bar"
|
||||
style="@style/Widget.MaterialComponents.Toolbar.Surface"
|
||||
android:layout_width="match_parent"
|
||||
app:liftOnScroll="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue