Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,6 @@ fun ProSettings(
),
subtitle = annotatedStringResource(subtitle),
subtitleColor = subColor,
enabled = !refunding,
endContent = {
Box(
modifier = Modifier.size(LocalDimensions.current.itemButtonIconSpacing)
Expand Down Expand Up @@ -942,7 +941,9 @@ fun ProSettingsFooter(
sendCommand: (ProSettingsViewModel.Commands) -> Unit,
) {
// Manage Pro - Expired has this in the header so exclude it here
if(proStatus !is ProStatus.Expired) {
// We also don't want to show this while refund in process
val refunding = (proStatus as? ProStatus.Active)?.refundInProgress ?: false
if(proStatus !is ProStatus.Expired && !refunding) {
Spacer(Modifier.height(LocalDimensions.current.smallSpacing))
ProManage(
data = proStatus,
Expand Down Expand Up @@ -1025,6 +1026,28 @@ fun PreviewProSettingsPro(
}
}

@Preview
@Composable
fun PreviewProSettingsProiOSRefund(
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
) {
PreviewTheme(colors) {
ProSettingsHome(
data = ProSettingsViewModel.ProSettingsState(
proDataState = ProDataState(
type = previewAutoRenewingApple.copy(refundInProgress = true),
refreshState = State.Success(Unit),
showProBadge = true,
),
),
inSheet = false,
sendCommand = {},
listState = rememberLazyListState(),
onBack = {},
)
}
}

@Preview
@Composable
fun PreviewProSettingsProLoading(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ sealed interface ProSettingsDestination: Parcelable {
@Serializable
@Parcelize
data object RefundSubscription: ProSettingsDestination

@Serializable
@Parcelize
data object RefundInProgress: ProSettingsDestination
}

enum class ProNavHostCustomActions {
Expand Down Expand Up @@ -184,6 +188,15 @@ fun ProSettingsNavHost(
)
}

// Refund In Progress
horizontalSlideComposable<ProSettingsDestination.RefundInProgress> { entry ->
val viewModel = navController.proGraphViewModel(entry, navigator)
RefundInProgressScreen(
viewModel = viewModel,
onBack = handleBack,
)
}

// Cancellation
horizontalSlideComposable<CancelSubscription> { entry ->
val viewModel = navController.proGraphViewModel(entry, navigator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,13 @@ class ProSettingsViewModel @AssistedInject constructor(
// Not loading nor error. If in grace period show a dialog
// otherwise go to the "choose plan" screen
else -> {
// if we in the process of refunding on another platform, show that screen instead
if((_proSettingsUIState.value.proDataState.type as? ProStatus.Active)?.refundInProgress == true){
navigateTo(ProSettingsDestination.RefundInProgress)
return
}

// otherwise handle the "Choose Plan"
val provider = (_proSettingsUIState.value.proDataState.type as? ProStatus.Active)?.providerData
if(_proSettingsUIState.value.inGracePeriod){
_dialogState.update {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package org.thoughtcrime.securesms.preferences.prosettings

import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import com.squareup.phrase.Phrase
import network.loki.messenger.R
import org.session.libsession.utilities.NonTranslatableStringConstants
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.ICON_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.PLATFORM_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.PRO_KEY
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.ShowOpenUrlDialog
import org.thoughtcrime.securesms.pro.ProStatus
import org.thoughtcrime.securesms.pro.getPlatformDisplayName
import org.thoughtcrime.securesms.pro.previewAutoRenewingApple
import org.thoughtcrime.securesms.ui.components.annotatedStringResource
import org.thoughtcrime.securesms.ui.components.iconExternalLink
import org.thoughtcrime.securesms.ui.components.inlineContentMap
import org.thoughtcrime.securesms.ui.theme.LocalColors
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
import org.thoughtcrime.securesms.ui.theme.LocalType
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.theme.ThemeColors
import org.thoughtcrime.securesms.ui.theme.bold


@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun RefundInProgressScreen(
viewModel: ProSettingsViewModel,
onBack: () -> Unit,
) {
val state by viewModel.proSettingsUIState.collectAsState()
val activePlan = state.proDataState.type as? ProStatus.Active ?: return

RefundInProgress(
subscription = activePlan,
sendCommand = viewModel::onCommand,
onBack = onBack,
)
}

@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
@Composable
fun RefundInProgress(
subscription: ProStatus.Active,
sendCommand: (ProSettingsViewModel.Commands) -> Unit,
onBack: () -> Unit,
){
val context = LocalContext.current

BaseCellButtonProSettingsScreen(
disabled = true,
onBack = onBack,
buttonText = stringResource(R.string.theReturn),
dangerButton = false,
onButtonClick = onBack,
title = stringResource(R.string.proRequestedRefund),
){
Column {
Text(
text = stringResource(R.string.nextSteps),
style = LocalType.current.base.bold(),
color = LocalColors.current.text,
)

Spacer(Modifier.height(LocalDimensions.current.xxxsSpacing))

Text(
text = annotatedStringResource(
Phrase.from(context.getText(R.string.proRefundNextSteps))
.put(PLATFORM_KEY, subscription.providerData.getPlatformDisplayName())
.put(PRO_KEY, NonTranslatableStringConstants.PRO)
.put(APP_NAME_KEY, context.getString(R.string.app_name))
.format()
),
style = LocalType.current.base,
color = LocalColors.current.text,
)

Spacer(Modifier.height(LocalDimensions.current.smallSpacing))

Text(
text = stringResource(R.string.helpSupport),
style = LocalType.current.base.bold(),
color = LocalColors.current.text,
)

Spacer(Modifier.height(LocalDimensions.current.xxxsSpacing))

Text(
modifier = Modifier.clickable(
onClick = {
sendCommand(ShowOpenUrlDialog(subscription.providerData.refundSupportUrl))
}
),
text = annotatedStringResource(
Phrase.from(context.getText(R.string.proRefundSupport))
.put(PLATFORM_KEY, subscription.providerData.getPlatformDisplayName())
.put(APP_NAME_KEY, context.getString(R.string.app_name))
.put(ICON_KEY, iconExternalLink)
.format()
),
style = LocalType.current.base,
color = LocalColors.current.text,
inlineContent = inlineContentMap(
textSize = LocalType.current.small.fontSize,
imageColor = LocalColors.current.accentText
)
)
}
}
}

@Preview
@Composable
private fun PreviewUpdatePlan(
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
) {
PreviewTheme(colors) {
RefundInProgress (
subscription = previewAutoRenewingApple,
sendCommand = {},
onBack = {},
)
}
}
Loading