- create new folder dialog
- enter password
- folder lock notice
- bottom sheet chooser
This commit is contained in:
FunkyMuse 2023-10-10 13:33:55 +02:00
parent ec813b1389
commit 32906028b2
29 changed files with 717 additions and 30 deletions

View file

@ -1,4 +1,4 @@
package com.simplemobiletools.commons.dialogs
package com.simplemobiletools.commons.compose.alert_dialog
import androidx.compose.foundation.background
import androidx.compose.foundation.border

View file

@ -0,0 +1,127 @@
package com.simplemobiletools.commons.compose.bottom_sheet
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.SheetValue
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.saveable.rememberSaveable
import kotlinx.coroutines.launch
@Composable
fun rememberBottomSheetDialogState(
openBottomSheet: Boolean = false,
skipPartiallyExpanded: Boolean = false,
edgeToEdgeEnabled: Boolean = false,
confirmValueChange: (SheetValue) -> Boolean = { true },
) = remember {
BottomSheetDialogState(
openBottomSheet = openBottomSheet,
skipPartiallyExpanded = skipPartiallyExpanded,
edgeToEdgeEnabled = edgeToEdgeEnabled,
confirmValueChange = confirmValueChange
)
}
@Composable
fun rememberBottomSheetDialogStateSaveable(
openBottomSheet: Boolean = false,
skipPartiallyExpanded: Boolean = false,
edgeToEdgeEnabled: Boolean = false,
confirmValueChange: (SheetValue) -> Boolean = { true },
) = rememberSaveable(stateSaver = mapSaver(save = {
mapOf(
"skipPartiallyExpanded" to skipPartiallyExpanded,
"edgeToEdgeEnabled" to edgeToEdgeEnabled,
"openBottomSheet" to openBottomSheet,
)
}, restore = {
BottomSheetDialogState(
openBottomSheet = it["openBottomSheet"] as Boolean,
skipPartiallyExpanded = it["openBottomSheet"] as Boolean,
edgeToEdgeEnabled = it["openBottomSheet"] as Boolean,
)
})) {
mutableStateOf(
BottomSheetDialogState(
skipPartiallyExpanded = skipPartiallyExpanded,
edgeToEdgeEnabled = edgeToEdgeEnabled,
confirmValueChange = confirmValueChange
)
)
}
@Stable
class BottomSheetDialogState(
openBottomSheet: Boolean = false,
private val skipPartiallyExpanded: Boolean = false,
private val edgeToEdgeEnabled: Boolean = false,
private val confirmValueChange: (SheetValue) -> Boolean = { true },
) {
@Composable
fun rememberWindowInsets(
defaultInsets: WindowInsets = BottomSheetDefaults.windowInsets
) = remember { if (edgeToEdgeEnabled) WindowInsets(0) else defaultInsets }
@Composable
fun rememberSheetState() = rememberModalBottomSheetState(
skipPartiallyExpanded = skipPartiallyExpanded,
confirmValueChange = confirmValueChange
)
var isOpen by mutableStateOf(openBottomSheet)
private set
private var closeDialog by mutableStateOf(false)
/**
* Closes the dialog completely, calling [open] will create the dialog
* from scratch.
*/
fun close() {
if (closeDialog) {
closeDialog = false
}
closeDialog = true
}
fun open() {
if (isOpen) {
isOpen = false
}
isOpen = true
}
/**
* Minimises the dialog, calling [open] again will
* maximize it, keep in mind you need to call it with the
* appropriate params to avoid jumping if for example: it was fully expanded then
* you've minimised it and now you've called [open] again.
*/
fun minimise() {
isOpen = false
}
@Composable
fun DialogMember(
content: @Composable () -> Unit
) {
val bottomSheetState = rememberSheetState()
LaunchedEffect(closeDialog) {
if (closeDialog) {
launch { bottomSheetState.hide() }.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
minimise()
}
}
}
}
if (isOpen) {
content()
}
}
}

View file

