From a1a703b76547ae6ca3dcf4219d6ac009494bfa7a Mon Sep 17 00:00:00 2001 From: Marvin <295208132+marvinctl@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:45:55 +0530 Subject: [PATCH 1/2] feat!: simplify support prompts and app flags --- CHANGELOG.md | 5 + .../commons/activities/AboutActivity.kt | 19 +-- .../commons/activities/BaseSimpleActivity.kt | 2 +- .../activities/CustomizationActivity.kt | 8 +- .../compose/extensions/ActivityExtensions.kt | 21 +-- .../fossify/commons/dialogs/DonateDialog.kt | 36 +++-- .../commons/dialogs/FeatureLockedDialog.kt | 138 ------------------ .../commons/dialogs/PurchaseThankYouDialog.kt | 19 +-- .../fossify/commons/dialogs/RateAppDialog.kt | 34 +++++ .../commons/dialogs/UpgradeToProDialog.kt | 127 ---------------- .../fossify/commons/extensions/Activity.kt | 25 +--- .../org/fossify/commons/extensions/Context.kt | 18 +-- .../commons/extensions/SupportPrompt.kt | 38 +++++ .../org/fossify/commons/helpers/BaseConfig.kt | 20 ++- .../org/fossify/commons/helpers/Constants.kt | 8 +- .../commons/views/PurchaseThankYouItem.kt | 8 +- .../main/res/layout/dialog_feature_locked.xml | 31 ---- .../main/res/layout/dialog_upgrade_to_pro.xml | 12 -- commons/src/main/res/values/bools.xml | 4 +- commons/src/main/res/values/strings.xml | 90 +----------- samples/src/foss/res/values/bools.xml | 3 +- samples/src/gplay/res/values/bools.xml | 4 + .../samples/activities/MainActivity.kt | 36 +---- .../samples/activities/TestDialogActivity.kt | 22 --- samples/src/prepaid/res/values/bools.xml | 5 - 25 files changed, 157 insertions(+), 576 deletions(-) create mode 100644 CHANGELOG.md delete mode 100644 commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt create mode 100644 commons/src/main/kotlin/org/fossify/commons/dialogs/RateAppDialog.kt delete mode 100644 commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt create mode 100644 commons/src/main/kotlin/org/fossify/commons/extensions/SupportPrompt.kt delete mode 100644 commons/src/main/res/layout/dialog_feature_locked.xml delete mode 100644 commons/src/main/res/layout/dialog_upgrade_to_pro.xml create mode 100644 samples/src/gplay/res/values/bools.xml delete mode 100644 samples/src/prepaid/res/values/bools.xml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..db61d99a5d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +## Unreleased + +- Free apps show one rating prompt after five days on Play and one support prompt after ten days on all flavors. +- Simplify distribution flags and remove obsolete Pro upgrade and feature-lock APIs. +- Keep Thank You access to custom fonts and shared customization. diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/AboutActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/AboutActivity.kt index 343f4ab4a6..4add354a59 100644 --- a/commons/src/main/kotlin/org/fossify/commons/activities/AboutActivity.kt +++ b/commons/src/main/kotlin/org/fossify/commons/activities/AboutActivity.kt @@ -67,7 +67,7 @@ class AboutActivity : BaseComposeActivity() { val resources = context.resources AppThemeSurface { val showGoogleRelations = - remember { !resources.getBoolean(R.bool.hide_google_relations) } + remember { resources.getBoolean(R.bool.is_google_play_build) } val showGithubRelations = showGithubRelations() val showDonationLinks = remember { !isThankYouInstalled() || !showGoogleRelations } val onEmailClickAlertDialogState = getOnEmailClickAlertDialogState() @@ -135,11 +135,8 @@ class AboutActivity : BaseComposeActivity() { @Composable private fun getPackageInfo(): Pair { - var versionName = remember { intent.getStringExtra(APP_VERSION_NAME) ?: "" } + val versionName = remember { intent.getStringExtra(APP_VERSION_NAME) ?: "" } val packageName = remember { intent.getStringExtra(APP_PACKAGE_NAME) ?: "" } - if (baseConfig.appId.removeSuffix(".debug").endsWith(".pro")) { - versionName += " ${getString(R.string.pro)}" - } val fullVersion = stringResource(R.string.version_placeholder, versionName) return Pair(fullVersion, packageName) @@ -240,8 +237,8 @@ class AboutActivity : BaseComposeActivity() { private fun onInviteClick() { val storeUrl = when { - resources.getBoolean(R.bool.hide_google_relations) -> getGithubUrl() - else -> getStoreUrl() + resources.getBoolean(R.bool.is_google_play_build) -> getStoreUrl() + else -> getGithubUrl() } val text = String.format(getString(R.string.share_text), appName, storeUrl) @@ -261,10 +258,10 @@ class AboutActivity : BaseComposeActivity() { } private fun onDonateClick() { - if (resources.getBoolean(R.bool.hide_google_relations)) { - startActivity(Intent(applicationContext, DonationActivity::class.java)) - } else { + if (resources.getBoolean(R.bool.is_google_play_build)) { launchPurchaseThankYouIntent() + } else { + startActivity(Intent(applicationContext, DonationActivity::class.java)) } } @@ -282,7 +279,7 @@ class AboutActivity : BaseComposeActivity() { } private fun onPrivacyPolicyClick() { - val appId = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro") + val appId = baseConfig.appId.removeSuffix(".debug") .removePrefix("org.fossify.") val url = "https://www.fossify.org/policy/$appId" launchViewIntent(url) diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt index b9f640ec42..57a48e6693 100644 --- a/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt +++ b/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt @@ -1316,7 +1316,7 @@ abstract class BaseSimpleActivity : EdgeToEdgeActivity() { } private fun getExportSettingsFilename(): String { - val appName = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro") + val appName = baseConfig.appId.removeSuffix(".debug") .removePrefix("org.fossify.") return "$appName-settings_${getCurrentFormattedDateTime()}" } diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt index 1ab0022263..cf0cebd19a 100644 --- a/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt +++ b/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt @@ -28,7 +28,7 @@ import org.fossify.commons.extensions.getProperTextColor import org.fossify.commons.extensions.getThemeId import org.fossify.commons.extensions.isDynamicTheme import org.fossify.commons.extensions.isFontFile -import org.fossify.commons.extensions.isOrWasThankYouInstalled +import org.fossify.commons.extensions.hasThankYouUnlock import org.fossify.commons.extensions.isThankYouFontsSupported import org.fossify.commons.extensions.isSystemInDarkMode import org.fossify.commons.extensions.isThankYouInstalled @@ -607,8 +607,8 @@ class CustomizationActivity : BaseSimpleActivity() { val selectedType = selected as Int if (selectedType == FONT_TYPE_CUSTOM) { if ( - !resources.getBoolean(R.bool.hide_google_relations) - && !isOrWasThankYouInstalled(allowPretend = false) + resources.getBoolean(R.bool.is_google_play_build) + && !hasThankYouUnlock() ) { PurchaseThankYouDialog(this) return@RadioGroupDialog @@ -917,7 +917,7 @@ class CustomizationActivity : BaseSimpleActivity() { private fun showOrHideThankYouFeatures() { val showThankYouFeatures = canAccessGlobalConfig() - || !resources.getBoolean(R.bool.hide_google_relations) + || resources.getBoolean(R.bool.is_google_play_build) binding.applyToAllNote.beVisibleIf(!canAccessGlobalConfig()) binding.applyToAllHolder.beVisibleIf(showThankYouFeatures) binding.applyToAllDivider.root.beVisibleIf(showThankYouFeatures) diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/extensions/ActivityExtensions.kt b/commons/src/main/kotlin/org/fossify/commons/compose/extensions/ActivityExtensions.kt index af4496b3a7..77c40ae37a 100644 --- a/commons/src/main/kotlin/org/fossify/commons/compose/extensions/ActivityExtensions.kt +++ b/commons/src/main/kotlin/org/fossify/commons/compose/extensions/ActivityExtensions.kt @@ -13,13 +13,10 @@ import org.fossify.commons.R import org.fossify.commons.extensions.baseConfig import org.fossify.commons.extensions.checkAppIconColor import org.fossify.commons.extensions.getAppIconColors -import org.fossify.commons.extensions.getCanAppBeUpgraded import org.fossify.commons.extensions.getInternalStoragePath -import org.fossify.commons.extensions.isAProApp import org.fossify.commons.extensions.isAppInstalledOnSDCard -import org.fossify.commons.extensions.isOrWasThankYouInstalled -import org.fossify.commons.extensions.launchViewIntent import org.fossify.commons.extensions.random +import org.fossify.commons.extensions.showAutomaticSupportPromptIfEligible import org.fossify.commons.extensions.toggleAppIconColor import org.fossify.commons.extensions.updateSDCardPath import org.fossify.commons.helpers.isOreoMr1Plus @@ -27,8 +24,6 @@ import org.fossify.commons.models.Release fun ComponentActivity.appLaunchedCompose( appId: String, - showUpgradeDialog: () -> Unit, - showDonateDialog: () -> Unit, ) { baseConfig.internalStoragePath = getInternalStoragePath() updateSDCardPath() @@ -64,15 +59,7 @@ fun ComponentActivity.appLaunchedCompose( } baseConfig.appRunCount++ - if (baseConfig.appRunCount % 30 == 0 && !isAProApp()) { - if (!resources.getBoolean(R.bool.hide_google_relations)) { - if (getCanAppBeUpgraded()) { - showUpgradeDialog() - } else if (!isOrWasThankYouInstalled()) { - showDonateDialog() - } - } - } + showAutomaticSupportPromptIfEligible() } fun ComponentActivity.checkWhatsNewCompose(releases: List, currVersion: Int, showWhatsNewDialog: (List) -> Unit) { @@ -91,10 +78,6 @@ fun ComponentActivity.checkWhatsNewCompose(releases: List, currVersion: baseConfig.lastVersion = currVersion } -fun ComponentActivity.upgradeToPro() { - launchViewIntent("https://fossify.org/upgrade_to_pro") -} - const val DEVELOPER_PLAY_STORE_URL = "https://play.google.com/store/apps/dev?id=7297838378654322558" const val FAKE_VERSION_APP_LABEL = "You are using a fake version of the app. For your own safety download the original one from www.fossify.org. Thanks" diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt index f63090aa9c..75b748e1c8 100644 --- a/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt +++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt @@ -1,6 +1,7 @@ package org.fossify.commons.dialogs import android.app.Activity +import android.content.Intent import android.text.Html import android.text.method.LinkMovementMethod import android.widget.TextView @@ -22,6 +23,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.sp import androidx.compose.ui.window.DialogProperties import org.fossify.commons.R +import org.fossify.commons.activities.DonationActivity import org.fossify.commons.compose.alert_dialog.* import org.fossify.commons.compose.components.LinkifyTextComponent import org.fossify.commons.compose.extensions.MyDevices @@ -32,35 +34,49 @@ import org.fossify.commons.compose.theme.SimpleTheme import org.fossify.commons.databinding.DialogDonateBinding import org.fossify.commons.extensions.* -class DonateDialog(val activity: Activity) { +class DonateDialog(val activity: Activity, onShown: () -> Unit = {}) { init { + val isGooglePlayBuild = activity.resources.getBoolean(R.bool.is_google_play_build) + val positiveButtonId = if (isGooglePlayBuild) R.string.purchase else R.string.donate val view = DialogDonateBinding.inflate(activity.layoutInflater, null, false).apply { dialogDonateImage.applyColorFilter(activity.getProperTextColor()) - dialogDonateText.text = Html.fromHtml(activity.getString(R.string.donate_short)) + val messageId = if (isGooglePlayBuild) R.string.donate_short else R.string.donation_prompt + dialogDonateText.text = Html.fromHtml(activity.getString(messageId)) dialogDonateText.movementMethod = LinkMovementMethod.getInstance() dialogDonateImage.setOnClickListener { - activity.launchViewIntent(R.string.thank_you_url) + activity.openDonationOptions() } } activity.getAlertDialogBuilder() - .setPositiveButton(R.string.purchase) { _, _ -> activity.launchViewIntent(R.string.thank_you_url) } + .setPositiveButton(positiveButtonId) { _, _ -> activity.openDonationOptions() } .setNegativeButton(R.string.later, null) .apply { - activity.setupDialogStuff(view.root, this, cancelOnTouchOutside = false) + activity.setupDialogStuff(view.root, this) { dialog -> + if (dialog.isShowing) { + onShown() + } + } } } } +private fun Activity.openDonationOptions() { + if (resources.getBoolean(R.bool.is_google_play_build)) { + launchPurchaseThankYouIntent() + } else { + startActivity(Intent(this, DonationActivity::class.java)) + } +} + @Composable fun DonateAlertDialog( alertDialogState: AlertDialogState, modifier: Modifier = Modifier ) { val localContext = LocalContext.current.getActivity() - val donateIntent = { - localContext.launchViewIntent(R.string.thank_you_url) - } + val isGooglePlayBuild = localContext.resources.getBoolean(R.bool.is_google_play_build) + val donateIntent = { localContext.openDonationOptions() } androidx.compose.material3.AlertDialog( containerColor = dialogContainerColor, modifier = modifier @@ -81,7 +97,7 @@ fun DonateAlertDialog( donateIntent() alertDialogState.hide() }) { - Text(text = stringResource(id = R.string.purchase)) + Text(text = stringResource(id = if (isGooglePlayBuild) R.string.purchase else R.string.donate)) } }, title = { @@ -107,7 +123,7 @@ fun DonateAlertDialog( } }, text = { - val source = stringResource(id = R.string.donate_short) + val source = stringResource(id = if (isGooglePlayBuild) R.string.donate_short else R.string.donation_prompt) LinkifyTextComponent( fontSize = 16.sp, removeUnderlines = false, diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt deleted file mode 100644 index f9aa1907b9..0000000000 --- a/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt +++ /dev/null @@ -1,138 +0,0 @@ -package org.fossify.commons.dialogs - -import android.app.Activity -import android.text.Html -import android.text.method.LinkMovementMethod -import android.widget.TextView -import androidx.appcompat.app.AlertDialog -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Lock -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.DialogProperties -import org.fossify.commons.R -import org.fossify.commons.compose.alert_dialog.* -import org.fossify.commons.compose.components.LinkifyTextComponent -import org.fossify.commons.compose.extensions.MyDevices -import org.fossify.commons.compose.extensions.composeDonateIntent -import org.fossify.commons.compose.extensions.rememberMutableInteractionSource -import org.fossify.commons.compose.theme.AppThemeSurface -import org.fossify.commons.compose.theme.SimpleTheme -import org.fossify.commons.databinding.DialogFeatureLockedBinding -import org.fossify.commons.extensions.* - -class FeatureLockedDialog(val activity: Activity, val callback: () -> Unit) { - private var dialog: AlertDialog? = null - - init { - val view = DialogFeatureLockedBinding.inflate(activity.layoutInflater, null, false) - view.featureLockedImage.applyColorFilter(activity.getProperTextColor()) - - activity.getAlertDialogBuilder() - .setPositiveButton(R.string.purchase, null) - .setNegativeButton(R.string.later) { _, _ -> dismissDialog() } - .setOnDismissListener { dismissDialog() } - .apply { - activity.setupDialogStuff(view.root, this, cancelOnTouchOutside = false) { alertDialog -> - dialog = alertDialog - view.featureLockedDescription.text = Html.fromHtml(activity.getString(R.string.features_locked)) - view.featureLockedDescription.movementMethod = LinkMovementMethod.getInstance() - - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - activity.launchPurchaseThankYouIntent() - } - } - } - } - - fun dismissDialog() { - dialog?.dismiss() - callback() - } -} - -@Composable -fun FeatureLockedAlertDialog( - alertDialogState: AlertDialogState, - modifier: Modifier = Modifier, - cancelCallback: () -> Unit -) { - val donateIntent = composeDonateIntent() - androidx.compose.material3.AlertDialog( - containerColor = dialogContainerColor, - modifier = modifier - .dialogBorder(), - properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false), - onDismissRequest = cancelCallback, - shape = dialogShape, - tonalElevation = dialogElevation, - dismissButton = { - TextButton(onClick = { - cancelCallback() - alertDialogState.hide() - }) { - Text(text = stringResource(id = R.string.later)) - } - }, - confirmButton = { - TextButton(onClick = { - donateIntent() - }) { - Text(text = stringResource(id = R.string.purchase)) - } - }, - title = { - Box( - Modifier.fillMaxWidth(), - contentAlignment = Alignment.Center - ) { - Image( - Icons.Filled.Lock, - contentDescription = null, - modifier = Modifier - .size(SimpleTheme.dimens.icon.large) - .clickable( - indication = null, - interactionSource = rememberMutableInteractionSource(), - onClick = { - donateIntent() - } - ), - colorFilter = ColorFilter.tint(dialogTextColor) - ) - } - }, - text = { - val source = stringResource(id = R.string.features_locked) - LinkifyTextComponent( - fontSize = 16.sp, - removeUnderlines = false, - modifier = Modifier.fillMaxWidth(), - textAlignment = TextView.TEXT_ALIGNMENT_CENTER - ) { - source.fromHtml() - } - } - ) -} - -@Composable -@MyDevices -private fun FeatureLockedAlertDialogPreview() { - AppThemeSurface { - FeatureLockedAlertDialog(alertDialogState = rememberAlertDialogState()) { - - } - } -} diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt index 1f6f00cffe..138207356a 100644 --- a/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt +++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt @@ -7,9 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.sp import androidx.compose.ui.window.DialogProperties @@ -18,7 +16,6 @@ import org.fossify.commons.compose.alert_dialog.* import org.fossify.commons.compose.components.LinkifyTextComponent import org.fossify.commons.compose.extensions.MyDevices import org.fossify.commons.compose.extensions.composeDonateIntent -import org.fossify.commons.compose.extensions.config import org.fossify.commons.compose.theme.AppThemeSurface import org.fossify.commons.databinding.DialogPurchaseThankYouBinding import org.fossify.commons.extensions.* @@ -26,12 +23,7 @@ import org.fossify.commons.extensions.* class PurchaseThankYouDialog(val activity: Activity) { init { val view = DialogPurchaseThankYouBinding.inflate(activity.layoutInflater, null, false).apply { - var text = activity.getString(R.string.purchase_thank_you) - if (activity.baseConfig.appId.removeSuffix(".debug").endsWith(".pro")) { - text += "

