feat: write permission dialog

and few other fixes along the way
This commit is contained in:
FunkyMuse 2023-10-09 19:10:06 +02:00
parent 869eb0f163
commit a0ff2b2eeb
34 changed files with 416 additions and 173 deletions

View file

@ -51,6 +51,7 @@ android {
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api", "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi", "-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi",
"-Xcontext-receivers" "-Xcontext-receivers"
) )
} }
@ -98,6 +99,7 @@ dependencies {
api(libs.material) api(libs.material)
api(libs.gson) api(libs.gson)
implementation(libs.glide.compose)
api(libs.glide) api(libs.glide)
ksp(libs.glide.compiler) ksp(libs.glide.compiler)

View file

@ -43,7 +43,7 @@ import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.asynctasks.CopyMoveTask import com.simplemobiletools.commons.asynctasks.CopyMoveTask
import com.simplemobiletools.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL import com.simplemobiletools.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL
import com.simplemobiletools.commons.dialogs.* import com.simplemobiletools.commons.dialogs.*
import com.simplemobiletools.commons.dialogs.WritePermissionDialog.Mode import com.simplemobiletools.commons.dialogs.WritePermissionDialog.WritePermissionDialogMode
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.interfaces.CopyMoveListener import com.simplemobiletools.commons.interfaces.CopyMoveListener
@ -760,7 +760,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} }
funAfterSAFPermission = callback funAfterSAFPermission = callback
WritePermissionDialog(this, Mode.Otg) { WritePermissionDialog(this, WritePermissionDialogMode.Otg) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
try { try {
startActivityForResult(this, OPEN_DOCUMENT_TREE_OTG) startActivityForResult(this, OPEN_DOCUMENT_TREE_OTG)

View file

@ -0,0 +1,56 @@
package com.simplemobiletools.commons.compose.components
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.widget.TextView
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.extensions.removeUnderlines
@Composable
fun LinkifyTextComponent(
modifier: Modifier = Modifier,
fontSize: TextUnit = 14.sp,
removeUnderlines: Boolean = true,
textAlignment: Int = TextView.TEXT_ALIGNMENT_TEXT_START,
text: () -> Spanned
) {
val context = LocalContext.current
val customLinkifyTextView = remember {
TextView(context)
}
val textColor = SimpleTheme.colorScheme.onSurface
val linkTextColor = SimpleTheme.colorScheme.primary
AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView ->
textView.setTextColor(textColor.toArgb())
textView.setLinkTextColor(linkTextColor.toArgb())
textView.text = text()
textView.textAlignment = textAlignment
textView.textSize = fontSize.value
textView.movementMethod = LinkMovementMethod.getInstance()
if (removeUnderlines) {
customLinkifyTextView.removeUnderlines()
}
}
}
@Composable
@MyDevices
private fun LinkifyTextComponentPreview() = AppThemeSurface {
val source = stringResource(id = R.string.contributors_label)
LinkifyTextComponent {
source.fromHtml()
}
}

View file

@ -46,7 +46,7 @@ fun RadioButtonDialogComponent(
) )
Text( Text(
text = item, text = item,
modifier = Modifier.padding(start = SimpleTheme.dimens.margin.medium), modifier = Modifier.padding(start = SimpleTheme.dimens.padding.medium),
color = dialogTextColor color = dialogTextColor
) )
} }

View file