@ -0,0 +1,54 @@
package com.simplemobiletools.commons.compose.bottom_sheet
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.alert_dialog.dialogContainerColor
import com.simplemobiletools.commons.compose.alert_dialog.dialogElevation
import com.simplemobiletools.commons.compose.theme.LocalTheme
import com.simplemobiletools.commons.compose.theme.Shapes
import com.simplemobiletools.commons.compose.theme.light_grey_stroke
import com.simplemobiletools.commons.compose.theme.model.Theme
val bottomSheetDialogShape = Shapes.extraLarge.copy(
bottomEnd = CornerSize(0f),
bottomStart = CornerSize(0f)
)
val Modifier.bottomSheetDialogBorder: Modifier
@ReadOnlyComposable
@Composable get() =
when (LocalTheme.current) {
is Theme.BlackAndWhite -> then(Modifier.border(2.dp, light_grey_stroke, bottomSheetDialogShape))
else -> Modifier
}
@Composable
fun BottomSheetSpacerEdgeToEdge() {
Spacer(modifier = Modifier.padding(bottom = 42.dp))
}
@Composable
fun BottomSheetDialogSurface(
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit
) {
Surface(
modifier = modifier
.fillMaxSize()
.bottomSheetDialogBorder,
shape = bottomSheetDialogShape,
color = dialogContainerColor,
tonalElevation = dialogElevation,
) {
Column(modifier = Modifier.background(dialogContainerColor)) {
content()
}
}
}

View file

@ -10,11 +10,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.rememberMutableInteractionSource
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.compose.theme.SimpleTheme
import com.simplemobiletools.commons.dialogs.dialogTextColor
@Composable
fun RadioButtonDialogComponent(

View file

@ -13,8 +13,7 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.models.BlockedNumber

View file

@ -16,8 +16,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
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.alert_dialog.*
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface

View file

@ -2,8 +2,36 @@ package com.simplemobiletools.commons.dialogs
import android.os.Bundle
import android.view.ViewGroup
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import androidx.fragment.app.FragmentManager
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.adapters.setupSimpleListItem
import com.simplemobiletools.commons.compose.alert_dialog.dialogContainerColor
import com.simplemobiletools.commons.compose.alert_dialog.dialogElevation
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.bottom_sheet.BottomSheetDialogState
import com.simplemobiletools.commons.compose.bottom_sheet.BottomSheetDialogSurface
import com.simplemobiletools.commons.compose.bottom_sheet.BottomSheetSpacerEdgeToEdge
import com.simplemobiletools.commons.compose.bottom_sheet.bottomSheetDialogShape
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.databinding.ItemSimpleListBinding
import com.simplemobiletools.commons.fragments.BaseBottomSheetDialogFragment
import com.simplemobiletools.commons.models.SimpleListItem
@ -52,3 +80,99 @@ open class BottomSheetChooserDialog : BaseBottomSheetDialogFragment() {
}
}
}
@Composable
fun ChooserBottomSheetDialog(
bottomSheetDialogState: BottomSheetDialogState,
modifier: Modifier = Modifier,
items: SnapshotStateList<SimpleListItem>,
onItemClicked: (SimpleListItem) -> Unit
) {
val bottomSheetState = bottomSheetDialogState.rememberSheetState()
val windowInsets = bottomSheetDialogState.rememberWindowInsets()
ModalBottomSheet(
modifier = modifier,
onDismissRequest = bottomSheetDialogState::close,
sheetState = bottomSheetState,
windowInsets = windowInsets,
dragHandle = {},
shape = bottomSheetDialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
) {
ChooserScreenContent(items = items, onItemClicked = onItemClicked)
}
}
@Composable
private fun ChooserScreenContent(
items: SnapshotStateList<SimpleListItem>,
onItemClicked: (SimpleListItem) -> Unit
) {
BottomSheetDialogSurface {
Text(
text = stringResource(id = R.string.please_select_destination),
color = dialogTextColor,
fontSize = 21.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(SimpleTheme.dimens.padding.extraLarge)
.padding(top = SimpleTheme.dimens.padding.large)
)
for (item in items) {
val color = if (item.selected) SimpleTheme.colorScheme.primary else SimpleTheme.colorScheme.onSurface
ListItem(
modifier = Modifier
.clickable {
onItemClicked(item)
},
headlineContent = {
Text(stringResource(id = item.textRes), color = color)
},
leadingContent = {
if (item.imageRes != null) {
Image(
painter = painterResource(id = item.imageRes),
contentDescription = stringResource(id = item.textRes),
colorFilter = ColorFilter.tint(color)
)
}
},
trailingContent = {
if (item.selected) {
Image(
painter = painterResource(id = R.drawable.ic_check_circle_vector),
contentDescription = null,
colorFilter = ColorFilter.tint(color)
)
}
},
colors = ListItemDefaults.colors(containerColor = dialogContainerColor)
)
}
BottomSheetSpacerEdgeToEdge()
}
}
@MyDevices
@Composable
private fun ChooserBottomSheetDialogPreview() {
AppThemeSurface {
val list = remember {
mutableStateListOf(
SimpleListItem(1, R.string.record_video, R.drawable.ic_camera_vector),
SimpleListItem(2, R.string.record_audio, R.drawable.ic_microphone_vector, selected = true),
SimpleListItem(4, R.string.choose_contact, R.drawable.ic_add_person_vector)
)
}
ChooserScreenContent(items = list, onItemClicked = {})
/* https://issuetracker.google.com/issues/304300690
ChooserBottomSheetDialog(
bottomSheetDialogState = rememberBottomSheetDialogState(),
items = list,
onItemClicked = {},
modifier = Modifier.fillMaxSize()
)*/
}
}

