diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFeaturesFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFeaturesFragment.kt index 9b88e6cb..ab59a187 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFeaturesFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFeaturesFragment.kt @@ -2,29 +2,47 @@ package com.github.droidworksstudio.launcher.ui.settings import android.content.Context import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.fragment.findNavController -import com.github.droidworksstudio.launcher.databinding.FragmentSettingsLookFeelBinding +import com.github.droidworksstudio.common.getAppNameFromPackageName +import com.github.droidworksstudio.launcher.R +import com.github.droidworksstudio.launcher.databinding.FragmentSettingsFeaturesBinding import com.github.droidworksstudio.launcher.helper.AppHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.listener.ScrollEventListener +import com.github.droidworksstudio.launcher.repository.AppInfoRepository +import com.github.droidworksstudio.launcher.utils.Constants +import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel +import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import javax.inject.Inject @AndroidEntryPoint class SettingsFeaturesFragment : Fragment(), ScrollEventListener { - private var _binding: FragmentSettingsLookFeelBinding? = null + private var _binding: FragmentSettingsFeaturesBinding? = null private val binding get() = _binding!! + private val preferenceViewModel: PreferenceViewModel by viewModels() + @Inject lateinit var preferenceHelper: PreferenceHelper + @Inject + lateinit var appInfoRepository: AppInfoRepository + @Inject lateinit var appHelper: AppHelper @@ -37,7 +55,7 @@ class SettingsFeaturesFragment : Fragment(), savedInstanceState: Bundle? ): View { // Inflate the layout for this fragment - _binding = FragmentSettingsLookFeelBinding.inflate(inflater, container, false) + _binding = FragmentSettingsFeaturesBinding.inflate(inflater, container, false) _binding = binding return binding.root @@ -54,6 +72,38 @@ class SettingsFeaturesFragment : Fragment(), initializeInjectedDependencies() observeClickListener() + + binding.apply { + miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.getString(context) + } + + val actions = listOf( + Triple(preferenceHelper.doubleTapAction, preferenceHelper.doubleTapApp, binding.gesturesDoubleTapControl), + Triple(preferenceHelper.swipeUpAction, preferenceHelper.swipeUpApp, binding.gesturesSwipeUpControl), + Triple(preferenceHelper.swipeDownAction, preferenceHelper.swipeDownApp, binding.gesturesSwipeDownControl), + Triple(preferenceHelper.swipeLeftAction, preferenceHelper.swipeLeftApp, binding.gesturesSwipeLeftControl), + Triple(preferenceHelper.swipeRightAction, preferenceHelper.swipeRightApp, binding.gesturesSwipeRightControl) + ) + + actions.forEach { (action, app, control) -> + updateGestureControlText(context, action, app, control) + } + } + + // Function to update UI text based on action and app name + private fun updateGestureControlText( + context: Context, + action: Constants.Action, + appPackageName: String?, + textView: TextView + ) { + val actionText = if (action == Constants.Action.OpenApp) { + val appName = appPackageName?.let { context.getAppNameFromPackageName(it) } + context.getString(R.string.settings_actions_open_app_run, appName) + } else { + action.getString(context) + } + textView.text = actionText } override fun onStop() { @@ -63,14 +113,228 @@ class SettingsFeaturesFragment : Fragment(), private fun initializeInjectedDependencies() { binding.nestScrollView.scrollEventListener = this + + // Set initial values and listeners for switches + binding.apply { + automaticKeyboardSwitchCompat.isChecked = preferenceHelper.automaticKeyboard + automaticOpenAppSwitchCompat.isChecked = preferenceHelper.automaticOpenApp + lockSettingsSwitchCompat.isChecked = preferenceHelper.settingsLock + } } private fun observeClickListener() { + setupSwitchListeners() + + binding.apply { + gesturesDoubleTapControl.setOnClickListener { + swipeActionClickEvent(Constants.Swipe.DoubleTap) + } + + gesturesSwipeUpControl.setOnClickListener { + swipeActionClickEvent(Constants.Swipe.Up) + } + + gesturesSwipeDownControl.setOnClickListener { + swipeActionClickEvent(Constants.Swipe.Down) + } + + gesturesSwipeLeftControl.setOnClickListener { + swipeActionClickEvent(Constants.Swipe.Left) + } + + gesturesSwipeRightControl.setOnClickListener { + swipeActionClickEvent(Constants.Swipe.Right) + } + + miscellaneousSearchEngineControl.setOnClickListener { + showSearchEngineDialog() + } + } + } + + private var searchEngineDialog: AlertDialog? = null + + private fun showSearchEngineDialog() { + // Dismiss any existing dialog to prevent multiple dialogs open simultaneously + searchEngineDialog?.dismiss() + // Get the array of SearchEngines enum values + val items = Constants.SearchEngines.entries.toTypedArray() + + // Map the enum values to their string representations + val itemStrings = items.map { it.getString(context) }.toTypedArray() + + val dialogBuilder = MaterialAlertDialogBuilder(context) + + dialogBuilder.setTitle(getString(R.string.settings_select_search_engine)) + dialogBuilder.setItems(itemStrings) { _, which -> + val selectedItem = items[which] + preferenceViewModel.setSearchEngine(selectedItem) + binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name + } + // Assign the created dialog to launcherFontDialog + searchEngineDialog = dialogBuilder.create() + searchEngineDialog?.show() + } + + private var appSelectionDialog: AlertDialog? = null + + private fun showAppSelectionDialog(swipeType: Constants.Swipe) { + // Make sure this method is called within a lifecycle owner scope + lifecycleScope.launch(Dispatchers.Main) { + // Dismiss any existing dialog to prevent multiple dialogs open simultaneously + appSelectionDialog?.dismiss() + + // Collect the flow of installed apps + appInfoRepository.getDrawApps().collect { installedApps -> + // Extract app names and package names + val appNames = installedApps.map { it.appName }.toTypedArray() + val packageNames = installedApps.map { it.packageName } + + // Build and display the dialog + val dialogBuilder = MaterialAlertDialogBuilder(context) + dialogBuilder.setTitle("Select an App") + dialogBuilder.setItems(appNames) { _, which -> + val selectedPackageName = packageNames[which] + when (swipeType) { + Constants.Swipe.DoubleTap, + Constants.Swipe.Up, + Constants.Swipe.Down, + Constants.Swipe.Left, + Constants.Swipe.Right -> handleSwipeAction(swipeType, selectedPackageName) + } + + } + + // Assign the created dialog to launcherFontDialog + appSelectionDialog = dialogBuilder.create() + appSelectionDialog?.show() + } + } + } + + private fun setupSwitchListeners() { binding.apply { + automaticKeyboardSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setAutoKeyboard(isChecked) + } + + automaticOpenAppSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setAutoOpenApp(isChecked) + } + + lockSettingsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setLockSettings(isChecked) + } + } + + } + + private fun swipeActionClickEvent(swipe: Constants.Swipe) { + // Get the array of Action enum values + val actions = Constants.Action.entries.toTypedArray() + // Map the enum values to their string representations + val actionStrings = actions.map { it.getString(context) }.toTypedArray() + + val dialog = MaterialAlertDialogBuilder(context) + + dialog.setTitle("Select a Action") + dialog.setItems(actionStrings) { _, which -> + val selectedAction = actions[which] + when (swipe) { + Constants.Swipe.DoubleTap -> handleSwipeAction(context, Constants.Swipe.DoubleTap, selectedAction, binding) + Constants.Swipe.Up -> handleSwipeAction(context, Constants.Swipe.Up, selectedAction, binding) + Constants.Swipe.Down -> handleSwipeAction(context, Constants.Swipe.Down, selectedAction, binding) + Constants.Swipe.Left -> handleSwipeAction(context, Constants.Swipe.Left, selectedAction, binding) + Constants.Swipe.Right -> handleSwipeAction(context, Constants.Swipe.Right, selectedAction, binding) + } + } + dialog.show() + } + + private fun handleSwipeAction(swipeType: Constants.Swipe, selectedPackageName: String) { + val selectedApp = context.getAppNameFromPackageName(selectedPackageName) + + when (swipeType) { + Constants.Swipe.DoubleTap -> { + binding.gesturesDoubleTapControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + preferenceHelper.doubleTapApp = selectedPackageName + } + + Constants.Swipe.Up -> { + binding.gesturesSwipeUpControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + preferenceHelper.swipeUpApp = selectedPackageName + } + + Constants.Swipe.Down -> { + binding.gesturesSwipeDownControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + preferenceHelper.swipeDownApp = selectedPackageName + } + + Constants.Swipe.Left -> { + binding.gesturesSwipeLeftControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + preferenceHelper.swipeLeftApp = selectedPackageName + } + + Constants.Swipe.Right -> { + binding.gesturesSwipeRightControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + preferenceHelper.swipeRightApp = selectedPackageName + } + } + } + + // Function to handle setting action and updating UI + private fun handleSwipeAction(context: Context, swipe: Constants.Swipe, action: Constants.Action, binding: FragmentSettingsFeaturesBinding) { + preferenceViewModel.setSwipeAction(swipe, action) + + when (action) { + Constants.Action.OpenApp -> { + val selectedApp = when (swipe) { + Constants.Swipe.DoubleTap -> context.getAppNameFromPackageName(preferenceHelper.doubleTapApp) + Constants.Swipe.Up -> context.getAppNameFromPackageName(preferenceHelper.swipeUpApp) + Constants.Swipe.Down -> context.getAppNameFromPackageName(preferenceHelper.swipeDownApp) + Constants.Swipe.Left -> context.getAppNameFromPackageName(preferenceHelper.swipeLeftApp) + Constants.Swipe.Right -> context.getAppNameFromPackageName(preferenceHelper.swipeRightApp) + } + binding.apply { + when (swipe) { + Constants.Swipe.DoubleTap -> gesturesDoubleTapControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + Constants.Swipe.Up -> gesturesSwipeUpControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + Constants.Swipe.Down -> gesturesSwipeDownControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + Constants.Swipe.Left -> gesturesSwipeLeftControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + Constants.Swipe.Right -> gesturesSwipeRightControl.text = getString(R.string.settings_actions_open_app_run, selectedApp) + } + } + showAppSelectionDialog(swipe) + } + + else -> { + Log.d("doubleTapAction", preferenceHelper.doubleTapAction.getString(context)) + binding.apply { + when (swipe) { + Constants.Swipe.DoubleTap -> gesturesDoubleTapControl.text = preferenceHelper.doubleTapAction.getString(context) + Constants.Swipe.Up -> gesturesSwipeUpControl.text = preferenceHelper.swipeUpAction.getString(context) + Constants.Swipe.Down -> gesturesSwipeDownControl.text = preferenceHelper.swipeDownAction.getString(context) + Constants.Swipe.Left -> gesturesSwipeLeftControl.text = preferenceHelper.swipeLeftAction.getString(context) + Constants.Swipe.Right -> gesturesSwipeRightControl.text = preferenceHelper.swipeRightAction.getString(context) + } + } + } + } + } + + // Extension function to set swipe action in ViewModel + private fun PreferenceViewModel.setSwipeAction(swipe: Constants.Swipe, action: Constants.Action) { + when (swipe) { + Constants.Swipe.DoubleTap -> setDoubleTap(action) + Constants.Swipe.Up -> setSwipeUp(action) + Constants.Swipe.Down -> setSwipeDown(action) + Constants.Swipe.Left -> setSwipeLeft(action) + Constants.Swipe.Right -> setSwipeRight(action) } } private fun dismissDialogs() { -// backupRestoreDialog?.dismiss() + searchEngineDialog?.dismiss() + appSelectionDialog?.dismiss() } } \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsLookFeelFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsLookFeelFragment.kt index 29531d4c..e8a281e6 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsLookFeelFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsLookFeelFragment.kt @@ -106,6 +106,8 @@ class SettingsLookFeelFragment : Fragment(), } private fun observeClickListener() { + setupSwitchListeners() + binding.apply { selectAppearanceTextSize.setOnClickListener { val bottomSheetFragment = TextBottomSheetDialogFragment() @@ -138,6 +140,43 @@ class SettingsLookFeelFragment : Fragment(), } } + private fun setupSwitchListeners() { + binding.apply { + statueBarSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowStatusBar(isChecked) + } + + dateSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowDate(isChecked) + } + + timeSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowTime(isChecked) + } + + batterySwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowBattery(isChecked) + } + + dailyWordSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowDailyWord(isChecked) + } + + appIconsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowAppIcons(isChecked) + + // Disable and gray out the other setting if appIconsSwitchCompat is checked + binding.appIconDotsSwitchCompat.isEnabled = isChecked + binding.appIconDotsSwitchCompat.isChecked = false + } + + appIconDotsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowAppIconDots(isChecked) + } + } + + } + private var launcherFontDialog: AlertDialog? = null private fun showLauncherFontDialog() { diff --git a/app/src/main/res/layout/fragment_settings_features.xml b/app/src/main/res/layout/fragment_settings_features.xml index c79be029..f53fc7c8 100644 --- a/app/src/main/res/layout/fragment_settings_features.xml +++ b/app/src/main/res/layout/fragment_settings_features.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.settings.SettingsFragment"> + tools:context=".ui.settings.SettingsFeaturesFragment"> - - + + + + + android:layout_gravity="center_horizontal" + android:layout_marginBottom="24dp" + android:text="@string/features_settings_title" + android:textSize="24sp" + android:textStyle="bold" /> - - + android:text="@string/settings_title_home_behavior_preferences" + android:textColor="@color/icon_200" + android:textSize="@dimen/text_large" /> - - - - - - - - - - - - - + + + + + + + + - - + + + + + + + + - + android:orientation="horizontal" + tools:ignore="MissingConstraints"> + + + + + + - - + android:text="@string/settings_title_gestures" + android:textColor="@color/icon_200" + android:textSize="@dimen/text_large" /> - - - - - - - + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + - - + + + + + + + + + android:layout_marginVertical="10dp" + android:orientation="horizontal" + tools:ignore="MissingConstraints"> + + + + + + @@ -229,34 +335,51 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="20dp" - android:orientation="horizontal" + android:orientation="vertical" tools:ignore="MissingConstraints"> + - - + + + android:layout_marginVertical="10dp" + android:orientation="horizontal" + tools:ignore="MissingConstraints"> + + + + + + - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 82550ddb..482fc2b0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,6 +18,12 @@ Advanced + + Look And Feel + + + Features + Advanced Settings @@ -48,9 +54,6 @@ Share Application Elevate your experience with %1$s! Get it now on fDroid and see what everyone is talking about!\n - - Look And Feel - Home Fragment Draw Fragment