@ -10,7 +10,7 @@ import com.simplemobiletools.commons.extensions.launchViewIntent
@Composable @Composable
fun FakeVersionCheck() { fun FakeVersionCheck() {
val context = LocalContext.current.getActivity() val context = LocalContext.current
val confirmationDialogAlertDialogState = rememberAlertDialogState().apply { val confirmationDialogAlertDialogState = rememberAlertDialogState().apply {
DialogMember { DialogMember {
ConfirmationAlertDialog( ConfirmationAlertDialog(

View file

@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -22,10 +24,12 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.LifecycleResumeEffect
import androidx.lifecycle.compose.LifecycleStartEffect import androidx.lifecycle.compose.LifecycleStartEffect
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.system_ui_controller.rememberSystemUiController import com.simplemobiletools.commons.compose.system_ui_controller.rememberSystemUiController
import com.simplemobiletools.commons.compose.theme.SimpleTheme import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.compose.theme.isLitWell import com.simplemobiletools.commons.compose.theme.isLitWell
import com.simplemobiletools.commons.extensions.darkenColor import com.simplemobiletools.commons.extensions.darkenColor
import com.simplemobiletools.commons.extensions.launchViewIntent
fun Context.getActivity(): Activity { fun Context.getActivity(): Activity {
return when (this) { return when (this) {
@ -158,3 +162,12 @@ internal fun TransparentSystemBars(darkIcons: Boolean = !isSystemInDarkTheme())
onDispose { } onDispose { }
} }
} }
@Composable
fun composeDonateIntent(): () -> Unit {
val localContext = LocalContext.current
val localView = LocalView.current
return {
if (localView.isInEditMode) Unit else localContext.getActivity().launchViewIntent(R.string.thank_you_url)
}
}

View file

@ -39,7 +39,7 @@ fun SimpleScaffoldTopBar(
Text( Text(
text = title, text = title,
modifier = Modifier modifier = Modifier
.padding(start = SimpleTheme.dimens.margin.medium) .padding(start = SimpleTheme.dimens.padding.medium)
.fillMaxWidth(), .fillMaxWidth(),
color = scrolledColor, color = scrolledColor,
maxLines = 1, maxLines = 1,
@ -157,7 +157,7 @@ fun SimpleNavigationIcon(
) { ) {
Box( Box(
modifier modifier
.padding(start = SimpleTheme.dimens.margin.medium) .padding(start = SimpleTheme.dimens.padding.medium)
.clip(RoundedCornerShape(50)) .clip(RoundedCornerShape(50))
.clickable( .clickable(
navigationIconInteractionSource, rememberRipple( navigationIconInteractionSource, rememberRipple(
@ -175,13 +175,13 @@ fun SimpleBackIcon(iconColor: Color?) {
if (iconColor == null) { if (iconColor == null) {
Icon( Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back), imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back),
modifier = Modifier.padding(SimpleTheme.dimens.margin.small) modifier = Modifier.padding(SimpleTheme.dimens.padding.small)
) )
} else { } else {
Icon( Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back), imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back),
tint = iconColor, tint = iconColor,
modifier = Modifier.padding(SimpleTheme.dimens.margin.small) modifier = Modifier.padding(SimpleTheme.dimens.padding.small)
) )
} }
} }

View file

@ -96,7 +96,7 @@ fun ActionMenu(
Text( Text(
text = name, text = name,
fontSize = 14.sp, fontSize = 14.sp,
modifier = Modifier.padding(SimpleTheme.dimens.margin.medium), modifier = Modifier.padding(SimpleTheme.dimens.padding.medium),
) )
} }
}, },
@ -125,7 +125,7 @@ fun ActionMenu(
Text( Text(
text = stringResource(id = R.string.more_options), text = stringResource(id = R.string.more_options),
fontSize = 14.sp, fontSize = 14.sp,
modifier = Modifier.padding(SimpleTheme.dimens.margin.medium), modifier = Modifier.padding(SimpleTheme.dimens.padding.medium),
) )
} }
}, },

View file

@ -16,6 +16,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold
import com.simplemobiletools.commons.compose.settings.SettingsGroupTitle import com.simplemobiletools.commons.compose.settings.SettingsGroupTitle
@ -24,6 +25,7 @@ import com.simplemobiletools.commons.compose.settings.SettingsListItem
import com.simplemobiletools.commons.compose.settings.SettingsTitleTextComponent import com.simplemobiletools.commons.compose.settings.SettingsTitleTextComponent
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.models.LanguageContributor import com.simplemobiletools.commons.models.LanguageContributor
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@ -64,7 +66,7 @@ internal fun ContributorsScreen(
) )
} }
item { item {
Spacer(modifier = Modifier.padding(vertical = SimpleTheme.dimens.margin.medium)) Spacer(modifier = Modifier.padding(vertical = SimpleTheme.dimens.padding.medium))
} }
item { item {
SettingsHorizontalDivider() SettingsHorizontalDivider()
@ -85,15 +87,15 @@ internal fun ContributorsScreen(
icon = R.drawable.ic_heart_vector, icon = R.drawable.ic_heart_vector,
text = { text = {
val source = stringResource(id = R.string.contributors_label) val source = stringResource(id = R.string.contributors_label)
LinkifyText { LinkifyTextComponent {
stringFromHTML(source) source.fromHtml()
} }
}, },
tint = SimpleTheme.colorScheme.onSurface tint = SimpleTheme.colorScheme.onSurface
) )
} }
item { item {
Spacer(modifier = Modifier.padding(bottom = SimpleTheme.dimens.margin.medium)) Spacer(modifier = Modifier.padding(bottom = SimpleTheme.dimens.padding.medium))
} }
} }
@ -117,7 +119,7 @@ private fun ContributorItem(
leadingContent = { leadingContent = {
val imageSize = Modifier val imageSize = Modifier
.size(SimpleTheme.dimens.icon.medium) .size(SimpleTheme.dimens.icon.medium)
.padding(SimpleTheme.dimens.margin.medium) .padding(SimpleTheme.dimens.padding.medium)
Image( Image(
modifier = imageSize, modifier = imageSize,
painter = painterResource(id = languageContributor.iconId), painter = painterResource(id = languageContributor.iconId),

View file

@ -1,31 +1,22 @@
package com.simplemobiletools.commons.compose.screens package com.simplemobiletools.commons.compose.screens
import android.os.Build
import android.text.Html
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.widget.TextView
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold
import com.simplemobiletools.commons.compose.settings.SettingsHorizontalDivider import com.simplemobiletools.commons.compose.settings.SettingsHorizontalDivider
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.extensions.removeUnderlines import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.FAQItem
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@ -38,7 +29,7 @@ internal fun FAQScreen(
SimpleLazyListScaffold( SimpleLazyListScaffold(
title = stringResource(id = R.string.frequently_asked_questions), title = stringResource(id = R.string.frequently_asked_questions),
goBack = goBack, goBack = goBack,
contentPadding = PaddingValues(bottom = SimpleTheme.dimens.margin.medium) contentPadding = PaddingValues(bottom = SimpleTheme.dimens.padding.medium)
) { ) {
itemsIndexed(faqItems) { index, faqItem -> itemsIndexed(faqItems) { index, faqItem ->
Column(modifier = Modifier.fillMaxWidth()) { Column(modifier = Modifier.fillMaxWidth()) {
@ -56,8 +47,8 @@ internal fun FAQScreen(
}, },
supportingContent = { supportingContent = {
if (faqItem.text is Int) { if (faqItem.text is Int) {
val text = stringFromHTML(stringResource(id = faqItem.text)) val text = stringResource(id = faqItem.text).fromHtml()
LinkifyText( LinkifyTextComponent(
text = { text }, text = { text },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
fontSize = 14.sp fontSize = 14.sp
@ -71,12 +62,12 @@ internal fun FAQScreen(
} }
}, },
) )
Spacer(modifier = Modifier.padding(bottom = SimpleTheme.dimens.margin.medium)) Spacer(modifier = Modifier.padding(bottom = SimpleTheme.dimens.padding.medium))
if (index != faqItems.lastIndex) { if (index != faqItems.lastIndex) {
SettingsHorizontalDivider( SettingsHorizontalDivider(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(bottom = SimpleTheme.dimens.margin.small) .padding(bottom = SimpleTheme.dimens.padding.small)
) )
} }
} }
@ -84,42 +75,6 @@ internal fun FAQScreen(
} }
} }
@Suppress("deprecation")
fun stringFromHTML(source: String): Spanned {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY)
} else {
Html.fromHtml(source)
}
}
@Composable
fun LinkifyText(
modifier: Modifier = Modifier,
fontSize: TextUnit = 14.sp,
removeUnderlines: Boolean = true,
textAlignment: Int = TextView.TEXT_ALIGNMENT_TEXT_START,
text: () -> Spanned
) {
val context = LocalContext.current
val customLinkifyTextView = remember {
TextView(context)
}
val textColor = SimpleTheme.colorScheme.onSurface
val linkTextColor = SimpleTheme.colorScheme.primary
AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView ->
textView.setTextColor(textColor.toArgb())
textView.setLinkTextColor(linkTextColor.toArgb())
textView.text = text()
textView.textAlignment = textAlignment
textView.textSize = fontSize.value
textView.movementMethod = LinkMovementMethod.getInstance()
if (removeUnderlines) {
customLinkifyTextView.removeUnderlines()
}
}
}
@MyDevices @MyDevices
@Composable @Composable
private fun FAQScreenPreview() { private fun FAQScreenPreview() {

View file

@ -35,7 +35,7 @@ internal fun LicenseScreen(
Column { Column {
LicenseItem(license, onLicenseClick) LicenseItem(license, onLicenseClick)
if (index != thirdPartyLicenses.lastIndex) { if (index != thirdPartyLicenses.lastIndex) {
SettingsHorizontalDivider(modifier = Modifier.padding(bottom = SimpleTheme.dimens.margin.small)) SettingsHorizontalDivider(modifier = Modifier.padding(bottom = SimpleTheme.dimens.padding.small))
} }
} }
} }
@ -58,7 +58,7 @@ private fun LicenseItem(
}, supportingContent = { }, supportingContent = {
Text( Text(
text = stringResource(id = license.textId), text = stringResource(id = license.textId),
modifier = Modifier.padding(top = SimpleTheme.dimens.margin.extraSmall), modifier = Modifier.padding(top = SimpleTheme.dimens.padding.extraSmall),
) )
}, colors = ListItemDefaults.colors(headlineColor = SimpleTheme.colorScheme.primary, supportingColor = SimpleTheme.colorScheme.onSurface)) }, colors = ListItemDefaults.colors(headlineColor = SimpleTheme.colorScheme.primary, supportingColor = SimpleTheme.colorScheme.onSurface))
} }

View file