View file

@ -27,8 +27,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogCallConfirmationBinding

View file

@ -22,6 +22,7 @@ import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.RadioGroupDialogComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices

View file

@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
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.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.RadioGroupDialogComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices

View file

@ -33,6 +33,8 @@ import androidx.core.view.children
import androidx.core.view.updateLayoutParams
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState
import com.simplemobiletools.commons.compose.alert_dialog.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.dialogBorder
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.config

View file

@ -11,8 +11,7 @@ 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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogMessageBinding

View file

@ -12,8 +12,7 @@ import androidx.compose.ui.text.font.FontWeight
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogMessageBinding

View file

@ -2,8 +2,26 @@ package com.simplemobiletools.commons.dialogs
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
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.unit.sp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.compose.alert_dialog.*
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.databinding.DialogCreateNewFolderBinding
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.isRPlus
@ -33,6 +51,7 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
createFolder("$path/$name", alertDialog)
}
else -> activity.toast(R.string.invalid_name)
}
})
@ -49,6 +68,7 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
sendSuccess(alertDialog, path)
}
}
activity.needsStupidWritePermissions(path) -> activity.handleSAFDialog(path) {
if (it) {
try {
@ -64,12 +84,14 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
}
}
}
File(path).mkdirs() -> sendSuccess(alertDialog, path)
isRPlus() && activity.isAStorageRootFolder(path.getParentPath()) -> activity.handleSAFCreateDocumentDialogSdk30(path) {
if (it) {
sendSuccess(alertDialog, path)
}
}
else -> activity.toast(activity.getString(R.string.could_not_create_folder, path.getFilenameFromPath()))
}
} catch (e: Exception) {
@ -82,3 +104,113 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
alertDialog.dismiss()
}
}
@Composable
fun CreateNewFolderAlertDialog(
alertDialogState: AlertDialogState,
modifier: Modifier = Modifier,
path: String,
callback: (path: String) -> Unit
) {
val focusRequester = remember { FocusRequester() }
val context = LocalContext.current
val view = LocalView.current
var title by remember { mutableStateOf("") }
AlertDialog(
modifier = modifier.dialogBorder,
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
onDismissRequest = alertDialogState::hide,
confirmButton = {
TextButton(
onClick = {
alertDialogState.hide()
//add callback
val name = title
when {
name.isEmpty() -> context.toast(R.string.empty_name)
name.isAValidFilename() -> {
val file = File(path, name)
if (file.exists()) {
context.toast(R.string.name_taken)
return@TextButton
}
callback("$path/$name")
}
else -> context.toast(R.string.invalid_name)
}
}
) {
Text(text = stringResource(id = R.string.ok))
}
},
dismissButton = {
TextButton(
onClick = alertDialogState::hide
) {
Text(text = stringResource(id = R.string.cancel))
}
},
title = {
Text(
text = stringResource(id = R.string.create_new_folder),
color = dialogTextColor,
fontSize = 21.sp,
fontWeight = FontWeight.Bold,
)
},
text = {
Column(
Modifier.fillMaxWidth(),
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth(),
value = if (!view.isInEditMode) "${context.humanizePath(path).trimEnd('/')}/" else path,
onValueChange = {},
label = {
Text(text = stringResource(id = R.string.folder))
},
enabled = false,
colors = OutlinedTextFieldDefaults.colors(
disabledTextColor = dialogTextColor,
disabledBorderColor = SimpleTheme.colorScheme.primary,
disabledLabelColor = SimpleTheme.colorScheme.primary,
)
)
Spacer(modifier = Modifier.padding(vertical = SimpleTheme.dimens.padding.medium))
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = title,
onValueChange = {
title = it
},
label = {
Text(text = stringResource(id = R.string.title))
},
)
}
}
)
ShowKeyboardWhenDialogIsOpenedAndRequestFocus(focusRequester = focusRequester)
}
@MyDevices
@Composable
private fun CreateNewFolderAlertDialogPreview() {
AppThemeSurface {
CreateNewFolderAlertDialog(
alertDialogState = rememberAlertDialogState(),
path = "Internal/",
callback = {}
)
}
}

