Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
New Donation
  • Loading branch information
ThomasSession committed Mar 19, 2026
commit c7456295ee70c1f2e556f0a775b38e807bbdbff5
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,11 @@ interface TextSecurePreferences {
const val HAS_CHECKED_DOZE_WHITELIST = "has_checked_doze_whitelist"

// Donation
const val HAS_DONATED = "has_donated"
const val HAS_COPIED_DONATION_URL = "has_copied_donation_url"
const val SEEN_DONATION_CTA_AMOUNT = "seen_donation_cta_amount"
const val LAST_SEEN_DONATION_CTA = "last_seen_donation_cta"
const val SHOW_DONATION_CTA_FROM_POSITIVE_REVIEW = "show_donation_cta_from_positive_review"
const val HAS_DONATED = "has_donated_v2"
const val HAS_COPIED_DONATION_URL = "has_copied_donation_url_v2"
const val SEEN_DONATION_CTA_AMOUNT = "seen_donation_cta_amount_v2"
const val LAST_SEEN_DONATION_CTA = "last_seen_donation_cta_v2"
const val SHOW_DONATION_CTA_FROM_POSITIVE_REVIEW = "show_donation_cta_from_positive_review_v2"

const val DEBUG_HAS_DONATED = "debug_has_donated"
const val DEBUG_HAS_COPIED_DONATION_URL = "debug_has_copied_donation_url"
Expand Down
195 changes: 174 additions & 21 deletions app/src/main/java/org/thoughtcrime/securesms/home/HomeDialogs.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
package org.thoughtcrime.securesms.home

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.retain.retain
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.squareup.phrase.Phrase
import kotlinx.coroutines.delay
import network.loki.messenger.R
Expand All @@ -31,17 +57,33 @@ import org.thoughtcrime.securesms.home.startconversation.StartConversationSheet
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsDestination
import org.thoughtcrime.securesms.ui.dialog.AlertDialog
import org.thoughtcrime.securesms.ui.AnimatedSessionProCTA
import org.thoughtcrime.securesms.ui.BottomFadingEdgeBox
import org.thoughtcrime.securesms.ui.CTAFeature
import org.thoughtcrime.securesms.ui.CTAImage
import org.thoughtcrime.securesms.ui.dialog.DialogButtonData
import org.thoughtcrime.securesms.ui.GetString
import org.thoughtcrime.securesms.ui.dialog.OpenURLAlertDialog
import org.thoughtcrime.securesms.ui.PinProCTA
import org.thoughtcrime.securesms.ui.ProBadgeText
import org.thoughtcrime.securesms.ui.ProCTAFeature
import org.thoughtcrime.securesms.ui.SimpleSessionProCTA
import org.thoughtcrime.securesms.ui.UserProfileModal
import org.thoughtcrime.securesms.ui.components.AccentFillButtonRect
import org.thoughtcrime.securesms.ui.components.TertiaryFillButtonRect
import org.thoughtcrime.securesms.ui.components.annotatedStringResource
import org.thoughtcrime.securesms.ui.dialog.BasicSessionAlertDialog
import org.thoughtcrime.securesms.ui.dialog.DialogBg
import org.thoughtcrime.securesms.ui.dialog.LinkAlertDialog
import org.thoughtcrime.securesms.ui.proBadgeColorDisabled
import org.thoughtcrime.securesms.ui.proBadgeColorStandard
import org.thoughtcrime.securesms.ui.qaTag
import org.thoughtcrime.securesms.ui.shimmerOverlay
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.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.theme.blackAlpha40

@Composable
fun HomeDialogs(
Expand Down Expand Up @@ -211,27 +253,8 @@ fun HomeDialogs(
}

if (showDonation && dialogsState.donationCTA) {
val context = LocalContext.current
SimpleSessionProCTA(
heroImage = R.drawable.cta_hero_flower,
title = Phrase.from(context,R.string.donateSessionHelp)
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()
.toString(),
showProBadge = false,
text = Phrase.from(context,R.string.donateSessionDescription)
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()
.toString(),
positiveButtonText = stringResource(R.string.donate),
negativeButtonText = stringResource(R.string.maybeLater),
onUpgrade = {
sendCommand(HideDonationCTADialog)
sendCommand(ShowDonationConfirmation)
},
onCancel = {
sendCommand(HideDonationCTADialog)
}
DonationDialog(
sendCommand = sendCommand
)
}

Expand All @@ -247,3 +270,133 @@ fun HomeDialogs(
}
}

@Composable
fun DonationDialog(
sendCommand: (HomeViewModel.Commands) -> Unit
) {
val context = LocalContext.current
val onCancel = {
sendCommand(HideDonationCTADialog)
}

val title = Phrase.from(context,R.string.donateSessionHelp) //todo DONV2 proper string
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()

val text = Phrase.from(context,R.string.donateSessionDescription) //todo DONV2 proper string
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()


val titleColor: Color = LocalColors.current.text

BasicSessionAlertDialog(
onDismissRequest = onCancel,
content = {
DialogBg {
BoxWithConstraints(Modifier.fillMaxWidth()) {
val heroMaxHeight = maxHeight * 0.4f
Column(
modifier = Modifier.fillMaxWidth()
.verticalScroll(rememberScrollState())
) {
// hero image
BottomFadingEdgeBox(
modifier = Modifier.heightIn(max = heroMaxHeight),
fadingEdgeHeight = 70.dp,
fadingColor = LocalColors.current.backgroundSecondary,
content = { _ ->
CTAImage(heroImage = R.drawable.cta_hero_donation)
},
)

// content
Column(
modifier = Modifier
.fillMaxWidth()
.padding(LocalDimensions.current.smallSpacing)
) {
// title
Text(
modifier = Modifier
.align(Alignment.CenterHorizontally),
text = annotatedStringResource(title),
textAlign = TextAlign.Center,
style = LocalType.current.h5.copy(color = titleColor),
)

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

// main message
Text(
modifier = Modifier
.qaTag(R.string.qa_cta_body)
.align(Alignment.CenterHorizontally),
text = annotatedStringResource(text),
textAlign = TextAlign.Center,
style = LocalType.current.base.copy(
color = LocalColors.current.textSecondary
)
)

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

// buttons
Row(
Modifier.height(IntrinsicSize.Min)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(
LocalDimensions.current.xsSpacing,
Alignment.CenterHorizontally
),
) {
AccentFillButtonRect(
modifier = Modifier
.qaTag(R.string.qa_cta_button_positive)
.weight(1f)
.shimmerOverlay(),
text = "Read Appeal", //stringResource(R.string.donate), //todo DONV2 proper string
onClick = {
sendCommand(HideDonationCTADialog)
sendCommand(ShowDonationConfirmation)
}
)
}
}
}

IconButton(
onClick = onCancel,
modifier = Modifier
.align(Alignment.TopEnd)
.padding(LocalDimensions.current.xxsSpacing)
.background(
color = blackAlpha40,
shape = CircleShape,
).size(34.dp),
) {
Icon(
painter = painterResource(id = R.drawable.ic_x),
tint = Color.White,
contentDescription = stringResource(R.string.close)
)
}
}
}
}
)
}


@Preview
@Composable
fun PreviewDonationDialog() {
PreviewTheme {
Column(
modifier = Modifier.fillMaxSize()
) {
DonationDialog {}
}
}
}

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.