@ -86,7 +86,7 @@ internal fun ManageBlockedNumbersScreen(
onCopy: (BlockedNumber) -> Unit, onCopy: (BlockedNumber) -> Unit,
) { ) {
val dimens = SimpleTheme.dimens val dimens = SimpleTheme.dimens
val startingPadding = remember { Modifier.padding(horizontal = dimens.margin.small) } val startingPadding = remember { Modifier.padding(horizontal = dimens.padding.small) }
val selectedIds: MutableState<Set<Long>> = rememberSaveable { mutableStateOf(emptySet()) } val selectedIds: MutableState<Set<Long>> = rememberSaveable { mutableStateOf(emptySet()) }
val hapticFeedback = LocalHapticFeedback.current val hapticFeedback = LocalHapticFeedback.current
val isInActionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } } val isInActionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } }
@ -194,7 +194,7 @@ internal fun ManageBlockedNumbersScreen(
ids = blockedNumbers?.map { blockedNumber -> blockedNumber.id }.orEmpty() ids = blockedNumbers?.map { blockedNumber -> blockedNumber.id }.orEmpty()
) )
}, },
verticalArrangement = Arrangement.spacedBy(SimpleTheme.dimens.margin.extraSmall), verticalArrangement = Arrangement.spacedBy(SimpleTheme.dimens.padding.extraSmall),
contentPadding = PaddingValues(bottom = paddingValues.calculateBottomPadding()) contentPadding = PaddingValues(bottom = paddingValues.calculateBottomPadding())
) { ) {
when { when {
@ -324,7 +324,7 @@ private fun BlockedNumber(
movableContentOf { movableContentOf {
Text( Text(
text = blockedNumber.contactName.toString(), text = blockedNumber.contactName.toString(),
modifier = modifier.padding(horizontal = SimpleTheme.dimens.margin.medium, vertical = SimpleTheme.dimens.margin.extraSmall) modifier = modifier.padding(horizontal = SimpleTheme.dimens.padding.medium, vertical = SimpleTheme.dimens.padding.extraSmall)
) )
} }
} }
@ -381,7 +381,7 @@ private fun blockedNumberListItemColors(
private fun BlockedNumberHeadlineContent(modifier: Modifier = Modifier, blockedNumber: BlockedNumber, hasContactName: Boolean) { private fun BlockedNumberHeadlineContent(modifier: Modifier = Modifier, blockedNumber: BlockedNumber, hasContactName: Boolean) {
Text( Text(
text = blockedNumber.number, text = blockedNumber.number,
modifier = modifier.padding(horizontal = SimpleTheme.dimens.margin.medium), modifier = modifier.padding(horizontal = SimpleTheme.dimens.padding.medium),
color = if (hasContactName) LocalContentColor.current.copy(alpha = 0.7f) else LocalContentColor.current color = if (hasContactName) LocalContentColor.current.copy(alpha = 0.7f) else LocalContentColor.current
) )
} }
@ -548,7 +548,7 @@ private fun NonActionModeToolbar(
title = { scrolledTextColor -> title = { scrolledTextColor ->
Text( Text(
text = stringResource(id = R.string.manage_blocked_numbers), text = stringResource(id = R.string.manage_blocked_numbers),
modifier = Modifier.padding(start = SimpleTheme.dimens.margin.extraLarge), modifier = Modifier.padding(start = SimpleTheme.dimens.padding.extraLarge),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
color = scrolledTextColor color = scrolledTextColor
@ -584,8 +584,8 @@ private fun LazyListScope.emptyBlockedNumbers(
style = TextStyle(fontStyle = FontStyle.Italic, textAlign = TextAlign.Center, color = SimpleTheme.colorScheme.onSurface), style = TextStyle(fontStyle = FontStyle.Italic, textAlign = TextAlign.Center, color = SimpleTheme.colorScheme.onSurface),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.small) .padding(top = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.small)
.padding(horizontal = SimpleTheme.dimens.margin.extraLarge) .padding(horizontal = SimpleTheme.dimens.padding.extraLarge)
) )
} }
item { item {
@ -606,7 +606,7 @@ private fun LazyListScope.emptyBlockedNumbers(
color = SimpleTheme.colorScheme.primary, color = SimpleTheme.colorScheme.primary,
fontSize = 18.sp fontSize = 18.sp
), ),
modifier = Modifier.padding(SimpleTheme.dimens.margin.medium) modifier = Modifier.padding(SimpleTheme.dimens.padding.medium)
) )
} }
} }
@ -622,8 +622,8 @@ private fun LazyListScope.noPermissionToBlock(
style = TextStyle(fontStyle = FontStyle.Italic, textAlign = TextAlign.Center), style = TextStyle(fontStyle = FontStyle.Italic, textAlign = TextAlign.Center),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge) .padding(top = SimpleTheme.dimens.padding.extraLarge)
.padding(horizontal = SimpleTheme.dimens.margin.extraLarge) .padding(horizontal = SimpleTheme.dimens.padding.extraLarge)
) )
} }
item { item {
@ -644,7 +644,7 @@ private fun LazyListScope.noPermissionToBlock(
color = SimpleTheme.colorScheme.primary, color = SimpleTheme.colorScheme.primary,
fontSize = 18.sp fontSize = 18.sp
), ),
modifier = Modifier.padding(SimpleTheme.dimens.margin.extraLarge) modifier = Modifier.padding(SimpleTheme.dimens.padding.extraLarge)
) )
} }
} }

View file

@ -57,7 +57,7 @@ fun SettingsCheckBoxComponent(
Text( Text(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(end = SimpleTheme.dimens.margin.extraLarge), .padding(end = SimpleTheme.dimens.padding.extraLarge),
text = label, text = label,
color = preferenceLabelColor(isEnabled = isPreferenceEnabled), color = preferenceLabelColor(isEnabled = isPreferenceEnabled),
fontSize = 14.sp fontSize = 14.sp
@ -67,7 +67,7 @@ fun SettingsCheckBoxComponent(
text = value.toString(), text = value.toString(),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(end = SimpleTheme.dimens.margin.extraLarge), .padding(end = SimpleTheme.dimens.padding.extraLarge),
color = preferenceValueColor(isEnabled = isPreferenceEnabled), color = preferenceValueColor(isEnabled = isPreferenceEnabled),
) )
} }

View file