View file

@ -22,8 +22,7 @@ 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.alert_dialog.*
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.getActivity

View file

@ -1,8 +1,29 @@
package com.simplemobiletools.commons.dialogs
import androidx.appcompat.app.AlertDialog
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.sp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.compose.alert_dialog.*
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.databinding.DialogEnterPasswordBinding
import com.simplemobiletools.commons.extensions.*
@ -52,3 +73,95 @@ class EnterPasswordDialog(
view.password.text?.clear()
}
}
@Composable
fun EnterPasswordAlertDialog(
alertDialogState: AlertDialogState,
modifier: Modifier = Modifier,
callback: (password: String) -> Unit,
cancelCallback: () -> Unit
) {
val localContext = LocalContext.current
val focusRequester = remember { FocusRequester() }
var password by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
val visualTransformation by remember {
derivedStateOf {
if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation()
}
}
AlertDialog(
modifier = modifier.dialogBorder,
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
onDismissRequest = alertDialogState::hide andThen cancelCallback,
confirmButton = {
TextButton(
onClick = {
if (password.isEmpty()) {
localContext.toast(R.string.empty_password)
} else {
alertDialogState.hide()
callback(password)
}
}
) {
Text(text = stringResource(id = R.string.ok))
}
},
dismissButton = {
TextButton(
onClick = alertDialogState::hide
) {
Text(text = stringResource(id = R.string.cancel))
}
},
title = {
Text(
text = stringResource(id = R.string.enter_password),
color = dialogTextColor,
fontSize = 21.sp,
fontWeight = FontWeight.Bold,
)
},
text = {
OutlinedTextField(
visualTransformation = visualTransformation,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
trailingIcon = {
val image = passwordImageVector(passwordVisible)
IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(imageVector = image, null)
}
},
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = password,
onValueChange = {
password = it
},
label = {
Text(text = stringResource(id = R.string.password))
},
singleLine = true
)
}
)
ShowKeyboardWhenDialogIsOpenedAndRequestFocus(focusRequester = focusRequester)
}
private fun passwordImageVector(passwordVisible: Boolean) = if (passwordVisible) {
Icons.Filled.Visibility
} else {
Icons.Filled.VisibilityOff
}
@MyDevices
@Composable
private fun EnterPasswordAlertDialogPreview() {
AppThemeSurface {
EnterPasswordAlertDialog(rememberAlertDialogState(), callback = {}, cancelCallback = {})
}
}