${activity.getString(R.string.shared_theme_note)}" - } - - purchaseThankYou.text = Html.fromHtml(text) + purchaseThankYou.text = Html.fromHtml(activity.getString(R.string.purchase_thank_you)) purchaseThankYou.movementMethod = LinkMovementMethod.getInstance() purchaseThankYou.removeUnderlines() } @@ -50,11 +42,7 @@ fun PurchaseThankYouAlertDialog( alertDialogState: AlertDialogState, modifier: Modifier = Modifier, ) { - val localContext = LocalContext.current val donateIntent = composeDonateIntent() - val appId = remember { - localContext.config.appId - } androidx.compose.material3.AlertDialog( containerColor = dialogContainerColor, modifier = modifier @@ -79,10 +67,7 @@ fun PurchaseThankYouAlertDialog( } }, text = { - var text = stringResource(R.string.purchase_thank_you) - if (appId.removeSuffix(".debug").endsWith(".pro")) { - text += "

${stringResource(R.string.shared_theme_note)}" - } + val text = stringResource(R.string.purchase_thank_you) LinkifyTextComponent( fontSize = 16.sp, removeUnderlines = false, diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/RateAppDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/RateAppDialog.kt new file mode 100644 index 0000000000..2e401f54ad --- /dev/null +++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/RateAppDialog.kt @@ -0,0 +1,34 @@ +package org.fossify.commons.dialogs + +import android.app.Activity +import org.fossify.commons.R +import org.fossify.commons.databinding.DialogMessageBinding +import org.fossify.commons.extensions.getAlertDialogBuilder +import org.fossify.commons.extensions.setupDialogStuff + +internal class RateAppDialog( + activity: Activity, + onRate: () -> Unit, + onShown: () -> Unit, +) { + init { + val view = DialogMessageBinding.inflate(activity.layoutInflater, null, false).apply { + message.setText(R.string.rate_app_prompt) + } + + activity.getAlertDialogBuilder() + .setPositiveButton(R.string.rate_this_app) { _, _ -> onRate() } + .setNegativeButton(R.string.later, null) + .apply { + activity.setupDialogStuff( + view = view.root, + dialog = this, + titleId = R.string.rate_this_app, + ) { dialog -> + if (dialog.isShowing) { + onShown() + } + } + } + } +} diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt deleted file mode 100644 index 31efa88f38..0000000000 --- a/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt +++ /dev/null @@ -1,127 +0,0 @@ -package org.fossify.commons.dialogs - -import android.app.Activity -import androidx.appcompat.app.AlertDialog -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.DialogProperties -import org.fossify.commons.R -import org.fossify.commons.compose.alert_dialog.* -import org.fossify.commons.compose.extensions.MyDevices -import org.fossify.commons.compose.extensions.andThen -import org.fossify.commons.compose.theme.AppThemeSurface -import org.fossify.commons.compose.theme.SimpleTheme -import org.fossify.commons.databinding.DialogUpgradeToProBinding -import org.fossify.commons.extensions.getAlertDialogBuilder -import org.fossify.commons.extensions.launchUpgradeToProIntent -import org.fossify.commons.extensions.launchViewIntent -import org.fossify.commons.extensions.setupDialogStuff - -class UpgradeToProDialog(val activity: Activity) { - - init { - val view = DialogUpgradeToProBinding.inflate(activity.layoutInflater, null, false).apply { - upgradeToPro.text = activity.getString(R.string.upgrade_to_pro_long) - } - - activity.getAlertDialogBuilder() - .setPositiveButton(R.string.upgrade) { _, _ -> upgradeApp() } - .setNeutralButton(R.string.more_info, null) // do not dismiss the dialog on pressing More Info - .setNegativeButton(R.string.later, null) - .apply { - activity.setupDialogStuff(view.root, this, R.string.upgrade_to_pro, cancelOnTouchOutside = false) { alertDialog -> - alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener { - moreInfo() - } - } - } - } - - private fun upgradeApp() { - activity.launchUpgradeToProIntent() - } - - private fun moreInfo() { - activity.launchViewIntent("https://fossify.org/upgrade_to_pro") - } -} - -@Composable -fun UpgradeToProAlertDialog( - alertDialogState: AlertDialogState, - modifier: Modifier = Modifier, - onMoreInfoClick: () -> Unit, - onUpgradeClick: () -> Unit -) { - AlertDialog( - onDismissRequest = {}, - text = { - Text( - text = stringResource(id = R.string.upgrade_to_pro_long), - color = dialogTextColor, - fontSize = 16.sp, - ) - }, - title = { - Text( - text = stringResource(id = R.string.upgrade_to_pro), - color = dialogTextColor, - fontSize = 21.sp, - fontWeight = FontWeight.Bold, - ) - }, - tonalElevation = dialogElevation, - shape = dialogShape, - containerColor = dialogContainerColor, - confirmButton = { - Row( - Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End - ) { - TextButton( - onClick = onMoreInfoClick, // do not dismiss the dialog on pressing More Info - modifier = Modifier.weight(0.2f) - ) { - Text(text = stringResource(id = R.string.more_info)) - } - TextButton( - onClick = alertDialogState::hide, - modifier = Modifier.padding(horizontal = SimpleTheme.dimens.padding.medium) - ) { - Text(text = stringResource(id = R.string.later)) - } - TextButton( - onClick = onUpgradeClick andThen alertDialogState::hide, - ) { - Text(text = stringResource(id = R.string.upgrade)) - } - } - }, - modifier = modifier.dialogBorder(), - properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false) - ) -} - -@MyDevices -@Composable -private fun UpgradeToProAlertDialogPreview() { - AppThemeSurface { - UpgradeToProAlertDialog( - alertDialogState = rememberAlertDialogState(), - onMoreInfoClick = {}, - onUpgradeClick = {}, - ) - } -} diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt index 3acdac26a8..4188822e7e 100644 --- a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt +++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt @@ -49,10 +49,8 @@ import org.fossify.commons.dialogs.AppSideloadedDialog import org.fossify.commons.dialogs.ConfirmationAdvancedDialog import org.fossify.commons.dialogs.ConfirmationDialog import org.fossify.commons.dialogs.CustomIntervalPickerDialog -import org.fossify.commons.dialogs.DonateDialog import org.fossify.commons.dialogs.RadioGroupDialog import org.fossify.commons.dialogs.SecurityDialog -import org.fossify.commons.dialogs.UpgradeToProDialog import org.fossify.commons.dialogs.WhatsNewDialog import org.fossify.commons.dialogs.WritePermissionDialog import org.fossify.commons.dialogs.WritePermissionDialog.WritePermissionDialogMode @@ -127,19 +125,7 @@ fun Activity.appLaunched(appId: String) { } baseConfig.appRunCount++ - if (baseConfig.appRunCount % 30 == 0 && !isAProApp()) { - if (!resources.getBoolean(R.bool.hide_google_relations)) { - showDonateOrUpgradeDialog() - } - } -} - -fun Activity.showDonateOrUpgradeDialog() { - if (getCanAppBeUpgraded()) { - UpgradeToProDialog(this) - } else if (!isOrWasThankYouInstalled()) { - DonateDialog(this) - } + showAutomaticSupportPromptIfEligible() } fun Activity.isAppInstalledOnSDCard(): Boolean = try { @@ -402,15 +388,6 @@ fun Activity.launchPurchaseThankYouIntent() { launchViewIntent(getString(R.string.thank_you_url)) } -fun Activity.launchUpgradeToProIntent() { - hideKeyboard() - try { - launchViewIntent("market://details?id=${baseConfig.appId.removeSuffix(".debug")}.pro") - } catch (ignored: Exception) { - launchViewIntent(getStoreUrl()) - } -} - fun Activity.launchMoreAppsFromUsIntent() { launchViewIntent(DEVELOPER_PLAY_STORE_URL) } diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt index 1cd124ad1b..097a5bd0da 100644 --- a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt +++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt @@ -124,7 +124,6 @@ import org.fossify.commons.helpers.isQPlus import org.fossify.commons.helpers.isRPlus import org.fossify.commons.helpers.isSPlus import org.fossify.commons.helpers.isUpsideDownCakePlus -import org.fossify.commons.helpers.proPackages import org.fossify.commons.models.AlarmSound import org.fossify.commons.models.BlockedNumber import org.joda.time.DateTimeConstants @@ -597,7 +596,7 @@ fun Context.canAccessGlobalConfig(): Boolean { return isThankYouInstalled() && ContextCompat.checkSelfPermission(this, PERMISSION_WRITE_GLOBAL_SETTINGS) == PERMISSION_GRANTED } -fun Context.isOrWasThankYouInstalled(allowPretend: Boolean = true): Boolean { +fun Context.hasThankYouUnlock(): Boolean { return when { isThankYouInstalled() -> { if (!baseConfig.hadThankYouInstalled) { @@ -606,21 +605,10 @@ fun Context.isOrWasThankYouInstalled(allowPretend: Boolean = true): Boolean { true } baseConfig.hadThankYouInstalled -> true - resources.getBoolean(R.bool.pretend_thank_you_installed) && allowPretend -> true else -> false } } -fun Context.isAProApp() = packageName.startsWith("org.fossify.") && packageName.removeSuffix(".debug").endsWith(".pro") - -fun Context.addLockedLabelIfNeeded(stringId: Int): String { - return if (isOrWasThankYouInstalled()) { - getString(stringId) - } else { - "${getString(stringId)} (${getString(R.string.feature_locked)})" - } -} - fun Context.isPackageInstalled(pkgName: String): Boolean { return try { packageManager.getPackageInfo(pkgName, 0) @@ -843,10 +831,6 @@ fun Context.saveExifRotation(exif: ExifInterface, degrees: Int) { fun Context.getLaunchIntent() = packageManager.getLaunchIntentForPackage(baseConfig.appId) -fun Context.getCanAppBeUpgraded() = proPackages.contains(baseConfig.appId.removeSuffix(".debug").removePrefix("org.fossify.")) - -fun Context.getProUrl() = "https://play.google.com/store/apps/details?id=${baseConfig.appId.removeSuffix(".debug")}.pro" - fun Context.getStoreUrl() = "https://play.google.com/store/apps/details?id=${packageName.removeSuffix(".debug")}" fun Context.getTimeFormat() = if (baseConfig.use24HourFormat) TIME_FORMAT_24 else TIME_FORMAT_12 diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/SupportPrompt.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/SupportPrompt.kt new file mode 100644 index 0000000000..c7701b3aad --- /dev/null +++ b/commons/src/main/kotlin/org/fossify/commons/extensions/SupportPrompt.kt @@ -0,0 +1,38 @@ +package org.fossify.commons.extensions + +import android.app.Activity +import org.fossify.commons.R +import org.fossify.commons.dialogs.DonateDialog +import org.fossify.commons.dialogs.RateAppDialog + +private const val DAY_MILLIS = 24L * 60L * 60L * 1000L +private const val RATING_DELAY_MILLIS = 5L * DAY_MILLIS +private const val DONATION_DELAY_MILLIS = 10L * DAY_MILLIS + +internal fun Activity.showAutomaticSupportPromptIfEligible() { + if (resources.getBoolean(R.bool.is_paid_app)) { + return + } + + val config = baseConfig + val isSupporter = hasThankYouUnlock() + val now = System.currentTimeMillis() + if (config.supportPromptFirstLaunchTimestamp == 0L) { + config.supportPromptFirstLaunchTimestamp = now + return + } + + val elapsed = now - config.supportPromptFirstLaunchTimestamp + if ( + resources.getBoolean(R.bool.is_google_play_build) && + !config.wasRatePromptShown && elapsed >= RATING_DELAY_MILLIS + ) { + RateAppDialog(this, onRate = { launchAppRatingPage() }) { + config.wasRatePromptShown = true + } + } else if (!config.wasDonationPromptShown && elapsed >= DONATION_DELAY_MILLIS && !isSupporter) { + DonateDialog(this) { + config.wasDonationPromptShown = true + } + } +} diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt index 66dfae5d42..c3b9aafe76 100644 --- a/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt +++ b/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt @@ -29,6 +29,18 @@ open class BaseConfig(val context: Context) { get() = prefs.getInt(APP_RUN_COUNT, 0) set(appRunCount) = prefs.edit().putInt(APP_RUN_COUNT, appRunCount).apply() + var supportPromptFirstLaunchTimestamp: Long + get() = prefs.getLong(SUPPORT_PROMPT_FIRST_LAUNCH_TIMESTAMP, 0L) + set(timestamp) = prefs.edit().putLong(SUPPORT_PROMPT_FIRST_LAUNCH_TIMESTAMP, timestamp).apply() + + var wasRatePromptShown: Boolean + get() = prefs.getBoolean(WAS_RATE_PROMPT_SHOWN, prefs.getBoolean(WAS_RATE_PROMPT_ACCEPTED, false)) + set(wasShown) = prefs.edit().putBoolean(WAS_RATE_PROMPT_SHOWN, wasShown).apply() + + var wasDonationPromptShown: Boolean + get() = prefs.getBoolean(WAS_DONATION_PROMPT_SHOWN, false) + set(wasShown) = prefs.edit().putBoolean(WAS_DONATION_PROMPT_SHOWN, wasShown).apply() + var lastVersion: Int get() = prefs.getInt(LAST_VERSION, 0) set(lastVersion) = prefs.edit().putInt(LAST_VERSION, lastVersion).apply() @@ -367,10 +379,6 @@ open class BaseConfig(val context: Context) { get() = prefs.getBoolean(WAS_BEFORE_ASKING_SHOWN, false) set(wasBeforeAskingShown) = prefs.edit().putBoolean(WAS_BEFORE_ASKING_SHOWN, wasBeforeAskingShown).apply() - var wasInitialUpgradeToProShown: Boolean - get() = prefs.getBoolean(WAS_INITIAL_UPGRADE_TO_PRO_SHOWN, false) - set(wasInitialUpgradeToProShown) = prefs.edit().putBoolean(WAS_INITIAL_UPGRADE_TO_PRO_SHOWN, wasInitialUpgradeToProShown).apply() - var wasAppIconCustomizationWarningShown: Boolean get() = prefs.getBoolean(WAS_APP_ICON_CUSTOMIZATION_WARNING_SHOWN, false) set(wasAppIconCustomizationWarningShown) = prefs.edit().putBoolean(WAS_APP_ICON_CUSTOMIZATION_WARNING_SHOWN, wasAppIconCustomizationWarningShown) @@ -404,10 +412,6 @@ open class BaseConfig(val context: Context) { get() = prefs.getBoolean(WAS_OTG_HANDLED, false) set(wasOTGHandled) = prefs.edit().putBoolean(WAS_OTG_HANDLED, wasOTGHandled).apply() - var wasUpgradedFromFreeShown: Boolean - get() = prefs.getBoolean(WAS_UPGRADED_FROM_FREE_SHOWN, false) - set(wasUpgradedFromFreeShown) = prefs.edit().putBoolean(WAS_UPGRADED_FROM_FREE_SHOWN, wasUpgradedFromFreeShown).apply() - var wasSortingByNumericValueAdded: Boolean get() = prefs.getBoolean(WAS_SORTING_BY_NUMERIC_VALUE_ADDED, false) set(wasSortingByNumericValueAdded) = prefs.edit().putBoolean(WAS_SORTING_BY_NUMERIC_VALUE_ADDED, wasSortingByNumericValueAdded).apply() diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt index 4aef023e30..62d54b78b4 100644 --- a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt +++ b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt @@ -81,6 +81,10 @@ const val YEAR_SECONDS = YEAR_MINUTES * 60 // shared preferences const val PREFS_KEY = "Prefs" const val APP_RUN_COUNT = "app_run_count" +const val SUPPORT_PROMPT_FIRST_LAUNCH_TIMESTAMP = "support_prompt_first_launch_timestamp" +const val WAS_RATE_PROMPT_SHOWN = "was_rate_prompt_shown" +const val WAS_DONATION_PROMPT_SHOWN = "was_donation_prompt_shown" +const val WAS_RATE_PROMPT_ACCEPTED = "was_rate_prompt_accepted" const val LAST_VERSION = "last_version" const val SD_TREE_URI = "tree_uri_2" const val PRIMARY_ANDROID_DATA_TREE_URI = "primary_android_data_tree_uri_2" @@ -151,12 +155,10 @@ const val WIDGET_ID_TO_MEASURE = "widget_id_to_measure" const val WAS_ORANGE_ICON_CHECKED = "was_orange_icon_checked" const val WAS_APP_ON_SD_SHOWN = "was_app_on_sd_shown" const val WAS_BEFORE_ASKING_SHOWN = "was_before_asking_shown" -const val WAS_INITIAL_UPGRADE_TO_PRO_SHOWN = "was_initial_upgrade_to_pro_shown" const val WAS_APP_ICON_CUSTOMIZATION_WARNING_SHOWN = "was_app_icon_customization_warning_shown" const val APP_SIDELOADING_STATUS = "app_sideloading_status" const val DATE_FORMAT = "date_format" const val WAS_OTG_HANDLED = "was_otg_handled_2" -const val WAS_UPGRADED_FROM_FREE_SHOWN = "was_upgraded_from_free_shown" const val WAS_SORTING_BY_NUMERIC_VALUE_ADDED = "was_sorting_by_numeric_value_added" const val WAS_FOLDER_LOCKING_NOTICE_SHOWN = "was_folder_locking_notice_shown" const val LAST_RENAME_USED = "last_rename_used" @@ -608,8 +610,6 @@ fun getConflictResolution(resolutions: LinkedHashMap, path: String) } } -val proPackages = arrayListOf() - fun mydebug(message: String) = Log.e("DEBUG", message) fun getQuestionMarks(size: Int) = ("?," * size).trimEnd(',') diff --git a/commons/src/main/kotlin/org/fossify/commons/views/PurchaseThankYouItem.kt b/commons/src/main/kotlin/org/fossify/commons/views/PurchaseThankYouItem.kt index f3b5b6b05e..4e9f2da864 100644 --- a/commons/src/main/kotlin/org/fossify/commons/views/PurchaseThankYouItem.kt +++ b/commons/src/main/kotlin/org/fossify/commons/views/PurchaseThankYouItem.kt @@ -10,7 +10,7 @@ import androidx.lifecycle.findViewTreeLifecycleOwner import org.fossify.commons.R import org.fossify.commons.extensions.beGoneIf import org.fossify.commons.extensions.findActivity -import org.fossify.commons.extensions.isOrWasThankYouInstalled +import org.fossify.commons.extensions.hasThankYouUnlock import org.fossify.commons.extensions.launchPurchaseThankYouIntent import org.fossify.commons.extensions.toast @@ -21,7 +21,7 @@ class PurchaseThankYouItem @JvmOverloads constructor( ) : RelativeLayout(context, attrs, defStyle) { private var lifecycleOwner: LifecycleOwner? = null - private val hideGoogleRelations = resources.getBoolean(R.bool.hide_google_relations) + private val isGooglePlayBuild = resources.getBoolean(R.bool.is_google_play_build) private val lifecycleObserver = object : DefaultLifecycleObserver { override fun onResume(owner: LifecycleOwner) { updateVisibility() @@ -39,7 +39,7 @@ class PurchaseThankYouItem @JvmOverloads constructor( findViewById(R.id.purchase_thank_you_value).text = subtitle updateVisibility() - if (!context.isOrWasThankYouInstalled(allowPretend = false)) { + if (!context.hasThankYouUnlock()) { setOnClickListener { val activity = context.findActivity() if (activity != null) { @@ -65,7 +65,7 @@ class PurchaseThankYouItem @JvmOverloads constructor( fun updateVisibility() { beGoneIf( - context.isOrWasThankYouInstalled(allowPretend = false) || hideGoogleRelations + context.hasThankYouUnlock() || !isGooglePlayBuild ) } } diff --git a/commons/src/main/res/layout/dialog_feature_locked.xml b/commons/src/main/res/layout/dialog_feature_locked.xml deleted file mode 100644 index 1e1a1efd46..0000000000 --- a/commons/src/main/res/layout/dialog_feature_locked.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - diff --git a/commons/src/main/res/layout/dialog_upgrade_to_pro.xml b/commons/src/main/res/layout/dialog_upgrade_to_pro.xml deleted file mode 100644 index c14465621a..0000000000 --- a/commons/src/main/res/layout/dialog_upgrade_to_pro.xml +++ /dev/null @@ -1,12 +0,0 @@ - - diff --git a/commons/src/main/res/values/bools.xml b/commons/src/main/res/values/bools.xml index f5c7c50159..e0b6af867d 100644 --- a/commons/src/main/res/values/bools.xml +++ b/commons/src/main/res/values/bools.xml @@ -1,6 +1,6 @@ false - false - false + false + false diff --git a/commons/src/main/res/values/strings.xml b/commons/src/main/res/values/strings.xml index f3edff4241..0ba124e27e 100644 --- a/commons/src/main/res/values/strings.xml +++ b/commons/src/main/res/values/strings.xml @@ -102,7 +102,6 @@ Change view type Grid - Grid (Pro) Uneven Grid List Increase column count @@ -178,7 +177,6 @@ Filter - Filter (Pro) No items found. Change filter @@ -386,7 +384,6 @@ Caution: Certain launchers may not handle app icon customization correctly. If the icon disappears, attempt launching the app through Google Play or a widget, if accessible. After launching, restore the default green icon color #106D1F. In extreme cases, reinstalling the app may be necessary. The current theme has been successfully applied to all Fossify apps. Any future changes to this theme will be synced automatically. - Note that even though you are using the Pro app version, you still need Fossify Thank You for technical reasons. It takes care of the color synchronization. Fossify Thank You to use this feature and support development. Thank you! @@ -431,10 +428,8 @@ Undo Redo Print - Print (Pro) Shortcut Create shortcut - Create shortcut (Pro) Add number to contact View contact details Call from SIM 1 @@ -525,7 +520,6 @@ Password setup successfully. Please reinstall the app in case you forget it. Protection setup successfully. Please reinstall the app in case of problems with resetting it. Lock folder - Lock folder (Pro) Unlock folder This protection works in this app only, it is not supposed to replace a real systemwide folder encryption. Enter password @@ -700,7 +694,6 @@ Look & feel Customize appearance Theme & colors - Locked Customize widget colors Customize notifications Notification sound @@ -894,20 +887,10 @@ Sat Sun - - Your app version will not be updated anymore. Please upgrade to the Pro version to receive new fixes and other improvements. - Your app version will not be updated anymore. Please upgrade to the Pro version to receive new fixes and other improvements by clicking here. It is free till: %s. If you download it till then, you will be able to use it for free forever. More info Upgrade You have to migrate locally stored events manually via exporting in an .ics file, then importing. You can find both export/import buttons at the main screen menu. - Hello,\n\nseems like you just upgraded from the free version. Once you are happy with this one and maybe migrated your settings and favorites over, you can uninstall the old free one to avoid launching it accidentally as you will not need it anymore, it will also prevent this dialog from showing up.\n\nThanks! - Hello,\n\nseems like you already have the Pro app version too. Once you are happy with it and maybe migrated your settings and favorites over, you can uninstall this one to avoid launching it accidentally as you will not need it anymore.\n\nThanks! - Hello,\n\nseems like you just upgraded from the free version. Once you are happy with this one and maybe migrated your data over, you can uninstall the old free one to avoid launching it accidentally as you will not need it anymore, it will also prevent this dialog from showing up.\n\nThanks! - Hello,\n\nseems like you already have the Pro app version too. Once you are happy with it and maybe migrated your data over, you can uninstall this one to avoid launching it accidentally as you will not need it anymore.\n\nThanks! - Hello,\n\nseems like you just upgraded from the free version. If you want to migrate your locally stored events over, you have to do it manually by exporting them into an .ics file in the free app version and importing here through the top menu. \n\nOnce you are satisfied with your setup in the Pro version, you can uninstall the old free one as you won\'t need it anymore, it will also prevent this dialog from showing up.\n\nThanks! - Hello,\n\nseems like you just upgraded from the free version. If you had any contacts stored under \"%s\", you have to migrate them manually by exporting in a .vcf file from the free app version and importing here through the top menu.\n\nOnce you are satisfied with your setup in the Pro version, you can uninstall the old free one as you won\'t need it anymore, it will also prevent this dialog from showing up.\n\nThanks! - Hello,\n\nseems like you just upgraded from the free version. If you want to migrate your notes over, you have to do it manually by exporting them into a file in the free app version and importing here through the top menu. \n\nOnce you are satisfied with your setup in the Pro version, you can uninstall the old free one as you won\'t need it anymore, it will also prevent this dialog from showing up.\n\nThanks! About @@ -915,12 +898,12 @@ For the source codes visit Send your feedback or suggestions to Known issues - Upgrade to Pro More Fossify apps Invite friends Hey, come check out %1$s at %2$s Invite via Rate this app + Enjoying the app? Please rate it on Google Play. Donate Follow us v %1$s\nCopyright © Fossify %2$d @@ -935,25 +918,15 @@ Additional info App version: %s Device OS: %s - -
- hope you are enjoying the app. It contains no ads, please support its development by purchasing the Fossify Thank You app, it will also prevent this dialog from showing up again.