@ -35,7 +35,7 @@ fun SettingsGroupTitle(
Box( Box(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = SimpleTheme.dimens.margin.extraLarge), .padding(horizontal = SimpleTheme.dimens.padding.extraLarge),
contentAlignment = Alignment.CenterStart contentAlignment = Alignment.CenterStart
) { ) {
val primary = SimpleTheme.colorScheme.primary val primary = SimpleTheme.colorScheme.primary

View file

@ -51,7 +51,7 @@ fun SettingsListItem(
leadingContent = { leadingContent = {
val imageSize = Modifier val imageSize = Modifier
.size(SimpleTheme.dimens.icon.medium) .size(SimpleTheme.dimens.icon.medium)
.padding(SimpleTheme.dimens.margin.medium) .padding(SimpleTheme.dimens.padding.medium)
when { when {
icon != null && isImage && tint != null -> Image( icon != null && isImage && tint != null -> Image(
modifier = imageSize, modifier = imageSize,
@ -107,7 +107,7 @@ fun SettingsListItem(
leadingContent = { leadingContent = {
val imageSize = Modifier val imageSize = Modifier
.size(SimpleTheme.dimens.icon.medium) .size(SimpleTheme.dimens.icon.medium)
.padding(SimpleTheme.dimens.margin.medium) .padding(SimpleTheme.dimens.padding.medium)
when { when {
icon != null && isImage && tint != null -> Image( icon != null && isImage && tint != null -> Image(
modifier = imageSize, modifier = imageSize,

View file

@ -20,11 +20,11 @@ fun SettingsTitleTextComponent(
maxLines: Int = 1, maxLines: Int = 1,
overflow: TextOverflow = TextOverflow.Ellipsis overflow: TextOverflow = TextOverflow.Ellipsis
) { ) {
Box(modifier = Modifier.padding(top = SimpleTheme.dimens.margin.extraLarge)) { Box(modifier = Modifier.padding(top = SimpleTheme.dimens.padding.extraLarge)) {
Text( Text(
text = text.uppercase(), text = text.uppercase(),
modifier = modifier modifier = modifier
.padding(horizontal = SimpleTheme.dimens.margin.small), .padding(horizontal = SimpleTheme.dimens.padding.small),
color = color, color = color,
fontSize = 14.sp, fontSize = 14.sp,
maxLines = maxLines, maxLines = maxLines,

View file

@ -6,7 +6,7 @@ import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.theme.model.Dimensions import com.simplemobiletools.commons.compose.theme.model.Dimensions
internal val CommonDimensions = Dimensions( internal val CommonDimensions = Dimensions(
margin = Dimensions.Margins( padding = Dimensions.Paddings(
extraSmall = 2.dp, extraSmall = 2.dp,
small = 4.dp, small = 4.dp,
medium = 8.dp, medium = 8.dp,

View file

@ -5,11 +5,11 @@ import androidx.compose.ui.unit.Dp
@Immutable @Immutable
data class Dimensions( data class Dimensions(
val margin: Margins, val padding: Paddings,
val icon: IconSizes val icon: IconSizes
) { ) {
@Immutable @Immutable
data class Margins( data class Paddings(
val extraSmall: Dp, val extraSmall: Dp,
val small: Dp, val small: Dp,
val medium: Dp, val medium: Dp,

View file

@ -18,15 +18,11 @@ import androidx.compose.ui.unit.sp
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.screens.LinkifyText
import com.simplemobiletools.commons.compose.screens.stringFromHTML
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogTextviewBinding import com.simplemobiletools.commons.databinding.DialogTextviewBinding
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.extensions.getStringsPackageName
import com.simplemobiletools.commons.extensions.launchViewIntent
import com.simplemobiletools.commons.extensions.setupDialogStuff
class AppSideloadedDialog(val activity: Activity, val callback: () -> Unit) { class AppSideloadedDialog(val activity: Activity, val callback: () -> Unit) {
private var dialog: AlertDialog? = null private var dialog: AlertDialog? = null
@ -96,8 +92,8 @@ fun AppSideLoadedAlertDialog(
shape = dialogShape, shape = dialogShape,
text = { text = {
val source = stringResource(id = R.string.sideloaded_app, url) val source = stringResource(id = R.string.sideloaded_app, url)
LinkifyText(fontSize = 16.sp, removeUnderlines = false) { LinkifyTextComponent(fontSize = 16.sp, removeUnderlines = false) {
stringFromHTML(source) source.fromHtml()
} }
}, },
title = { title = {

View file

@ -147,7 +147,7 @@ fun ChangeDateTimeFormatAlertDialog(
items = kinds, selected = selected, items = kinds, selected = selected,
setSelected = setSelected, setSelected = setSelected,
modifier = Modifier.padding( modifier = Modifier.padding(
vertical = SimpleTheme.dimens.margin.extraLarge, vertical = SimpleTheme.dimens.padding.extraLarge,
) )
) )
SettingsHorizontalDivider() SettingsHorizontalDivider()
@ -157,7 +157,7 @@ fun ChangeDateTimeFormatAlertDialog(
label = stringResource(id = R.string.use_24_hour_time_format), label = stringResource(id = R.string.use_24_hour_time_format),
initialValue = is24HoursSelected, initialValue = is24HoursSelected,
onChange = { is24HoursSelected = it }, onChange = { is24HoursSelected = it },
modifier = Modifier.padding(horizontal = SimpleTheme.dimens.margin.medium) modifier = Modifier.padding(horizontal = SimpleTheme.dimens.padding.medium)
) )
} }
} }
@ -167,7 +167,7 @@ fun ChangeDateTimeFormatAlertDialog(
horizontalArrangement = Arrangement.End, horizontalArrangement = Arrangement.End,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.extraLarge, end = SimpleTheme.dimens.margin.extraLarge) .padding(top = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.extraLarge, end = SimpleTheme.dimens.padding.extraLarge)
.align(Alignment.BottomStart) .align(Alignment.BottomStart)
) { ) {
TextButton(onClick = { TextButton(onClick = {

View file

@ -98,16 +98,16 @@ fun ChangeViewTypeAlertDialog(
setSelected(selectedTitle) setSelected(selectedTitle)
}, },
modifier = Modifier.padding( modifier = Modifier.padding(
vertical = SimpleTheme.dimens.margin.extraLarge, vertical = SimpleTheme.dimens.padding.extraLarge,
), ),
verticalPadding = SimpleTheme.dimens.margin.extraLarge, verticalPadding = SimpleTheme.dimens.padding.extraLarge,
) )
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End, horizontalArrangement = Arrangement.End,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(end = SimpleTheme.dimens.margin.extraLarge) .padding(end = SimpleTheme.dimens.padding.extraLarge)
) { ) {
TextButton(onClick = { TextButton(onClick = {
alertDialogState.hide() alertDialogState.hide()

View file

@ -165,7 +165,7 @@ fun ColorPickerAlertDialog(
Column( Column(
Modifier Modifier
.fillMaxWidth(0.95f) .fillMaxWidth(0.95f)
.padding(SimpleTheme.dimens.margin.extraLarge) .padding(SimpleTheme.dimens.padding.extraLarge)
) { ) {
var dialogColorPickerBinding by remember { mutableStateOf<DialogColorPickerBinding?>(null) } var dialogColorPickerBinding by remember { mutableStateOf<DialogColorPickerBinding?>(null) }
val currentColorHsv by remember { derivedStateOf { Hsv(FloatArray(3)).apply { Color.colorToHSV(color, this.value) } } } val currentColorHsv by remember { derivedStateOf { Hsv(FloatArray(3)).apply { Color.colorToHSV(color, this.value) } } }

View file

@ -24,11 +24,10 @@ import androidx.compose.ui.window.DialogProperties
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.getActivity import com.simplemobiletools.commons.compose.extensions.getActivity
import com.simplemobiletools.commons.compose.extensions.rememberMutableInteractionSource import com.simplemobiletools.commons.compose.extensions.rememberMutableInteractionSource
import com.simplemobiletools.commons.compose.screens.LinkifyText
import com.simplemobiletools.commons.compose.screens.stringFromHTML
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.databinding.DialogDonateBinding import com.simplemobiletools.commons.databinding.DialogDonateBinding
@ -110,13 +109,13 @@ fun DonateAlertDialog(
}, },
text = { text = {
val source = stringResource(id = R.string.donate_short) val source = stringResource(id = R.string.donate_short)
LinkifyText( LinkifyTextComponent(
fontSize = 16.sp, fontSize = 16.sp,
removeUnderlines = false, removeUnderlines = false,
textAlignment = TextView.TEXT_ALIGNMENT_CENTER, textAlignment = TextView.TEXT_ALIGNMENT_CENTER,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
stringFromHTML(source) source.fromHtml()
} }
} }
) )

View file

@ -18,18 +18,16 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.getActivity import com.simplemobiletools.commons.compose.extensions.composeDonateIntent
import com.simplemobiletools.commons.compose.extensions.rememberMutableInteractionSource import com.simplemobiletools.commons.compose.extensions.rememberMutableInteractionSource
import com.simplemobiletools.commons.compose.screens.LinkifyText
import com.simplemobiletools.commons.compose.screens.stringFromHTML
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.databinding.DialogFeatureLockedBinding import com.simplemobiletools.commons.databinding.DialogFeatureLockedBinding
@ -71,10 +69,7 @@ fun FeatureLockedAlertDialog(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
cancelCallback: () -> Unit cancelCallback: () -> Unit
) { ) {
val localContext = LocalContext.current.getActivity() val donateIntent = composeDonateIntent()
val donateIntent = {
localContext.launchViewIntent(R.string.thank_you_url)
}
androidx.compose.material3.AlertDialog( androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor, containerColor = dialogContainerColor,
modifier = modifier modifier = modifier
@ -121,13 +116,13 @@ fun FeatureLockedAlertDialog(
}, },
text = { text = {
val source = stringResource(id = R.string.features_locked) val source = stringResource(id = R.string.features_locked)
LinkifyText( LinkifyTextComponent(
fontSize = 16.sp, fontSize = 16.sp,
removeUnderlines = false, removeUnderlines = false,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
textAlignment = TextView.TEXT_ALIGNMENT_CENTER textAlignment = TextView.TEXT_ALIGNMENT_CENTER
) { ) {
stringFromHTML(source) source.fromHtml()
} }
} }
) )

View file

@ -19,6 +19,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.viewinterop.AndroidViewBinding import androidx.compose.ui.viewinterop.AndroidViewBinding
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider import androidx.compose.ui.window.DialogWindowProvider
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.appbar.MaterialToolbar
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
@ -166,8 +167,7 @@ class LineColorPickerDialog(
fun LineColorPickerAlertDialog( fun LineColorPickerAlertDialog(
alertDialogState: AlertDialogState, alertDialogState: AlertDialogState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ColorInt @ColorInt color: Int,
color: Int,
isPrimaryColorPicker: Boolean, isPrimaryColorPicker: Boolean,
primaryColors: Int = R.array.md_primary_colors, primaryColors: Int = R.array.md_primary_colors,
appIconIDs: ArrayList<Int>? = null, appIconIDs: ArrayList<Int>? = null,
@ -179,11 +179,10 @@ fun LineColorPickerAlertDialog(
var wasDimmedBackgroundRemoved by remember { mutableStateOf(false) } var wasDimmedBackgroundRemoved by remember { mutableStateOf(false) }
val defaultColor = remember { val defaultColor = remember {
context.resources.getColor(R.color.color_primary) ContextCompat.getColor(context, R.color.color_primary)
} }
AlertDialog( AlertDialog(
modifier = modifier modifier = modifier,
.dialogBorder,
onDismissRequest = alertDialogState::hide, onDismissRequest = alertDialogState::hide,
properties = DialogProperties(usePlatformDefaultWidth = false) properties = DialogProperties(usePlatformDefaultWidth = false)
) { ) {
@ -191,7 +190,7 @@ fun LineColorPickerAlertDialog(
Column( Column(
Modifier Modifier
.fillMaxWidth(0.95f) .fillMaxWidth(0.95f)
.padding(SimpleTheme.dimens.margin.extraLarge) .padding(SimpleTheme.dimens.padding.extraLarge)
) { ) {
val dialogTextColor = dialogTextColor val dialogTextColor = dialogTextColor
var dialogLineColorPickerBinding by remember { mutableStateOf<DialogLineColorPickerBinding?>(null) } var dialogLineColorPickerBinding by remember { mutableStateOf<DialogLineColorPickerBinding?>(null) }

View file

@ -16,11 +16,10 @@ import androidx.compose.ui.window.DialogProperties
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.composeDonateIntent
import com.simplemobiletools.commons.compose.extensions.config import com.simplemobiletools.commons.compose.extensions.config
import com.simplemobiletools.commons.compose.extensions.getActivity
import com.simplemobiletools.commons.compose.screens.LinkifyText
import com.simplemobiletools.commons.compose.screens.stringFromHTML
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogPurchaseThankYouBinding import com.simplemobiletools.commons.databinding.DialogPurchaseThankYouBinding
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
@ -52,10 +51,8 @@ fun PurchaseThankYouAlertDialog(
alertDialogState: AlertDialogState, alertDialogState: AlertDialogState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val localContext = LocalContext.current.getActivity() val localContext = LocalContext.current
val donateIntent = { val donateIntent = composeDonateIntent()
localContext.launchViewIntent(R.string.thank_you_url)
}
val appId = remember { val appId = remember {
localContext.config.appId localContext.config.appId
} }
@ -87,12 +84,12 @@ fun PurchaseThankYouAlertDialog(
if (appId.removeSuffix(".debug").endsWith(".pro")) { if (appId.removeSuffix(".debug").endsWith(".pro")) {
text += "<br><br>${stringResource(R.string.shared_theme_note)}" text += "<br><br>${stringResource(R.string.shared_theme_note)}"
} }
LinkifyText( LinkifyTextComponent(
fontSize = 16.sp, fontSize = 16.sp,
removeUnderlines = false, removeUnderlines = false,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
stringFromHTML(text) text.fromHtml()
} }
} }
) )

View file

@ -132,7 +132,7 @@ fun RadioGroupAlertDialog(
text = stringResource(id = titleId), text = stringResource(id = titleId),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 24.dp, bottom = SimpleTheme.dimens.margin.medium) .padding(top = 24.dp, bottom = SimpleTheme.dimens.padding.medium)
.padding(horizontal = 24.dp), .padding(horizontal = 24.dp),
color = dialogTextColor, color = dialogTextColor,
fontSize = 21.sp fontSize = 21.sp
@ -147,7 +147,7 @@ fun RadioGroupAlertDialog(
alertDialogState.hide() alertDialogState.hide()
}, },
modifier = Modifier.padding( modifier = Modifier.padding(
vertical = SimpleTheme.dimens.margin.extraLarge, vertical = SimpleTheme.dimens.padding.extraLarge,
) )
) )
} }
@ -159,7 +159,7 @@ fun RadioGroupAlertDialog(
}, },
modifier = Modifier modifier = Modifier
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
.padding(top = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.extraLarge, end = SimpleTheme.dimens.margin.extraLarge) .padding(top = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.extraLarge, end = SimpleTheme.dimens.padding.extraLarge)
) { ) {
Text(text = stringResource(id = R.string.ok)) Text(text = stringResource(id = R.string.ok))
} }

View file

@ -97,7 +97,7 @@ fun RateStarsAlertDialog(
text = stringResource(id = R.string.rate_our_app), text = stringResource(id = R.string.rate_our_app),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.large), .padding(top = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.large),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
color = dialogTextColor, color = dialogTextColor,
fontSize = 16.sp fontSize = 16.sp
@ -105,7 +105,7 @@ fun RateStarsAlertDialog(
StarRating( StarRating(
modifier = Modifier modifier = Modifier
.align(CenterHorizontally) .align(CenterHorizontally)
.padding(SimpleTheme.dimens.margin.extraLarge), .padding(SimpleTheme.dimens.padding.extraLarge),
currentRating = currentRating, currentRating = currentRating,
onRatingChanged = { stars -> onRatingChanged = { stars ->
currentRating = stars currentRating = stars
@ -120,7 +120,7 @@ fun RateStarsAlertDialog(
onClick = alertDialogState::hide, onClick = alertDialogState::hide,
modifier = Modifier modifier = Modifier
.align(End) .align(End)
.padding(end = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.medium) .padding(end = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.medium)
) { ) {
Text(text = stringResource(id = R.string.later)) Text(text = stringResource(id = R.string.later))
} }

View file

@ -99,7 +99,7 @@ fun UpgradeToProAlertDialog(
} }
TextButton( TextButton(
onClick = alertDialogState::hide, onClick = alertDialogState::hide,
modifier = Modifier.padding(horizontal = SimpleTheme.dimens.margin.medium) modifier = Modifier.padding(horizontal = SimpleTheme.dimens.padding.medium)
) { ) {
Text(text = stringResource(id = R.string.later)) Text(text = stringResource(id = R.string.later))
} }

View file

@ -2,39 +2,64 @@ package com.simplemobiletools.commons.dialogs
import android.app.Activity import android.app.Activity
import android.text.Html import android.text.Html
import android.text.Spanned
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.compose.runtime.Composable import androidx.compose.foundation.clickable
import androidx.compose.runtime.Immutable import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.integration.compose.GlideImage
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
import com.simplemobiletools.commons.R import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.andThen
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.databinding.DialogWritePermissionBinding import com.simplemobiletools.commons.databinding.DialogWritePermissionBinding
import com.simplemobiletools.commons.databinding.DialogWritePermissionOtgBinding import com.simplemobiletools.commons.databinding.DialogWritePermissionOtgBinding
import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.humanizePath import com.simplemobiletools.commons.extensions.humanizePath
import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.setupDialogStuff
class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: () -> Unit) { class WritePermissionDialog(activity: Activity, val writePermissionDialogMode: WritePermissionDialogMode, val callback: () -> Unit) {
@Immutable @Immutable
sealed class Mode { sealed class WritePermissionDialogMode {
@Immutable @Immutable
data object Otg : Mode() data object Otg : WritePermissionDialogMode()
@Immutable @Immutable
data object SdCard : Mode() data object SdCard : WritePermissionDialogMode()
@Immutable @Immutable
data class OpenDocumentTreeSDK30(val path: String) : Mode() data class OpenDocumentTreeSDK30(val path: String) : WritePermissionDialogMode()
@Immutable @Immutable
data object CreateDocumentSDK30 : Mode() data object CreateDocumentSDK30 : WritePermissionDialogMode()
} }
private var dialog: AlertDialog? = null private var dialog: AlertDialog? = null
@ -51,20 +76,20 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
val glide = Glide.with(activity) val glide = Glide.with(activity)
val crossFade = DrawableTransitionOptions.withCrossFade() val crossFade = DrawableTransitionOptions.withCrossFade()
when (mode) { when (writePermissionDialogMode) {
Mode.Otg -> { WritePermissionDialogMode.Otg -> {
otgView.writePermissionsDialogOtgText.setText(R.string.confirm_usb_storage_access_text) otgView.writePermissionsDialogOtgText.setText(R.string.confirm_usb_storage_access_text)
glide.load(R.drawable.img_write_storage_otg).transition(crossFade).into(otgView.writePermissionsDialogOtgImage) glide.load(R.drawable.img_write_storage_otg).transition(crossFade).into(otgView.writePermissionsDialogOtgImage)
} }
Mode.SdCard -> { WritePermissionDialogMode.SdCard -> {
glide.load(R.drawable.img_write_storage).transition(crossFade).into(sdCardView.writePermissionsDialogImage) glide.load(R.drawable.img_write_storage).transition(crossFade).into(sdCardView.writePermissionsDialogImage)
glide.load(R.drawable.img_write_storage_sd).transition(crossFade).into(sdCardView.writePermissionsDialogImageSd) glide.load(R.drawable.img_write_storage_sd).transition(crossFade).into(sdCardView.writePermissionsDialogImageSd)
} }
is Mode.OpenDocumentTreeSDK30 -> { is WritePermissionDialogMode.OpenDocumentTreeSDK30 -> {
dialogTitle = R.string.confirm_folder_access_title dialogTitle = R.string.confirm_folder_access_title
val humanizedPath = activity.humanizePath(mode.path) val humanizedPath = activity.humanizePath(writePermissionDialogMode.path)
otgView.writePermissionsDialogOtgText.text = otgView.writePermissionsDialogOtgText.text =
Html.fromHtml(activity.getString(R.string.confirm_storage_access_android_text_specific, humanizedPath)) Html.fromHtml(activity.getString(R.string.confirm_storage_access_android_text_specific, humanizedPath))
glide.load(R.drawable.img_write_storage_sdk_30).transition(crossFade).into(otgView.writePermissionsDialogOtgImage) glide.load(R.drawable.img_write_storage_sdk_30).transition(crossFade).into(otgView.writePermissionsDialogOtgImage)
@ -74,7 +99,7 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
} }
} }
Mode.CreateDocumentSDK30 -> { WritePermissionDialogMode.CreateDocumentSDK30 -> {
dialogTitle = R.string.confirm_folder_access_title dialogTitle = R.string.confirm_folder_access_title
otgView.writePermissionsDialogOtgText.text = Html.fromHtml(activity.getString(R.string.confirm_create_doc_for_new_folder_text)) otgView.writePermissionsDialogOtgText.text = Html.fromHtml(activity.getString(R.string.confirm_create_doc_for_new_folder_text))
glide.load(R.drawable.img_write_storage_create_doc_sdk_30).transition(crossFade).into(otgView.writePermissionsDialogOtgImage) glide.load(R.drawable.img_write_storage_create_doc_sdk_30).transition(crossFade).into(otgView.writePermissionsDialogOtgImage)
@ -92,7 +117,11 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
BaseSimpleActivity.funAfterSAFPermission = null BaseSimpleActivity.funAfterSAFPermission = null
} }
.apply { .apply {
activity.setupDialogStuff(if (mode == Mode.SdCard) sdCardView.root else otgView.root, this, dialogTitle) { alertDialog -> activity.setupDialogStuff(
if (writePermissionDialogMode == WritePermissionDialogMode.SdCard) sdCardView.root else otgView.root,
this,
dialogTitle
) { alertDialog ->
dialog = alertDialog dialog = alertDialog
} }
} }
@ -107,15 +136,186 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
@Composable @Composable
fun WritePermissionAlertDialog( fun WritePermissionAlertDialog(
alertDialogState: AlertDialogState, alertDialogState: AlertDialogState,
modifier: Modifier = Modifier modifier: Modifier = Modifier,
writePermissionDialogMode: WritePermissionDialog.WritePermissionDialogMode,
callback: () -> Unit,
onCancelCallback: () -> Unit
) { ) {
//todo in progress val dialogTitle = remember {
adjustDialogTitle(
writePermissionDialogMode = writePermissionDialogMode,
dialogTitle = R.string.confirm_storage_access_title
)
}
val crossFadeTransition = remember {
DrawableTransitionOptions().crossFade(DrawableCrossFadeFactory.Builder(350).setCrossFadeEnabled(true).build())
}
AlertDialog(
onDismissRequest = alertDialogState::hide andThen onCancelCallback,
modifier = modifier
.fillMaxWidth(0.9f),
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
DialogSurface {
Box {
Column(
modifier = modifier
.padding(bottom = 64.dp)
.verticalScroll(rememberScrollState())
) {
Text(
text = stringResource(id = dialogTitle),
color = dialogTextColor,
modifier = Modifier
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge.plus(SimpleTheme.dimens.padding.large))
.padding(top = SimpleTheme.dimens.padding.extraLarge.plus(SimpleTheme.dimens.padding.small)),
fontSize = 21.sp,
fontWeight = FontWeight.Bold,
)
when (writePermissionDialogMode) {
WritePermissionDialog.WritePermissionDialogMode.CreateDocumentSDK30 -> CreateDocumentSDK30(
crossFadeTransition = crossFadeTransition,
onImageClick = alertDialogState::hide andThen callback
)
is WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30 -> OpenDocumentTreeSDK30(
crossFadeTransition = crossFadeTransition,
onImageClick = alertDialogState::hide andThen callback,
path = writePermissionDialogMode.path
)
WritePermissionDialog.WritePermissionDialogMode.Otg -> OTG(crossFadeTransition)
WritePermissionDialog.WritePermissionDialogMode.SdCard -> SDCard(crossFadeTransition)
}
Spacer(Modifier.padding(vertical = SimpleTheme.dimens.padding.extraLarge))
}
TextButton(
onClick = alertDialogState::hide andThen callback,
modifier = Modifier
.padding(
top = SimpleTheme.dimens.padding.extraLarge,
bottom = SimpleTheme.dimens.padding.extraLarge,
end = SimpleTheme.dimens.padding.extraLarge
)
.align(Alignment.BottomEnd)
) {
Text(text = stringResource(id = R.string.ok))
}
}
}
}
}
@Composable
private fun CreateDocumentSDK30(crossFadeTransition: DrawableTransitionOptions, onImageClick: () -> Unit) {
WritePermissionText(stringResource(R.string.confirm_create_doc_for_new_folder_text).fromHtml())
WritePermissionImage(
crossFadeTransition = crossFadeTransition,
drawable = R.drawable.img_write_storage_create_doc_sdk_30,
modifier = Modifier.clickable(onClick = onImageClick)
)
}
@Composable
private fun OpenDocumentTreeSDK30(crossFadeTransition: DrawableTransitionOptions, onImageClick: () -> Unit, path: String) {
val context = LocalContext.current
val view = LocalView.current
val humanizedPath = remember { if (!view.isInEditMode) context.humanizePath(path) else "" }
WritePermissionText(stringResource(R.string.confirm_storage_access_android_text_specific, humanizedPath).fromHtml())
WritePermissionImage(
crossFadeTransition = crossFadeTransition,
drawable = R.drawable.img_write_storage_sdk_30,
modifier = Modifier.clickable(onClick = onImageClick)
)
}
@Composable
private fun SDCard(crossFadeTransition: DrawableTransitionOptions) {
WritePermissionText(R.string.confirm_storage_access_text)
WritePermissionImage(crossFadeTransition = crossFadeTransition, drawable = R.drawable.img_write_storage)
WritePermissionText(R.string.confirm_storage_access_text_sd)
WritePermissionImage(crossFadeTransition = crossFadeTransition, drawable = R.drawable.img_write_storage_sd)
}
@Composable
private fun OTG(
crossFadeTransition: DrawableTransitionOptions
) {
WritePermissionText(R.string.confirm_usb_storage_access_text)
WritePermissionImage(crossFadeTransition = crossFadeTransition, drawable = R.drawable.img_write_storage_otg)
}
@Composable
private fun WritePermissionImage(
modifier: Modifier = Modifier,
crossFadeTransition: DrawableTransitionOptions,
@DrawableRes drawable: Int
) {
GlideImage(
modifier = modifier
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge.plus(SimpleTheme.dimens.padding.large)),
model = drawable,
contentDescription = null,
) { requestBuilder ->
requestBuilder.transition(crossFadeTransition)
}
}
@Composable
private fun WritePermissionText(@StringRes text: Int) {
Text(
text = stringResource(id = text),
color = dialogTextColor,
modifier = Modifier
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge.plus(SimpleTheme.dimens.padding.medium))
.padding(vertical = SimpleTheme.dimens.padding.extraLarge),
)
}
@Composable
private fun WritePermissionText(text: Spanned) {
LinkifyTextComponent(
modifier = Modifier
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge.plus(SimpleTheme.dimens.padding.medium))
.padding(vertical = SimpleTheme.dimens.padding.extraLarge),
) {
text
}
}
private fun adjustDialogTitle(
writePermissionDialogMode: WritePermissionDialog.WritePermissionDialogMode,
dialogTitle: Int
): Int =
when (writePermissionDialogMode) {
WritePermissionDialog.WritePermissionDialogMode.CreateDocumentSDK30 -> R.string.confirm_folder_access_title
is WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30 -> R.string.confirm_folder_access_title
else -> dialogTitle
}
private class WritePermissionDialogModePreviewParameter : PreviewParameterProvider<WritePermissionDialog.WritePermissionDialogMode> {
override val values: Sequence<WritePermissionDialog.WritePermissionDialogMode>
get() = sequenceOf(
WritePermissionDialog.WritePermissionDialogMode.SdCard,
WritePermissionDialog.WritePermissionDialogMode.Otg,
WritePermissionDialog.WritePermissionDialogMode.CreateDocumentSDK30,
WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30(""),
)
} }
@Composable @Composable
@MyDevices @MyDevices
private fun WritePermissionAlertDialogPreview() { private fun WritePermissionAlertDialogPreview(@PreviewParameter(WritePermissionDialogModePreviewParameter::class) mode: WritePermissionDialog.WritePermissionDialogMode) {
AppThemeSurface { AppThemeSurface {
WritePermissionAlertDialog(rememberAlertDialogState()) WritePermissionAlertDialog(
alertDialogState = rememberAlertDialogState(),
writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30("."),
callback = {},
onCancelCallback = {}
)
} }
} }

View file

@ -39,7 +39,7 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL import com.simplemobiletools.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL
import com.simplemobiletools.commons.databinding.DialogTitleBinding import com.simplemobiletools.commons.databinding.DialogTitleBinding
import com.simplemobiletools.commons.dialogs.* import com.simplemobiletools.commons.dialogs.*
import com.simplemobiletools.commons.dialogs.WritePermissionDialog.Mode import com.simplemobiletools.commons.dialogs.WritePermissionDialog.WritePermissionDialogMode
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.* import com.simplemobiletools.commons.models.*
import com.simplemobiletools.commons.views.MyTextView import com.simplemobiletools.commons.views.MyTextView
@ -113,7 +113,7 @@ fun BaseSimpleActivity.isShowingSAFDialog(path: String): Boolean {
return if ((!isRPlus() && isPathOnSD(path) && !isSDCardSetAsDefaultStorage() && (baseConfig.sdTreeUri.isEmpty() || !hasProperStoredTreeUri(false)))) { return if ((!isRPlus() && isPathOnSD(path) && !isSDCardSetAsDefaultStorage() && (baseConfig.sdTreeUri.isEmpty() || !hasProperStoredTreeUri(false)))) {
runOnUiThread { runOnUiThread {
if (!isDestroyed && !isFinishing) { if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.SdCard) { WritePermissionDialog(this, WritePermissionDialogMode.SdCard) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
putExtra(EXTRA_SHOW_ADVANCED, true) putExtra(EXTRA_SHOW_ADVANCED, true)
try { try {
@ -148,7 +148,7 @@ fun BaseSimpleActivity.isShowingSAFDialogSdk30(path: String): Boolean {
runOnUiThread { runOnUiThread {
if (!isDestroyed && !isFinishing) { if (!isDestroyed && !isFinishing) {
val level = getFirstParentLevel(path) val level = getFirstParentLevel(path)
WritePermissionDialog(this, Mode.OpenDocumentTreeSDK30(path.getFirstParentPath(this, level))) { WritePermissionDialog(this, WritePermissionDialogMode.OpenDocumentTreeSDK30(path.getFirstParentPath(this, level))) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
putExtra(EXTRA_SHOW_ADVANCED, true) putExtra(EXTRA_SHOW_ADVANCED, true)
putExtra(DocumentsContract.EXTRA_INITIAL_URI, createFirstParentTreeUriUsingRootTree(path)) putExtra(DocumentsContract.EXTRA_INITIAL_URI, createFirstParentTreeUriUsingRootTree(path))
@ -183,7 +183,7 @@ fun BaseSimpleActivity.isShowingSAFCreateDocumentDialogSdk30(path: String): Bool
return if (!hasProperStoredDocumentUriSdk30(path)) { return if (!hasProperStoredDocumentUriSdk30(path)) {
runOnUiThread { runOnUiThread {
if (!isDestroyed && !isFinishing) { if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.CreateDocumentSDK30) { WritePermissionDialog(this, WritePermissionDialogMode.CreateDocumentSDK30) {
Intent(Intent.ACTION_CREATE_DOCUMENT).apply { Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
type = DocumentsContract.Document.MIME_TYPE_DIR type = DocumentsContract.Document.MIME_TYPE_DIR
putExtra(EXTRA_SHOW_ADVANCED, true) putExtra(EXTRA_SHOW_ADVANCED, true)
@ -264,7 +264,7 @@ fun BaseSimpleActivity.isShowingOTGDialog(path: String): Boolean {
fun BaseSimpleActivity.showOTGPermissionDialog(path: String) { fun BaseSimpleActivity.showOTGPermissionDialog(path: String) {
runOnUiThread { runOnUiThread {
if (!isDestroyed && !isFinishing) { if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.Otg) { WritePermissionDialog(this, WritePermissionDialogMode.Otg) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
try { try {
startActivityForResult(this, OPEN_DOCUMENT_TREE_OTG) startActivityForResult(this, OPEN_DOCUMENT_TREE_OTG)

View file

@ -4,25 +4,25 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Point import android.graphics.Point
import android.os.Build
import android.os.StatFs import android.os.StatFs
import android.provider.MediaStore import android.provider.MediaStore
import android.telephony.PhoneNumberUtils import android.telephony.PhoneNumberUtils
import android.text.Spannable import android.text.*
import android.text.SpannableString
import android.text.TextUtils
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.widget.TextView import android.widget.TextView
import com.bumptech.glide.signature.ObjectKey import com.bumptech.glide.signature.ObjectKey
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import org.joda.time.DateTime
import org.joda.time.Years
import org.joda.time.format.DateTimeFormat
import java.io.File import java.io.File
import java.text.DateFormat import java.text.DateFormat
import java.text.Normalizer import java.text.Normalizer
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.Locale
import java.util.regex.Pattern import java.util.regex.Pattern
import org.joda.time.DateTime
import org.joda.time.Years
import org.joda.time.format.DateTimeFormat
fun String.getFilenameFromPath() = substring(lastIndexOf("/") + 1) fun String.getFilenameFromPath() = substring(lastIndexOf("/") + 1)
@ -928,3 +928,19 @@ fun String.getMimeType(): String {
} }
fun String.isBlockedNumberPattern() = contains("*") fun String.isBlockedNumberPattern() = contains("*")
fun String?.fromHtml(): Spanned =
when {
this == null -> {
// return an empty spannable if the html is null
SpannableString("")
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
}
else -> {
Html.fromHtml(this)
}
}

View file

@ -48,7 +48,7 @@ class MainActivity : BaseSimpleActivity() {
startActivity(Intent(this, TestDialogActivity::class.java)) startActivity(Intent(this, TestDialogActivity::class.java))
} }
binding.testButton.setOnClickListener { binding.testButton.setOnClickListener {
WritePermissionDialog(this, mode = WritePermissionDialog.Mode.OpenDocumentTreeSDK30("")){ WritePermissionDialog(this, writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30(".")){
} }
} }

View file

@ -62,12 +62,25 @@ class TestDialogActivity : ComponentActivity() {
ShowButton(getUpgradeToProAlertDialogState(), text = "Upgrade to pro") ShowButton(getUpgradeToProAlertDialogState(), text = "Upgrade to pro")
ShowButton(getWhatsNewAlertDialogState(), text = "What's new") ShowButton(getWhatsNewAlertDialogState(), text = "What's new")
ShowButton(getChangeViewTypeAlertDialogState(), text = "Change view type") ShowButton(getChangeViewTypeAlertDialogState(), text = "Change view type")
ShowButton(getWritePermissionAlertDialogState(), text = "Write permission dialog")
Spacer(modifier = Modifier.padding(bottom = 16.dp)) Spacer(modifier = Modifier.padding(bottom = 16.dp))
} }
} }
} }
} }
@Composable
private fun getWritePermissionAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
WritePermissionAlertDialog(
alertDialogState = this,
writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30("."),
callback = {},
onCancelCallback = {}
)
}
}
@Composable @Composable
private fun getChangeViewTypeAlertDialogState() = rememberAlertDialogState().apply { private fun getChangeViewTypeAlertDialogState() = rememberAlertDialogState().apply {
DialogMember { DialogMember {