View file

@ -22,8 +22,7 @@ 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.alert_dialog.*
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.composeDonateIntent

View file

@ -1,7 +1,19 @@
package com.simplemobiletools.commons.dialogs
import android.app.Activity
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.alert_dialog.*
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.databinding.DialogTextviewBinding
import com.simplemobiletools.commons.extensions.baseConfig
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
@ -26,3 +38,57 @@ class FolderLockingNoticeDialog(val activity: Activity, val callback: () -> Unit
callback()
}
}
@Composable
fun FolderLockingNoticeAlertDialog(
alertDialogState: AlertDialogState,
modifier: Modifier = Modifier,
callback: () -> Unit
) {
AlertDialog(
modifier = modifier.dialogBorder,
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
onDismissRequest = alertDialogState::hide,
confirmButton = {
TextButton(
onClick = alertDialogState::hide andThen callback
) {
Text(text = stringResource(id = R.string.ok))
}
},
dismissButton = {
TextButton(
onClick = alertDialogState::hide
) {
Text(text = stringResource(id = R.string.cancel))
}
},
title = {
Text(
text = stringResource(id = R.string.disclaimer),
color = dialogTextColor,
fontSize = 21.sp,
fontWeight = FontWeight.Bold,
)
},
text = {
Text(
text = stringResource(id = R.string.lock_folder_notice),
color = dialogTextColor,
)
}
)
}
@Composable
@MyDevices
private fun FolderLockingNoticeAlertDialogPreview() {
AppThemeSurface {
FolderLockingNoticeAlertDialog(
alertDialogState = rememberAlertDialogState(),
callback = {},
)
}
}

View file

@ -25,6 +25,8 @@ import com.google.android.material.appbar.MaterialToolbar
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.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface

View file

@ -11,8 +11,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.databinding.DialogMessageBinding

View file

@ -14,8 +14,7 @@ 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.alert_dialog.*
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.composeDonateIntent

View file

@ -24,6 +24,8 @@ import androidx.compose.ui.unit.dp
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.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.RadioGroupDialogComponent
import com.simplemobiletools.commons.compose.extensions.BooleanPreviewParameterProvider

View file

@ -26,6 +26,8 @@ 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.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface

View file

@ -17,8 +17,7 @@ import androidx.compose.ui.text.font.FontWeight
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.extensions.andThen
import com.simplemobiletools.commons.compose.theme.AppThemeSurface

View file

@ -16,8 +16,7 @@ import androidx.compose.ui.text.font.FontWeight
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.alert_dialog.*
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.settings.SettingsHorizontalDivider
import com.simplemobiletools.commons.compose.theme.AppThemeSurface

View file

@ -32,6 +32,8 @@ 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.DialogSurface
import com.simplemobiletools.commons.compose.alert_dialog.dialogTextColor
import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import com.simplemobiletools.commons.compose.components.LinkifyTextComponent
import com.simplemobiletools.commons.compose.extensions.MyDevices

View file