- Thank you! - ]]> -
- Hello,<br><br>hope you are enjoying the app. It contains no ads and we aren\'t collecting your data either, please support its development by purchasing <a href=https://play.google.com/store/apps/details?id=org.fossify.thankyou>Fossify Thank You</a>. You will also have all app features including color customization unlocked.<br><br>Thank you! - Support us by purchasing <a href=https://play.google.com/store/apps/details?id=org.fossify.thankyou>Fossify Thank You</a> please, it will also unlock all app features including color customization. + Support Fossify by purchasing <a href="https://play.google.com/store/apps/details?id=org.fossify.thankyou">Fossify Thank You</a>. It enables custom font files and shared customization across our apps. + If you enjoy using this app, please consider supporting Fossify\'s development. Purchase Please update Fossify Thank You to the latest version Before you ask a question, please check the app settings and read the Frequently Asked Questions first. Maybe the solution is there. Also make sure that you are using the latest app version. - Also note that this app version is no longer being developed, get the Pro one for many improvements. Read it Read FAQ Thank you - The widget is locked.\nPlease upgrade to the Pro version to unlock it. - This feature is locked, please purchase <a href=https://play.google.com/store/apps/details?id=org.fossify.thankyou>Fossify Thank You</a> for unlocking the full app.<br><br>It is a one time payment only and if you won\'t be satisfied, we can refund you. All Fossify apps @@ -1028,10 +1001,6 @@ After launching, restore the default green icon color #106D1F. In extreme cases, reinstalling the app may be necessary.
The money has been deducted from my bank account, but I cannot download the app. What can I do? Payments are fully handled by Google, their system glitches from time to time. Just clear your Google Play app cache and restart your device, then retry downloading it. - Why should I upgrade to the Pro version? - As your app version is no longer updated, the bugs you have maybe spotted will never be fixed. There will also be no new functions added. You can purchase the Pro version on Google Play for a small sum of money. - It is a one time payment, which means that once you purchase it, you will never have to pay again. Not even after getting a new device. If you won\'t like the Pro version, you can just uninstall it within a few hours and you will automatically get your money back. - If you want a refund anytime later, just contact us at hello@fossify.org and you will get it. How can I select multiple items at once? There are multiple ways of doing that. The first one is starting the selection mode by long pressing one item, then short clicking on others to select them. The second way is similar to selecting items on PCs with a mouse, just start the selection mode by long pressing one item, then with your finger still down drag it across other items for selecting. The third way of selecting multiple items is long pressing one item, then long pressing another one and everything in between gets selected. If you @@ -1105,55 +1074,6 @@ Chinese (Simplified) Chinese (Traditional) - - Get the Pro version now! - Basic - Pro - No ads - No internet access - 100% Money Back Guarantee - One time payment - Improved design - Many other improvements - - - Advanced photo editor - Advanced photo & video editor - HEIC/HEIF file support - Advanced batch file renaming - Individual folder locking - Printing support - - - Time zone support - Attendees and email reminders - Easy event importing - New widgets - - - Improved duplicate contact merging - Font size customization - Optional private contact sharing within our apps - Customizable contact ringtones - Contact filtering - Privately stored contacts - - - Checklists - Different note and colors per widget - Note locking - - - Date and time format customization - Home screen shortcuts - File compression support - Tab with recent files - - - Background color customization - File importing support - Zooming - Third-party licences Kotlin (programming language) @@ -1201,9 +1121,6 @@ Your trial expires soon. Unlock the app for one final day Welcome to %s! - Thank you for using our app. You can use this unlocked version for <font color=\'#FFFFFF\'>%d days</font>. Once the trial ends, please consider upgrading to the Pro version. It has a huge amount of new features, modern design, no ads and many other improvements. - \n\nYou just have to pay for it once in a lifetime and if you won\'t be satisfied, you can uninstall it and get a refund.\n\nHope you\'ll like it :) - Please upgrade to the Pro version to enjoy the app to the fullest.\n\nYou just have to pay for it once in a lifetime and if you won\'t be satisfied, you can uninstall it and get a refund.\n\nSee you there :) Your trial expires in %d day. @@ -1211,7 +1128,6 @@ - DEPRECATED: This version of the app is no longer maintained, get the Pro version at https://play.google.com/store/apps/details?id=org.fossify..xxx.pro Don\'t forget that if you uninstall any paid app within 2 hours, you will automatically be refunded. If you want a refund anytime later, just contact us at hello@fossify.org and you will get it. That makes it easy to try it out :) diff --git a/samples/src/foss/res/values/bools.xml b/samples/src/foss/res/values/bools.xml index 2d21c72209..30f2bf4108 100644 --- a/samples/src/foss/res/values/bools.xml +++ b/samples/src/foss/res/values/bools.xml @@ -1,5 +1,4 @@ - true - true + false diff --git a/samples/src/gplay/res/values/bools.xml b/samples/src/gplay/res/values/bools.xml new file mode 100644 index 0000000000..cfcc26e949 --- /dev/null +++ b/samples/src/gplay/res/values/bools.xml @@ -0,0 +1,4 @@ + + + true + diff --git a/samples/src/main/kotlin/org/fossify/commons/samples/activities/MainActivity.kt b/samples/src/main/kotlin/org/fossify/commons/samples/activities/MainActivity.kt index eccf848e71..eed1debcd5 100644 --- a/samples/src/main/kotlin/org/fossify/commons/samples/activities/MainActivity.kt +++ b/samples/src/main/kotlin/org/fossify/commons/samples/activities/MainActivity.kt @@ -3,12 +3,8 @@ package org.fossify.commons.samples.activities import android.content.Intent import android.os.Bundle import androidx.activity.compose.setContent -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import org.fossify.commons.activities.BaseSimpleActivity import org.fossify.commons.activities.ManageBlockedNumbersActivity -import org.fossify.commons.compose.alert_dialog.AlertDialogState -import org.fossify.commons.compose.alert_dialog.rememberAlertDialogState import org.fossify.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL import org.fossify.commons.compose.extensions.FAKE_VERSION_APP_LABEL import org.fossify.commons.compose.extensions.appLaunchedCompose @@ -16,8 +12,6 @@ import org.fossify.commons.compose.extensions.enableEdgeToEdgeSimple import org.fossify.commons.compose.extensions.onEventValue import org.fossify.commons.compose.theme.AppThemeSurface import org.fossify.commons.dialogs.ConfirmationDialog -import org.fossify.commons.dialogs.DonateAlertDialog -import org.fossify.commons.extensions.appLaunched import org.fossify.commons.extensions.launchMoreAppsFromUsIntent import org.fossify.commons.extensions.launchViewIntent import org.fossify.commons.helpers.LICENSE_AUTOFITTEXTVIEW @@ -30,11 +24,13 @@ class MainActivity : BaseSimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - appLaunched(BuildConfig.APPLICATION_ID) + appLaunchedCompose(BuildConfig.APPLICATION_ID) enableEdgeToEdgeSimple() setContent { AppThemeSurface { - val showMoreApps = onEventValue { !resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations) } + val showMoreApps = onEventValue { + resources.getBoolean(org.fossify.commons.R.bool.is_google_play_build) + } MainScreen( openColorCustomization = ::startCustomizationActivity, @@ -58,32 +54,10 @@ class MainActivity : BaseSimpleActivity() { openAbout = ::launchAbout, moreAppsFromUs = ::launchMoreAppsFromUsIntent ) - AppLaunched() } } } - @Composable - private fun AppLaunched( - donateAlertDialogState: AlertDialogState = getDonateAlertDialogState(), - ) { - LaunchedEffect(Unit) { - appLaunchedCompose( - appId = BuildConfig.APPLICATION_ID, - showDonateDialog = donateAlertDialogState::show, - showUpgradeDialog = {} - ) - } - } - - @Composable - private fun getDonateAlertDialogState() = - rememberAlertDialogState().apply { - DialogMember { - DonateAlertDialog(alertDialogState = this) - } - } - private fun launchAbout() { val licenses = LICENSE_AUTOFITTEXTVIEW @@ -93,7 +67,7 @@ class MainActivity : BaseSimpleActivity() { FAQItem(org.fossify.commons.R.string.faq_4_title_commons, org.fossify.commons.R.string.faq_4_text_commons) ) - if (!resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations)) { + if (resources.getBoolean(org.fossify.commons.R.bool.is_google_play_build)) { faqItems.add(FAQItem(org.fossify.commons.R.string.faq_2_title_commons, org.fossify.commons.R.string.faq_2_text_commons)) faqItems.add(FAQItem(org.fossify.commons.R.string.faq_6_title_commons, org.fossify.commons.R.string.faq_6_text_commons)) } diff --git a/samples/src/main/kotlin/org/fossify/commons/samples/activities/TestDialogActivity.kt b/samples/src/main/kotlin/org/fossify/commons/samples/activities/TestDialogActivity.kt index 9cf7422979..088bf6d559 100644 --- a/samples/src/main/kotlin/org/fossify/commons/samples/activities/TestDialogActivity.kt +++ b/samples/src/main/kotlin/org/fossify/commons/samples/activities/TestDialogActivity.kt @@ -41,7 +41,6 @@ import org.fossify.commons.dialogs.CreateNewFolderAlertDialog import org.fossify.commons.dialogs.CustomIntervalPickerAlertDialog import org.fossify.commons.dialogs.DonateAlertDialog import org.fossify.commons.dialogs.EnterPasswordAlertDialog -import org.fossify.commons.dialogs.FeatureLockedAlertDialog import org.fossify.commons.dialogs.FileConflictAlertDialog import org.fossify.commons.dialogs.FolderLockingNoticeAlertDialog import org.fossify.commons.dialogs.LineColorPickerAlertDialog @@ -49,13 +48,10 @@ import org.fossify.commons.dialogs.OpenDeviceSettingsAlertDialog import org.fossify.commons.dialogs.PermissionRequiredAlertDialog import org.fossify.commons.dialogs.PurchaseThankYouAlertDialog import org.fossify.commons.dialogs.RadioGroupAlertDialog -import org.fossify.commons.dialogs.UpgradeToProAlertDialog import org.fossify.commons.dialogs.WhatsNewAlertDialog import org.fossify.commons.dialogs.WritePermissionAlertDialog import org.fossify.commons.dialogs.WritePermissionDialog import org.fossify.commons.extensions.baseConfig -import org.fossify.commons.extensions.launchUpgradeToProIntent -import org.fossify.commons.extensions.launchViewIntent import org.fossify.commons.extensions.toHex import org.fossify.commons.extensions.toast import org.fossify.commons.models.FileDirItem @@ -84,7 +80,6 @@ class TestDialogActivity : ComponentActivity() { ShowButton(getConfirmationAdvancedAlertDialogState(), text = "Confirmation advanced") ShowButton(getPermissionRequiredAlertDialogState(), text = "Permission required") ShowButton(getDonateAlertDialogState(), text = "Donate") - ShowButton(getFeatureLockedAlertDialogState(), text = "Feature Locked") ShowButton(getPurchaseThankYouAlertDialogState(), text = "Purchase thank you") ShowButton(getLineColorPickerAlertDialogState(), text = "Line color picker") ShowButton(getOpenDeviceSettingsAlertDialogState(), text = "Open device settings") @@ -92,7 +87,6 @@ class TestDialogActivity : ComponentActivity() { ShowButton(getCallConfirmationAlertDialogState(), text = "Call confirmation") ShowButton(getChangeDateTimeFormatAlertDialogState(), text = "Change date time") ShowButton(getRadioGroupDialogAlertDialogState(), text = "Radio group") - ShowButton(getUpgradeToProAlertDialogState(), text = "Upgrade to pro") ShowButton(getWhatsNewAlertDialogState(), text = "What's new") ShowButton(getChangeViewTypeAlertDialogState(), text = "Change view type") ShowButton(getWritePermissionAlertDialogState(), text = "Write permission") @@ -215,15 +209,6 @@ class TestDialogActivity : ComponentActivity() { } } - @Composable - private fun getUpgradeToProAlertDialogState() = rememberAlertDialogState().apply { - DialogMember { - UpgradeToProAlertDialog(alertDialogState = this, onMoreInfoClick = { - launchViewIntent("https://fossify.org/upgrade_to_pro") - }, onUpgradeClick = ::launchUpgradeToProIntent) - } - } - @Composable private fun getRadioGroupDialogAlertDialogState() = rememberAlertDialogState().apply { DialogMember { @@ -314,13 +299,6 @@ class TestDialogActivity : ComponentActivity() { } } - @Composable - private fun getFeatureLockedAlertDialogState() = rememberAlertDialogState().apply { - DialogMember { - FeatureLockedAlertDialog(alertDialogState = this, cancelCallback = {}) - } - } - @Composable private fun getDonateAlertDialogState() = rememberAlertDialogState().apply { diff --git a/samples/src/prepaid/res/values/bools.xml b/samples/src/prepaid/res/values/bools.xml deleted file mode 100644 index e76df3bc36..0000000000 --- a/samples/src/prepaid/res/values/bools.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - false - true - From 1b3a86157226c28babd63e034f0c81a1f675e6db Mon Sep 17 00:00:00 2001 From: Naveen Singh <36371707+naveensingh@users.noreply.github.com> Date: Thu, 1 Oct 2026 16:20:38 +0530 Subject: [PATCH 2/2] fix: tweak donation prompt slightly --- commons/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/src/main/res/values/strings.xml b/commons/src/main/res/values/strings.xml index 0ba124e27e..d93e4282af 100644 --- a/commons/src/main/res/values/strings.xml +++ b/commons/src/main/res/values/strings.xml @@ -918,7 +918,7 @@ Additional info App version: %s Device OS: %s - Support Fossify by purchasing <a href="https://play.google.com/store/apps/details?id=org.fossify.thankyou">Fossify Thank You</a>. It enables custom font files and shared customization across our apps. + Enjoying Fossify? Support the development of our ad-free apps by purchasing <a href="https://play.google.com/store/apps/details?id=org.Fossify.thankyou">Fossify Thank You</a>. It\'ll also enable custom fonts and shared customization across Fossify apps. Thank you for your support! If you enjoy using this app, please consider supporting Fossify\'s development. Purchase Please update Fossify Thank You to the latest version