diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/compose/components/SimpleDropDownMenuItem.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/compose/components/SimpleDropDownMenuItem.kt index abe9cc68b..c8617da63 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/compose/components/SimpleDropDownMenuItem.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/compose/components/SimpleDropDownMenuItem.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.unit.dp 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 private val dropDownPaddings = Modifier.padding(horizontal = 14.dp, vertical = 16.dp) @@ -37,16 +38,20 @@ fun SimpleDropDownMenuItem( indication: Indication? = LocalIndication.current, onClick: () -> Unit ) = - Box(modifier = modifier - .fillMaxWidth() - .clickable(interactionSource = interactionSource, indication = indication, onClick = onClick) - .then(dropDownPaddings)) { - Text( - text = text, - modifier = Modifier - .fillMaxWidth() - ) - } + SimpleDropDownMenuItem( + modifier = modifier, + interactionSource = interactionSource, + indication = indication, + onClick = onClick, + text = { + Text( + text = text, + modifier = Modifier + .fillMaxWidth(), + color = SimpleTheme.colorScheme.onSurface + ) + } + ) @Composable fun SimpleDropDownMenuItem( diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/compose/menus/ActionMenu.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/compose/menus/ActionMenu.kt index 1ea6780e4..a5ffae54a 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/compose/menus/ActionMenu.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/compose/menus/ActionMenu.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.commons.compose.menus import androidx.annotation.StringRes +import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* @@ -30,6 +31,8 @@ import com.simplemobiletools.commons.compose.extensions.rememberMutableInteracti import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.Shapes import com.simplemobiletools.commons.compose.theme.SimpleTheme +import com.simplemobiletools.commons.dialogs.dialogBorder +import com.simplemobiletools.commons.dialogs.dialogContainerColor import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -140,6 +143,9 @@ fun ActionMenu( } } DropdownMenu( + modifier = Modifier + .background(dialogContainerColor) + .dialogBorder, expanded = isMenuVisible, onDismissRequest = { onMenuToggle(false) }, ) { diff --git a/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/MainActivity.kt b/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/MainActivity.kt index 976e8cae2..a2e8de071 100644 --- a/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/MainActivity.kt +++ b/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/MainActivity.kt @@ -2,58 +2,103 @@ package com.simplemobiletools.commons.samples.activities import android.content.Intent import android.os.Bundle -import com.simplemobiletools.commons.activities.BaseSimpleActivity +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import com.simplemobiletools.commons.activities.AboutActivity +import com.simplemobiletools.commons.activities.CustomizationActivity 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 -import com.simplemobiletools.commons.helpers.LICENSE_AUTOFITTEXTVIEW +import com.simplemobiletools.commons.compose.alert_dialog.AlertDialogState +import com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState +import com.simplemobiletools.commons.compose.extensions.* +import com.simplemobiletools.commons.compose.theme.AppThemeSurface +import com.simplemobiletools.commons.dialogs.ConfirmationDialog +import com.simplemobiletools.commons.dialogs.DonateAlertDialog +import com.simplemobiletools.commons.dialogs.RateStarsAlertDialog +import com.simplemobiletools.commons.extensions.hideKeyboard +import com.simplemobiletools.commons.extensions.launchMoreAppsFromUsIntent +import com.simplemobiletools.commons.extensions.launchViewIntent +import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.FAQItem -import com.simplemobiletools.commons.models.SimpleListItem import com.simplemobiletools.commons.samples.BuildConfig import com.simplemobiletools.commons.samples.R -import com.simplemobiletools.commons.samples.databinding.ActivityMainBinding - -class MainActivity : BaseSimpleActivity() { - override fun getAppLauncherName() = getString(R.string.smtco_app_name) - - override fun getAppIconIDs(): ArrayList { - val ids = ArrayList() - ids.add(R.mipmap.commons_launcher) - return ids - } - - private val binding by viewBinding(ActivityMainBinding::inflate) +import com.simplemobiletools.commons.samples.screens.MainScreen +class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(binding.root) - appLaunched(BuildConfig.APPLICATION_ID) - updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(binding.mainNestedScrollview, binding.mainToolbar) - - binding.mainColorCustomization.setOnClickListener { - startCustomizationActivity() - } - binding.bottomSheetChooser.setOnClickListener { - launchAbout() - } - binding.manageBlockedNumbers.setOnClickListener { - startActivity(Intent(this, ManageBlockedNumbersActivity::class.java)) - } - binding.composeDialogs.setOnClickListener { - startActivity(Intent(this, TestDialogActivity::class.java)) - } - binding.testButton.setOnClickListener { - WritePermissionDialog(this, writePermissionDialogMode = WritePermissionDialog.WritePermissionDialogMode.OpenDocumentTreeSDK30(".")){ + enableEdgeToEdgeSimple() + setContent { + AppThemeSurface { + val showMoreApps = onEventValue { !resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations) } + MainScreen( + openColorCustomization = ::startCustomizationActivity, + manageBlockedNumbers = { + startActivity(Intent(this@MainActivity, ManageBlockedNumbersActivity::class.java)) + }, + showComposeDialogs = { + startActivity(Intent(this@MainActivity, TestDialogActivity::class.java)) + }, + openTestButton = { + ConfirmationDialog( + this@MainActivity, + FAKE_VERSION_APP_LABEL, + positive = com.simplemobiletools.commons.R.string.ok, + negative = 0 + ) { + launchViewIntent(DEVELOPER_PLAY_STORE_URL) + } + }, + showMoreApps = showMoreApps, + openAbout = ::launchAbout, + moreAppsFromUs = ::launchMoreAppsFromUsIntent + ) + AppLaunched() } } } + @Composable + private fun AppLaunched( + donateAlertDialogState: AlertDialogState = getDonateAlertDialogState(), + rateStarsAlertDialogState: AlertDialogState = getRateStarsAlertDialogState(), + ) { + LaunchedEffect(Unit) { + appLaunchedCompose( + appId = BuildConfig.APPLICATION_ID, + showDonateDialog = donateAlertDialogState::show, + showRateUsDialog = rateStarsAlertDialogState::show, + showUpgradeDialog = {} + ) + } + } + + @Composable + private fun getDonateAlertDialogState() = + rememberAlertDialogState().apply { + DialogMember { + DonateAlertDialog(alertDialogState = this) + } + } + + @Composable + private fun getRateStarsAlertDialogState() = rememberAlertDialogState().apply { + DialogMember { + RateStarsAlertDialog(alertDialogState = this, onRating = ::rateStarsRedirectAndThankYou) + } + } + + private fun startCustomizationActivity() { + Intent(applicationContext, CustomizationActivity::class.java).apply { + putExtra(APP_ICON_IDS, getAppIconIDs()) + putExtra(APP_LAUNCHER_NAME, getAppLauncherName()) + startActivity(this) + } + } + private fun launchAbout() { val licenses = LICENSE_AUTOFITTEXTVIEW @@ -71,27 +116,29 @@ class MainActivity : BaseSimpleActivity() { startAboutActivity(R.string.smtco_app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true) } - private fun launchBottomSheetDemo() { - BottomSheetChooserDialog.createChooser( - fragmentManager = supportFragmentManager, - title = com.simplemobiletools.commons.R.string.please_select_destination, - items = arrayOf( - SimpleListItem(1, com.simplemobiletools.commons.R.string.record_video, com.simplemobiletools.commons.R.drawable.ic_camera_vector), - SimpleListItem( - 2, - com.simplemobiletools.commons.R.string.record_audio, - com.simplemobiletools.commons.R.drawable.ic_microphone_vector, - selected = true - ), - SimpleListItem(4, com.simplemobiletools.commons.R.string.choose_contact, com.simplemobiletools.commons.R.drawable.ic_add_person_vector) - ) - ) { - toast("Clicked ${it.id}") + private fun startAboutActivity( + appNameId: Int, licenseMask: Long, versionName: String, faqItems: ArrayList, showFAQBeforeMail: Boolean, + getAppIconIDs: ArrayList = getAppIconIDs(), + getAppLauncherName: String = getAppLauncherName() + ) { + hideKeyboard() + Intent(applicationContext, AboutActivity::class.java).apply { + putExtra(APP_ICON_IDS, getAppIconIDs) + putExtra(APP_LAUNCHER_NAME, getAppLauncherName) + putExtra(APP_NAME, getString(appNameId)) + putExtra(APP_LICENSES, licenseMask) + putExtra(APP_VERSION_NAME, versionName) + putExtra(APP_FAQ, faqItems) + putExtra(SHOW_FAQ_BEFORE_MAIL, showFAQBeforeMail) + startActivity(this) } } - override fun onResume() { - super.onResume() - setupToolbar(binding.mainToolbar) + private fun getAppLauncherName() = getString(R.string.smtco_app_name) + + private fun getAppIconIDs(): ArrayList { + val ids = ArrayList() + ids.add(R.mipmap.commons_launcher) + return ids } } diff --git a/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/StringsAdapter.kt b/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/StringsAdapter.kt deleted file mode 100644 index 3a2d040ad..000000000 --- a/samples/src/main/kotlin/com/simplemobiletools/commons/samples/activities/StringsAdapter.kt +++ /dev/null @@ -1,129 +0,0 @@ -package com.simplemobiletools.commons.samples.activities - -import android.annotation.SuppressLint -import android.view.* -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.RecyclerView -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import com.simplemobiletools.commons.activities.BaseSimpleActivity -import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter -import com.simplemobiletools.commons.extensions.beVisibleIf -import com.simplemobiletools.commons.interfaces.ItemMoveCallback -import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract -import com.simplemobiletools.commons.interfaces.StartReorderDragListener -import com.simplemobiletools.commons.samples.databinding.ListItemBinding -import com.simplemobiletools.commons.views.MyRecyclerView -import java.util.* - -class StringsAdapter( - activity: BaseSimpleActivity, var strings: MutableList, recyclerView: MyRecyclerView, val swipeRefreshLayout: SwipeRefreshLayout, - itemClick: (Any) -> Unit -) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract { - - private var isChangingOrder = false - private var startReorderDragListener: StartReorderDragListener - - init { - setupDragListener(true) - - val touchHelper = ItemTouchHelper(ItemMoveCallback(this, true)) - touchHelper.attachToRecyclerView(recyclerView) - - startReorderDragListener = object : StartReorderDragListener { - override fun requestDrag(viewHolder: RecyclerView.ViewHolder) { - touchHelper.startDrag(viewHolder) - } - } - } - - override fun getActionMenuId() = com.simplemobiletools.commons.R.menu.cab_delete_only - - override fun prepareActionMode(menu: Menu) {} - - override fun actionItemPressed(id: Int) { - if (selectedKeys.isEmpty()) { - return - } - - when (id) { - com.simplemobiletools.commons.R.id.cab_delete -> changeOrder() - } - } - - override fun getSelectableItemCount() = strings.size - - override fun getIsItemSelectable(position: Int) = true - - override fun getItemSelectionKey(position: Int) = strings.getOrNull(position)?.hashCode() - - override fun getItemKeyPosition(key: Int) = strings.indexOfFirst { it.hashCode() == key } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false).run { ViewHolder(root) } - - override fun onActionModeCreated() {} - - override fun onActionModeDestroyed() { - if (isChangingOrder) { - notifyDataSetChanged() - } - - isChangingOrder = false - } - - override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) { - val item = strings[position] - holder.bindView(item, true, true) { itemView, layoutPosition -> - setupView(ListItemBinding.bind(itemView), item, holder) - } - bindViewHolder(holder) - } - - override fun getItemCount() = strings.size - - private fun changeOrder() { - isChangingOrder = true - notifyDataSetChanged() - } - - @SuppressLint("ClickableViewAccessibility") - private fun setupView(view: ListItemBinding, string: String, holder: ViewHolder) { - val isSelected = selectedKeys.contains(string.hashCode()) - view.apply { - itemFrame.isSelected = isSelected - itemName.text = string - - dragHandle.beVisibleIf(isChangingOrder) - - if (isChangingOrder) { - dragHandle.setOnTouchListener { v, event -> - if (event.action == MotionEvent.ACTION_DOWN) { - startReorderDragListener.requestDrag(holder) - } - false - } - } - } - } - - override fun onRowMoved(fromPosition: Int, toPosition: Int) { - if (fromPosition < toPosition) { - for (i in fromPosition until toPosition) { - Collections.swap(strings, i, i + 1) - } - } else { - for (i in fromPosition downTo toPosition + 1) { - Collections.swap(strings, i, i - 1) - } - } - - notifyItemMoved(fromPosition, toPosition) - } - - override fun onRowSelected(myViewHolder: ViewHolder?) { - swipeRefreshLayout.isEnabled = false - } - - override fun onRowClear(myViewHolder: ViewHolder?) { - swipeRefreshLayout.isEnabled = true - } -} diff --git a/samples/src/main/kotlin/com/simplemobiletools/commons/samples/screens/MainScreen.kt b/samples/src/main/kotlin/com/simplemobiletools/commons/samples/screens/MainScreen.kt new file mode 100644 index 000000000..04576fa30 --- /dev/null +++ b/samples/src/main/kotlin/com/simplemobiletools/commons/samples/screens/MainScreen.kt @@ -0,0 +1,139 @@ +package com.simplemobiletools.commons.samples.screens + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.compose.extensions.MyDevices +import com.simplemobiletools.commons.compose.lists.SimpleScaffold +import com.simplemobiletools.commons.compose.lists.simpleTopAppBarColors +import com.simplemobiletools.commons.compose.lists.topAppBarInsets +import com.simplemobiletools.commons.compose.lists.topAppBarPaddings +import com.simplemobiletools.commons.compose.menus.ActionItem +import com.simplemobiletools.commons.compose.menus.ActionMenu +import com.simplemobiletools.commons.compose.menus.OverflowMode +import com.simplemobiletools.commons.compose.theme.AppThemeSurface +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +@Composable +fun MainScreen( + openColorCustomization: () -> Unit, + manageBlockedNumbers: () -> Unit, + showComposeDialogs: () -> Unit, + openTestButton: () -> Unit, + showMoreApps: Boolean, + openAbout: () -> Unit, + moreAppsFromUs: () -> Unit, +) { + SimpleScaffold( + customTopBar = { scrolledColor: Color, _: MutableInteractionSource, scrollBehavior: TopAppBarScrollBehavior, statusBarColor: Int, colorTransitionFraction: Float, contrastColor: Color -> + TopAppBar( + title = {}, + actions = { + val actionMenus = remember { + buildActionMenuItems( + showMoreApps = showMoreApps, + openAbout = openAbout, + moreAppsFromUs = moreAppsFromUs + ) + } + var isMenuVisible by remember { mutableStateOf(false) } + ActionMenu( + items = actionMenus, + numIcons = 2, + isMenuVisible = isMenuVisible, + onMenuToggle = { isMenuVisible = it }, + iconsColor = scrolledColor + ) + }, + scrollBehavior = scrollBehavior, + colors = simpleTopAppBarColors(statusBarColor, colorTransitionFraction, contrastColor), + modifier = Modifier.topAppBarPaddings(), + windowInsets = topAppBarInsets() + ) + } + ) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Button( + onClick = openColorCustomization + ) { + Text(stringResource(id = R.string.color_customization)) + } + Button( + onClick = openAbout + ) { + Text("About") + } + Button( + onClick = manageBlockedNumbers + ) { + Text("Manage blocked numbers") + } + Button( + onClick = showComposeDialogs + ) { + Text("Compose dialogs") + } + Button( + onClick = openTestButton + ) { + Text("Test button") + } + } + } +} + +private fun buildActionMenuItems( + showMoreApps: Boolean, + openAbout: () -> Unit, + moreAppsFromUs: () -> Unit +): ImmutableList { + val list = mutableListOf() + list += ActionItem( + R.string.about, + icon = Icons.Outlined.Info, + doAction = openAbout, + overflowMode = OverflowMode.NEVER_OVERFLOW + ) + if (showMoreApps) { + list += ActionItem( + R.string.more_apps_from_us, + doAction = moreAppsFromUs, + overflowMode = OverflowMode.ALWAYS_OVERFLOW + ) + } + return list.toImmutableList() +} + +@Composable +@MyDevices +private fun MainScreenPreview() { + AppThemeSurface { + MainScreen( + openColorCustomization = {}, + manageBlockedNumbers = {}, + showComposeDialogs = {}, + openTestButton = {}, + showMoreApps = true, + openAbout = {}, + moreAppsFromUs = {} + ) + } +}