@ -1,9 +1,11 @@
package com.simplemobiletools.commons.models
import android.os.Parcelable
import androidx.compose.runtime.Immutable
import kotlinx.parcelize.Parcelize
@Parcelize
@Immutable
data class SimpleListItem(val id: Int, val textRes: Int, val imageRes: Int? = null, val selected: Boolean = false) : Parcelable {
companion object {

View file

@ -5,7 +5,6 @@ import android.os.Bundle
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.activities.ManageBlockedNumbersActivity
import com.simplemobiletools.commons.dialogs.BottomSheetChooserDialog
import com.simplemobiletools.commons.dialogs.WritePermissionDialog
import com.simplemobiletools.commons.extensions.appLaunched
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.viewBinding
@ -48,9 +47,7 @@ class MainActivity : BaseSimpleActivity() {
startActivity(Intent(this, TestDialogActivity::class.java))
}
binding.testButton.setOnClickListener {
WritePermissionDialog(this, writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30(".")){
}
launchBottomSheetDemo()
}
}

View file

@ -1,6 +1,7 @@
package com.simplemobiletools.commons.samples.activities
import android.os.Bundle
import android.os.Environment
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@ -11,6 +12,7 @@ import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
@ -18,6 +20,8 @@ import androidx.compose.ui.unit.dp
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.bottom_sheet.BottomSheetDialogState
import com.simplemobiletools.commons.compose.bottom_sheet.rememberBottomSheetDialogState
import com.simplemobiletools.commons.compose.extensions.config
import com.simplemobiletools.commons.compose.extensions.rateStarsRedirectAndThankYou
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
@ -28,6 +32,7 @@ import com.simplemobiletools.commons.extensions.launchViewIntent
import com.simplemobiletools.commons.extensions.toHex
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.commons.models.SimpleListItem
import kotlinx.collections.immutable.toImmutableList
class TestDialogActivity : ComponentActivity() {
@ -63,12 +68,64 @@ class TestDialogActivity : ComponentActivity() {
ShowButton(getWhatsNewAlertDialogState(), text = "What's new")
ShowButton(getChangeViewTypeAlertDialogState(), text = "Change view type")
ShowButton(getWritePermissionAlertDialogState(), text = "Write permission dialog")
ShowButton(getCreateNewFolderAlertDialogState(), text = "Create new folder")
ShowButton(getEnterPasswordAlertDialogState(), text = "Enter password")
ShowButton(getFolderLockingNoticeAlertDialogState(), text = "Folder locking notice")
ShowButton(getChooserBottomSheetDialogState(), text = "Bottom sheet chooser")
Spacer(modifier = Modifier.padding(bottom = 16.dp))
}
}
}
}
@Composable
private fun getChooserBottomSheetDialogState() = rememberBottomSheetDialogState().apply {
DialogMember {
val list = remember {
mutableStateListOf(
SimpleListItem(1, R.string.record_video, R.drawable.ic_camera_vector),
SimpleListItem(2, R.string.record_audio, R.drawable.ic_microphone_vector, selected = true),
SimpleListItem(4, R.string.choose_contact, R.drawable.ic_add_person_vector)
)
}
ChooserBottomSheetDialog(bottomSheetDialogState = this, items = list, onItemClicked = {
val indexToUpdate = list.indexOf(it)
list.forEachIndexed { index, simpleListItem ->
if (indexToUpdate == index) {
list[index] = it.copy(selected = true)
} else {
list[index] = simpleListItem.copy(selected = false)
}
}
})
}
}
@Composable
private fun getFolderLockingNoticeAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
FolderLockingNoticeAlertDialog(alertDialogState = this) {
}
}
}
@Composable
private fun getEnterPasswordAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
EnterPasswordAlertDialog(alertDialogState = this, callback = {}, cancelCallback = {})
}
}
@Composable
private fun getCreateNewFolderAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
CreateNewFolderAlertDialog(this, path = Environment.getExternalStorageDirectory().toString()) {
//todo create helper for private fun createFolder(path: String, alertDialog: AlertDialog) to extract bundled logic
}
}
}
@Composable
private fun getWritePermissionAlertDialogState() = rememberAlertDialogState().apply {
DialogMember {
@ -265,8 +322,8 @@ class TestDialogActivity : ComponentActivity() {
}
@Composable
private fun ShowButton(appSideLoadedDialogState: AlertDialogState, text: String) {
Button(onClick = appSideLoadedDialogState::show) {
private fun ShowButton(alertDialogState: AlertDialogState, text: String) {
Button(onClick = alertDialogState::show) {
Text(
text = text,
modifier = Modifier
@ -275,4 +332,18 @@ class TestDialogActivity : ComponentActivity() {
)
}
}
@Composable
private fun ShowButton(appSideLoadedDialogState: BottomSheetDialogState, text: String) {
Button(onClick = appSideLoadedDialogState::open) {
Text(
text = text,
modifier = Modifier
.fillMaxWidth(),
textAlign = TextAlign.Center
)
}
}
}