Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ fun HomeDialogs(
positiveButtonText = stringResource(R.string.renew),
negativeButtonText = stringResource(R.string.cancel),
onUpgrade = {
sendCommand(HomeViewModel.Commands.HideExpiredCTADialog)
sendCommand(HomeViewModel.Commands.GotoProSettings(ProSettingsDestination.ChoosePlan))
sendCommand(HideExpiredCTADialog)
sendCommand(GotoProSettings(ProSettingsDestination.ChoosePlan))
},
onCancel = {
sendCommand(HomeViewModel.Commands.HideExpiredCTADialog)
sendCommand(HideExpiredCTADialog)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.auth.LoginStateRepository
import org.thoughtcrime.securesms.database.RecipientRepository
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.debugmenu.DebugLogGroup
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsDestination
import org.thoughtcrime.securesms.pro.ProStatus
Expand Down Expand Up @@ -172,8 +173,9 @@ class HomeViewModel @Inject constructor(
&& !prefs.hasSeenProExpiring()
){
val validUntil = subscription.type.validUntil

if (validUntil.isBefore(now.plus(7, ChronoUnit.DAYS))) {
val show = validUntil.isBefore(now.plus(7, ChronoUnit.DAYS))
Log.d(DebugLogGroup.PRO_DATA.label, "Home: Pro active but not auto renewing (expiring). Valid until: $validUntil - Should show Expiring CTA? $show")
if (show) {
_dialogsState.update { state ->
state.copy(
proExpiringCTA = ProExpiringCTA(
Expand All @@ -186,9 +188,12 @@ class HomeViewModel @Inject constructor(
else if(subscription.type is ProStatus.Expired
&& !prefs.hasSeenProExpired()) {
val validUntil = subscription.type.expiredAt
val show = now.isBefore(validUntil.plus(30, ChronoUnit.DAYS))

Log.d(DebugLogGroup.PRO_DATA.label, "Home: Pro expired. Expired at: $validUntil - Should show Expired CTA? $show")

// Check if now is within 30 days after expiry
if (now.isBefore(validUntil.plus(30, ChronoUnit.DAYS))) {
if (show) {

_dialogsState.update { state ->
state.copy(proExpiredCTA = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class SettingsViewModel @Inject constructor(
private val inAppReviewManager: InAppReviewManager,
private val avatarUploadManager: AvatarUploadManager,
private val attachmentProcessor: AttachmentProcessor,
val proDetailsRepository: ProDetailsRepository,
private val proDetailsRepository: ProDetailsRepository,
) : ViewModel() {
private val TAG = "SettingsViewModel"

Expand Down Expand Up @@ -156,6 +156,7 @@ class SettingsViewModel @Inject constructor(
}
}

// refreshes the pro details data
viewModelScope.launch {
proDetailsRepository.requestRefresh()
}
Expand Down Expand Up @@ -606,10 +607,6 @@ class SettingsViewModel @Inject constructor(
}
}

private fun refreshSubscriptionData(){
//todo PRO implement properly
}

sealed class AvatarDialogState() {
object NoAvatar : AvatarDialogState()
data class UserAvatar(val data: AvatarUIData) : AvatarDialogState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,16 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
Expand All @@ -39,7 +35,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment.Companion.Center
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
Expand Down Expand Up @@ -71,13 +66,12 @@ import org.thoughtcrime.securesms.ui.theme.bold
fun BaseProSettingsScreen(
disabled: Boolean,
hideHomeAppBar: Boolean = false,
listState: LazyListState = rememberLazyListState(),
onBack: () -> Unit,
onHeaderClick: (() -> Unit)? = null,
extraHeaderContent: @Composable (() -> Unit)? = null,
content: @Composable LazyItemScope.() -> Unit
){
// We need the app bar to start as transparent and slowly go opaque as we scroll
val lazyListState = rememberLazyListState()
// Calculate scroll fraction
val density = LocalDensity.current
val thresholdPx = remember(density) { with(density) { 28.dp.toPx() } } // amount before the appbar gets fully opaque
Expand All @@ -86,9 +80,9 @@ fun BaseProSettingsScreen(
val rawFraction by remember {
derivedStateOf {
when {
lazyListState.layoutInfo.totalItemsCount == 0 -> 0f
lazyListState.firstVisibleItemIndex > 0 -> 1f
else -> (lazyListState.firstVisibleItemScrollOffset / thresholdPx).coerceIn(0f, 1f)
listState.layoutInfo.totalItemsCount == 0 -> 0f
listState.firstVisibleItemIndex > 0 -> 1f
else -> (listState.firstVisibleItemScrollOffset / thresholdPx).coerceIn(0f, 1f)
}
}
}
Expand All @@ -115,7 +109,7 @@ fun BaseProSettingsScreen(
modifier = Modifier
.fillMaxWidth()
.consumeWindowInsets(paddings),
state = lazyListState,
state = listState,
contentPadding = PaddingValues(
start = LocalDimensions.current.spacing,
end = LocalDimensions.current.spacing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ 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.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
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 androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import com.squareup.phrase.Phrase
import network.loki.messenger.R
import org.session.libsession.utilities.NonTranslatableStringConstants
Expand All @@ -37,6 +45,12 @@ fun CancelPlanScreen(
viewModel: ProSettingsViewModel,
onBack: () -> Unit,
) {
LaunchedEffect(Unit) {
// ensuring we get the latest data here
// since we can deep link to this screen without going through the pro home screen
viewModel.ensureCancelState()
}

val state by viewModel.cancelPlanState.collectAsState()

BaseStateProScreen(
Expand Down Expand Up @@ -73,6 +87,17 @@ fun CancelPlan(
onBack: () -> Unit,
) {
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current

// to track if the user came back from the cancel screen in the subscriber's page
var waitingForReturn by rememberSaveable { mutableStateOf(false) }

LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
if (waitingForReturn) {
waitingForReturn = false
sendCommand(ProSettingsViewModel.Commands.OnUserBackFromCancellation)
}
}

BaseCellButtonProSettingsScreen(
disabled = true,
Expand All @@ -82,6 +107,7 @@ fun CancelPlan(
.format().toString(),
dangerButton = true,
onButtonClick = {
waitingForReturn = true
sendCommand(OpenCancelSubscriptionPage)
},
title = Phrase.from(context.getText(R.string.proCancelSorry))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -54,13 +57,7 @@ import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.APP_PRO_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.ICON_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.PRO_KEY
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.GoToCancel
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.GoToChoosePlan
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.GoToRefund
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.OnHeaderClicked
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.OnProStatsClicked
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.SetShowProBadge
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.ShowOpenUrlDialog
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsViewModel.Commands.*
import org.thoughtcrime.securesms.pro.ProDataState
import org.thoughtcrime.securesms.pro.ProStatus
import org.thoughtcrime.securesms.pro.ProStatusManager
Expand Down Expand Up @@ -103,13 +100,26 @@ import org.thoughtcrime.securesms.util.State
fun ProSettingsHomeScreen(
viewModel: ProSettingsViewModel,
inSheet: Boolean,
shouldScrollToTop: Boolean = false,
onScrollToTopConsumed: () -> Unit = {},
onBack: () -> Unit,
) {
val data by viewModel.proSettingsUIState.collectAsState()

val listState = rememberLazyListState()

// check if we requested to scroll to the top
LaunchedEffect(shouldScrollToTop) {
if (shouldScrollToTop) {
listState.scrollToItem(0)
onScrollToTopConsumed()
}
}

ProSettingsHome(
data = data,
inSheet = inSheet,
listState = listState,
sendCommand = viewModel::onCommand,
onBack = onBack,
)
Expand All @@ -120,6 +130,7 @@ fun ProSettingsHomeScreen(
fun ProSettingsHome(
data: ProSettingsViewModel.ProSettingsState,
inSheet: Boolean,
listState: LazyListState,
sendCommand: (ProSettingsViewModel.Commands) -> Unit,
onBack: () -> Unit,
) {
Expand All @@ -132,6 +143,7 @@ fun ProSettingsHome(
BaseProSettingsScreen(
disabled = expiredInMainScreen,
hideHomeAppBar = inSheet,
listState = listState,
onBack = onBack,
onHeaderClick = {
// add a click handling if the subscription state is loading or errored
Expand Down Expand Up @@ -795,9 +807,9 @@ fun ProManage(
.format().toString()
),
icon = R.drawable.ic_refresh_cw,
qaTag = R.string.qa_pro_settings_action_request_refund,
qaTag = R.string.qa_pro_settings_action_recover_plan,
onClick = {
//todo PRO implement
sendCommand(RefeshProDetails)
}
)
}
Expand Down Expand Up @@ -979,6 +991,7 @@ fun PreviewProSettingsPro(
),
inSheet = false,
sendCommand = {},
listState = rememberLazyListState(),
onBack = {},
)
}
Expand All @@ -999,6 +1012,7 @@ fun PreviewProSettingsProLoading(
),
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1020,6 +1034,7 @@ fun PreviewProSettingsProError(
),
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1041,6 +1056,7 @@ fun PreviewProSettingsExpired(
)
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1062,6 +1078,7 @@ fun PreviewProSettingsExpiredInSheet(
)
),
inSheet = true,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1083,6 +1100,7 @@ fun PreviewProSettingsExpiredLoading(
)
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1104,6 +1122,7 @@ fun PreviewProSettingsExpiredError(
)
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1125,6 +1144,7 @@ fun PreviewProSettingsNonPro(
)
),
inSheet = false,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand All @@ -1146,6 +1166,7 @@ fun PreviewProSettingsNonProInSheet(
)
),
inSheet = true,
listState = rememberLazyListState(),
sendCommand = {},
onBack = {},
)
Expand Down
Loading