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.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi",
"-Xcontext-receivers"
)
}
@ -98,6 +99,7 @@ dependencies {
api(libs.material)
api(libs.gson)
implementation(libs.glide.compose)
api(libs.glide)
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.compose.extensions.DEVELOPER_PLAY_STORE_URL
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.helpers.*
import com.simplemobiletools.commons.interfaces.CopyMoveListener
@ -760,7 +760,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
funAfterSAFPermission = callback
WritePermissionDialog(this, Mode.Otg) {
WritePermissionDialog(this, WritePermissionDialogMode.Otg) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
try {
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 = item,
modifier = Modifier.padding(start = SimpleTheme.dimens.margin.medium),
modifier = Modifier.padding(start = SimpleTheme.dimens.padding.medium),
color = dialogTextColor
)
}

View file

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

View file

@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
@ -22,10 +24,12 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.LifecycleResumeEffect
import androidx.lifecycle.compose.LifecycleStartEffect
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.system_ui_controller.rememberSystemUiController
import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.compose.theme.isLitWell
import com.simplemobiletools.commons.extensions.darkenColor
import com.simplemobiletools.commons.extensions.launchViewIntent
fun Context.getActivity(): Activity {
return when (this) {
@ -158,3 +162,12 @@ internal fun TransparentSystemBars(darkIcons: Boolean = !isSystemInDarkTheme())
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 = title,
modifier = Modifier
.padding(start = SimpleTheme.dimens.margin.medium)
.padding(start = SimpleTheme.dimens.padding.medium)
.fillMaxWidth(),
color = scrolledColor,
maxLines = 1,
@ -157,7 +157,7 @@ fun SimpleNavigationIcon(
) {
Box(
modifier
.padding(start = SimpleTheme.dimens.margin.medium)
.padding(start = SimpleTheme.dimens.padding.medium)
.clip(RoundedCornerShape(50))
.clickable(
navigationIconInteractionSource, rememberRipple(
@ -175,13 +175,13 @@ fun SimpleBackIcon(iconColor: Color?) {
if (iconColor == null) {
Icon(
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 {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back),
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 = name,
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 = stringResource(id = R.string.more_options),
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.sp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold
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.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.models.LanguageContributor
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -64,7 +66,7 @@ internal fun ContributorsScreen(
)
}
item {
Spacer(modifier = Modifier.padding(vertical = SimpleTheme.dimens.margin.medium))
Spacer(modifier = Modifier.padding(vertical = SimpleTheme.dimens.padding.medium))
}
item {
SettingsHorizontalDivider()
@ -85,15 +87,15 @@ internal fun ContributorsScreen(
icon = R.drawable.ic_heart_vector,
text = {
val source = stringResource(id = R.string.contributors_label)
LinkifyText {
stringFromHTML(source)
LinkifyTextComponent {
source.fromHtml()
}
},
tint = SimpleTheme.colorScheme.onSurface
)
}
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 = {
val imageSize = Modifier
.size(SimpleTheme.dimens.icon.medium)
.padding(SimpleTheme.dimens.margin.medium)
.padding(SimpleTheme.dimens.padding.medium)
Image(
modifier = imageSize,
painter = painterResource(id = languageContributor.iconId),

View file

@ -1,31 +1,22 @@
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.lazy.itemsIndexed
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text
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.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.lists.SimpleLazyListScaffold
import com.simplemobiletools.commons.compose.settings.SettingsHorizontalDivider
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
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 kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -38,7 +29,7 @@ internal fun FAQScreen(
SimpleLazyListScaffold(
title = stringResource(id = R.string.frequently_asked_questions),
goBack = goBack,
contentPadding = PaddingValues(bottom = SimpleTheme.dimens.margin.medium)
contentPadding = PaddingValues(bottom = SimpleTheme.dimens.padding.medium)
) {
itemsIndexed(faqItems) { index, faqItem ->
Column(modifier = Modifier.fillMaxWidth()) {
@ -56,8 +47,8 @@ internal fun FAQScreen(
},
supportingContent = {
if (faqItem.text is Int) {
val text = stringFromHTML(stringResource(id = faqItem.text))
LinkifyText(
val text = stringResource(id = faqItem.text).fromHtml()
LinkifyTextComponent(
text = { text },
modifier = Modifier.fillMaxWidth(),
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) {
SettingsHorizontalDivider(
modifier = Modifier
.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
@Composable
private fun FAQScreenPreview() {

View file

@ -35,7 +35,7 @@ internal fun LicenseScreen(
Column {
LicenseItem(license, onLicenseClick)
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 = {
Text(
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))
}

View file

@ -86,7 +86,7 @@ internal fun ManageBlockedNumbersScreen(
onCopy: (BlockedNumber) -> Unit,
) {
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 hapticFeedback = LocalHapticFeedback.current
val isInActionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } }
@ -194,7 +194,7 @@ internal fun ManageBlockedNumbersScreen(
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())
) {
when {
@ -324,7 +324,7 @@ private fun BlockedNumber(
movableContentOf {
Text(
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) {
Text(
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
)
}
@ -548,7 +548,7 @@ private fun NonActionModeToolbar(
title = { scrolledTextColor ->
Text(
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,
overflow = TextOverflow.Ellipsis,
color = scrolledTextColor
@ -584,8 +584,8 @@ private fun LazyListScope.emptyBlockedNumbers(
style = TextStyle(fontStyle = FontStyle.Italic, textAlign = TextAlign.Center, color = SimpleTheme.colorScheme.onSurface),
modifier = Modifier
.fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge, bottom = SimpleTheme.dimens.margin.small)
.padding(horizontal = SimpleTheme.dimens.margin.extraLarge)
.padding(top = SimpleTheme.dimens.padding.extraLarge, bottom = SimpleTheme.dimens.padding.small)
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge)
)
}
item {
@ -606,7 +606,7 @@ private fun LazyListScope.emptyBlockedNumbers(
color = SimpleTheme.colorScheme.primary,
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),
modifier = Modifier
.fillMaxWidth()
.padding(top = SimpleTheme.dimens.margin.extraLarge)
.padding(horizontal = SimpleTheme.dimens.margin.extraLarge)
.padding(top = SimpleTheme.dimens.padding.extraLarge)
.padding(horizontal = SimpleTheme.dimens.padding.extraLarge)
)
}
item {
@ -644,7 +644,7 @@ private fun LazyListScope.noPermissionToBlock(
color = SimpleTheme.colorScheme.primary,
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(
modifier = Modifier
.fillMaxWidth()
.padding(end = SimpleTheme.dimens.margin.extraLarge),
.padding(end = SimpleTheme.dimens.padding.extraLarge),
text = label,
color = preferenceLabelColor(isEnabled = isPreferenceEnabled),
fontSize = 14.sp
@ -67,7 +67,7 @@ fun SettingsCheckBoxComponent(
text = value.toString(),
modifier = Modifier
.fillMaxWidth()
.padding(end = SimpleTheme.dimens.margin.extraLarge),
.padding(end = SimpleTheme.dimens.padding.extraLarge),
color = preferenceValueColor(isEnabled = isPreferenceEnabled),
)
}

View file

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

View file

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

View file

@ -20,11 +20,11 @@ fun SettingsTitleTextComponent(
maxLines: Int = 1,
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.uppercase(),
modifier = modifier
.padding(horizontal = SimpleTheme.dimens.margin.small),
.padding(horizontal = SimpleTheme.dimens.padding.small),
color = color,
fontSize = 14.sp,
maxLines = maxLines,

View file

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

View file

@ -5,11 +5,11 @@ import androidx.compose.ui.unit.Dp
@Immutable
data class Dimensions(
val margin: Margins,
val padding: Paddings,
val icon: IconSizes
) {
@Immutable
data class Margins(
data class Paddings(
val extraSmall: Dp,
val small: 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.compose.alert_dialog.AlertDialogState
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.screens.LinkifyText
import com.simplemobiletools.commons.compose.screens.stringFromHTML
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogTextviewBinding
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.getStringsPackageName
import com.simplemobiletools.commons.extensions.launchViewIntent
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.*
class AppSideloadedDialog(val activity: Activity, val callback: () -> Unit) {
private var dialog: AlertDialog? = null
@ -96,8 +92,8 @@ fun AppSideLoadedAlertDialog(
shape = dialogShape,
text = {
val source = stringResource(id = R.string.sideloaded_app, url)
LinkifyText(fontSize = 16.sp, removeUnderlines = false) {
stringFromHTML(source)
LinkifyTextComponent(fontSize = 16.sp, removeUnderlines = false) {
source.fromHtml()
}
},
title = {

View file

@ -147,7 +147,7 @@ fun ChangeDateTimeFormatAlertDialog(
items = kinds, selected = selected,
setSelected = setSelected,
modifier = Modifier.padding(
vertical = SimpleTheme.dimens.margin.extraLarge,
vertical = SimpleTheme.dimens.padding.extraLarge,
)
)
SettingsHorizontalDivider()
@ -157,7 +157,7 @@ fun ChangeDateTimeFormatAlertDialog(
label = stringResource(id = R.string.use_24_hour_time_format),
initialValue = is24HoursSelected,
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,
modifier = Modifier
.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)
) {
TextButton(onClick = {

View file

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

View file

@ -165,7 +165,7 @@ fun ColorPickerAlertDialog(
Column(
Modifier
.fillMaxWidth(0.95f)
.padding(SimpleTheme.dimens.margin.extraLarge)
.padding(SimpleTheme.dimens.padding.extraLarge)
) {
var dialogColorPickerBinding by remember { mutableStateOf<DialogColorPickerBinding?>(null) }
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.compose.alert_dialog.AlertDialogState
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.getActivity
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.SimpleTheme
import com.simplemobiletools.commons.databinding.DialogDonateBinding
@ -110,13 +109,13 @@ fun DonateAlertDialog(
},
text = {
val source = stringResource(id = R.string.donate_short)
LinkifyText(
LinkifyTextComponent(
fontSize = 16.sp,
removeUnderlines = false,
textAlignment = TextView.TEXT_ALIGNMENT_CENTER,
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.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
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.getActivity
import com.simplemobiletools.commons.compose.extensions.composeDonateIntent
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.SimpleTheme
import com.simplemobiletools.commons.databinding.DialogFeatureLockedBinding
@ -71,10 +69,7 @@ fun FeatureLockedAlertDialog(
modifier: Modifier = Modifier,
cancelCallback: () -> Unit
) {
val localContext = LocalContext.current.getActivity()
val donateIntent = {
localContext.launchViewIntent(R.string.thank_you_url)
}
val donateIntent = composeDonateIntent()
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
@ -121,13 +116,13 @@ fun FeatureLockedAlertDialog(
},
text = {
val source = stringResource(id = R.string.features_locked)
LinkifyText(
LinkifyTextComponent(
fontSize = 16.sp,
removeUnderlines = false,
modifier = Modifier.fillMaxWidth(),
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.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import com.google.android.material.appbar.MaterialToolbar
import com.simplemobiletools.commons.R
@ -166,8 +167,7 @@ class LineColorPickerDialog(
fun LineColorPickerAlertDialog(
alertDialogState: AlertDialogState,
modifier: Modifier = Modifier,
@ColorInt
color: Int,
@ColorInt color: Int,
isPrimaryColorPicker: Boolean,
primaryColors: Int = R.array.md_primary_colors,
appIconIDs: ArrayList<Int>? = null,
@ -179,11 +179,10 @@ fun LineColorPickerAlertDialog(
var wasDimmedBackgroundRemoved by remember { mutableStateOf(false) }
val defaultColor = remember {
context.resources.getColor(R.color.color_primary)
ContextCompat.getColor(context, R.color.color_primary)
}
AlertDialog(
modifier = modifier
.dialogBorder,
modifier = modifier,
onDismissRequest = alertDialogState::hide,
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
@ -191,7 +190,7 @@ fun LineColorPickerAlertDialog(
Column(
Modifier
.fillMaxWidth(0.95f)
.padding(SimpleTheme.dimens.margin.extraLarge)
.padding(SimpleTheme.dimens.padding.extraLarge)
) {
val dialogTextColor = dialogTextColor
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.compose.alert_dialog.AlertDialogState
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.composeDonateIntent
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.databinding.DialogPurchaseThankYouBinding
import com.simplemobiletools.commons.extensions.*
@ -52,10 +51,8 @@ fun PurchaseThankYouAlertDialog(
alertDialogState: AlertDialogState,
modifier: Modifier = Modifier,
) {
val localContext = LocalContext.current.getActivity()
val donateIntent = {
localContext.launchViewIntent(R.string.thank_you_url)
}
val localContext = LocalContext.current
val donateIntent = composeDonateIntent()
val appId = remember {
localContext.config.appId
}
@ -87,12 +84,12 @@ fun PurchaseThankYouAlertDialog(
if (appId.removeSuffix(".debug").endsWith(".pro")) {
text += "<br><br>${stringResource(R.string.shared_theme_note)}"
}
LinkifyText(
LinkifyTextComponent(
fontSize = 16.sp,
removeUnderlines = false,
modifier = Modifier.fillMaxWidth()
) {
stringFromHTML(text)
text.fromHtml()
}
}
)

View file

@ -132,7 +132,7 @@ fun RadioGroupAlertDialog(
text = stringResource(id = titleId),
modifier = Modifier
.fillMaxWidth()
.padding(top = 24.dp, bottom = SimpleTheme.dimens.margin.medium)
.padding(top = 24.dp, bottom = SimpleTheme.dimens.padding.medium)
.padding(horizontal = 24.dp),
color = dialogTextColor,
fontSize = 21.sp
@ -147,7 +147,7 @@ fun RadioGroupAlertDialog(
alertDialogState.hide()
},
modifier = Modifier.padding(
vertical = SimpleTheme.dimens.margin.extraLarge,
vertical = SimpleTheme.dimens.padding.extraLarge,
)
)
}
@ -159,7 +159,7 @@ fun RadioGroupAlertDialog(
},
modifier = Modifier
.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))
}

View file

@ -97,7 +97,7 @@ fun RateStarsAlertDialog(
text = stringResource(id = R.string.rate_our_app),
modifier = Modifier
.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,
color = dialogTextColor,
fontSize = 16.sp
@ -105,7 +105,7 @@ fun RateStarsAlertDialog(
StarRating(
modifier = Modifier
.align(CenterHorizontally)
.padding(SimpleTheme.dimens.margin.extraLarge),
.padding(SimpleTheme.dimens.padding.extraLarge),
currentRating = currentRating,
onRatingChanged = { stars ->
currentRating = stars
@ -120,7 +120,7 @@ fun RateStarsAlertDialog(
onClick = alertDialogState::hide,
modifier = Modifier
.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))
}

View file

@ -99,7 +99,7 @@ fun UpgradeToProAlertDialog(
}
TextButton(
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))
}

View file

@ -2,39 +2,64 @@ package com.simplemobiletools.commons.dialogs
import android.app.Activity
import android.text.Html
import android.text.Spanned
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.foundation.clickable
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.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.integration.compose.GlideImage
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
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.andThen
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.DialogWritePermissionOtgBinding
import com.simplemobiletools.commons.extensions.fromHtml
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.humanizePath
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
sealed class Mode {
sealed class WritePermissionDialogMode {
@Immutable
data object Otg : Mode()
data object Otg : WritePermissionDialogMode()
@Immutable
data object SdCard : Mode()
data object SdCard : WritePermissionDialogMode()
@Immutable
data class OpenDocumentTreeSDK30(val path: String) : Mode()
data class OpenDocumentTreeSDK30(val path: String) : WritePermissionDialogMode()
@Immutable
data object CreateDocumentSDK30 : Mode()
data object CreateDocumentSDK30 : WritePermissionDialogMode()
}
private var dialog: AlertDialog? = null
@ -51,20 +76,20 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
val glide = Glide.with(activity)
val crossFade = DrawableTransitionOptions.withCrossFade()
when (mode) {
Mode.Otg -> {
when (writePermissionDialogMode) {
WritePermissionDialogMode.Otg -> {
otgView.writePermissionsDialogOtgText.setText(R.string.confirm_usb_storage_access_text)
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_sd).transition(crossFade).into(sdCardView.writePermissionsDialogImageSd)
}
is Mode.OpenDocumentTreeSDK30 -> {
is WritePermissionDialogMode.OpenDocumentTreeSDK30 -> {
dialogTitle = R.string.confirm_folder_access_title
val humanizedPath = activity.humanizePath(mode.path)
val humanizedPath = activity.humanizePath(writePermissionDialogMode.path)
otgView.writePermissionsDialogOtgText.text =
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)
@ -74,7 +99,7 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
}
}
Mode.CreateDocumentSDK30 -> {
WritePermissionDialogMode.CreateDocumentSDK30 -> {
dialogTitle = R.string.confirm_folder_access_title
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)
@ -92,7 +117,11 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
BaseSimpleActivity.funAfterSAFPermission = null
}
.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
}
}
@ -107,15 +136,186 @@ class WritePermissionDialog(activity: Activity, val mode: Mode, val callback: ()
@Composable
fun WritePermissionAlertDialog(
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
@MyDevices
private fun WritePermissionAlertDialogPreview() {
private fun WritePermissionAlertDialogPreview(@PreviewParameter(WritePermissionDialogModePreviewParameter::class) mode: WritePermissionDialog.WritePermissionDialogMode) {
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.databinding.DialogTitleBinding
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.models.*
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)))) {
runOnUiThread {
if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.SdCard) {
WritePermissionDialog(this, WritePermissionDialogMode.SdCard) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
putExtra(EXTRA_SHOW_ADVANCED, true)
try {
@ -148,7 +148,7 @@ fun BaseSimpleActivity.isShowingSAFDialogSdk30(path: String): Boolean {
runOnUiThread {
if (!isDestroyed && !isFinishing) {
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 {
putExtra(EXTRA_SHOW_ADVANCED, true)
putExtra(DocumentsContract.EXTRA_INITIAL_URI, createFirstParentTreeUriUsingRootTree(path))
@ -183,7 +183,7 @@ fun BaseSimpleActivity.isShowingSAFCreateDocumentDialogSdk30(path: String): Bool
return if (!hasProperStoredDocumentUriSdk30(path)) {
runOnUiThread {
if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.CreateDocumentSDK30) {
WritePermissionDialog(this, WritePermissionDialogMode.CreateDocumentSDK30) {
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
type = DocumentsContract.Document.MIME_TYPE_DIR
putExtra(EXTRA_SHOW_ADVANCED, true)
@ -264,7 +264,7 @@ fun BaseSimpleActivity.isShowingOTGDialog(path: String): Boolean {
fun BaseSimpleActivity.showOTGPermissionDialog(path: String) {
runOnUiThread {
if (!isDestroyed && !isFinishing) {
WritePermissionDialog(this, Mode.Otg) {
WritePermissionDialog(this, WritePermissionDialogMode.Otg) {
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
try {
startActivityForResult(this, OPEN_DOCUMENT_TREE_OTG)

View file

@ -4,25 +4,25 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Point
import android.os.Build
import android.os.StatFs
import android.provider.MediaStore
import android.telephony.PhoneNumberUtils
import android.text.Spannable
import android.text.SpannableString
import android.text.TextUtils
import android.text.*
import android.text.style.ForegroundColorSpan
import android.widget.TextView
import com.bumptech.glide.signature.ObjectKey
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.text.DateFormat
import java.text.Normalizer
import java.text.SimpleDateFormat
import java.util.*
import java.util.Locale
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)
@ -928,3 +928,19 @@ fun String.getMimeType(): String {
}
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))
}
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(getWhatsNewAlertDialogState(), text = "What's new")
ShowButton(getChangeViewTypeAlertDialogState(), text = "Change view type")
ShowButton(getWritePermissionAlertDialogState(), text = "Write permission dialog")
Spacer(modifier = Modifier.padding(bottom = 16.dp))
}
}
}
}
@Composable
private fun getWritePermissionAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
WritePermissionAlertDialog(
alertDialogState = this,
writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30("."),
callback = {},
onCancelCallback = {}
)
}
}
@Composable
private fun getChangeViewTypeAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {