From 507a7139a1ec8695bbb94a342003811e27eaca78 Mon Sep 17 00:00:00 2001 From: HeCodes2Much Date: Mon, 25 Nov 2024 15:05:39 +0000 Subject: [PATCH] Feature: Adding haptic feedback if enabled in android base settings. --- app/src/main/AndroidManifest.xml | 26 ++++---- .../launcher/helper/AppHelper.kt | 45 ++++++++++++++ .../AlignmentBottomSheetDialogFragment.kt | 7 ++- .../ColorBottomSheetDialogFragment.kt | 11 +++- .../PaddingBottomSheetDialogFragment.kt | 10 ++- .../TextBottomSheetDialogFragment.kt | 11 +++- .../launcher/ui/home/HomeFragment.kt | 1 - .../ui/settings/SettingsFeaturesFragment.kt | 62 ++++++++++++++----- .../ui/settings/SettingsLookFeelFragment.kt | 25 ++++++++ 9 files changed, 164 insertions(+), 34 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index be5a52d..5aca704 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + xmlns:dist="http://schemas.android.com/apk/distribution" + xmlns:tools="http://schemas.android.com/tools"> @@ -10,15 +10,13 @@ + - @@ -32,15 +30,15 @@ + android:windowSoftInputMode="stateHidden"> @@ -74,8 +72,8 @@ + android:exported="false" + android:permission="android.permission.BIND_DEVICE_ADMIN"> @@ -99,8 +97,8 @@ + android:exported="false" + android:grantUriPermissions="true"> diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppHelper.kt b/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppHelper.kt index 661d948..b9b716f 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppHelper.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppHelper.kt @@ -11,6 +11,9 @@ import android.content.res.Configuration import android.content.res.Resources import android.net.Uri import android.os.Build +import android.os.VibrationEffect +import android.os.Vibrator +import android.os.VibratorManager import android.text.SpannableStringBuilder import android.text.style.ImageSpan import android.util.Log @@ -74,6 +77,48 @@ class AppHelper @Inject constructor() { } } + @RequiresApi(Build.VERSION_CODES.Q) + fun triggerHapticFeedback(context: Context?, effectType: String) { + val vibrator: Vibrator? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Use VibratorManager for API 31 and above + val vibratorManager = context?.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + vibratorManager.defaultVibrator + } else { + // Use Vibrator directly for older versions + @Suppress("DEPRECATION") + context?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + } + + if (vibrator != null && vibrator.hasVibrator()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // Define vibration effects based on the effectType + val vibrationEffect = when (effectType.lowercase()) { + "on" -> VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE) // 100ms vibration + "off" -> VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE) // 200ms vibration + "save" -> VibrationEffect.createWaveform(longArrayOf(0, 100, 50, 100), -1) // Two quick vibrations + "select" -> VibrationEffect.createWaveform(longArrayOf(0, 100, 100, 300, 200, 100), -1) // Patterned vibration + "click" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK) // Predefined click effect + else -> VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE) // Default effect + } + vibrator.vibrate(vibrationEffect) + } else { + @Suppress("DEPRECATION") + // For older APIs, approximate effects + when (effectType.lowercase()) { + "on" -> vibrator.vibrate(100) + "off" -> vibrator.vibrate(200) + "save" -> vibrator.vibrate(longArrayOf(0, 100, 50, 100), -1) + "select" -> vibrator.vibrate(longArrayOf(0, 100, 100, 300, 200, 100), -1) + "click" -> vibrator.vibrate(50) // Approximation for click + else -> vibrator.vibrate(50) // Default effect + } + } + } else { + // Handle cases where the device does not support vibration + Log.w("HapticFeedback", "Device does not support vibration") + } + } + fun dayNightMod(context: Context, view: View) { when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { Configuration.UI_MODE_NIGHT_YES -> { diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/AlignmentBottomSheetDialogFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/AlignmentBottomSheetDialogFragment.kt index c8bde0d..4b02c5d 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/AlignmentBottomSheetDialogFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/AlignmentBottomSheetDialogFragment.kt @@ -46,7 +46,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() { return binding.root } - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -83,6 +83,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() { } } + @RequiresApi(Build.VERSION_CODES.Q) private fun observeClickListener() { binding.bottomAlignmentDateView.setOnClickListener { selectedAlignment = REQUEST_KEY_DATE_ALIGNMENT @@ -111,6 +112,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() { } + @RequiresApi(Build.VERSION_CODES.Q) private fun showListDialog(selectedAlignment: String) { val items = resources.getStringArray(R.array.alignment_options) @@ -166,6 +168,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() { dialog.show() } + @RequiresApi(Build.VERSION_CODES.Q) private fun setAlignment( alignmentType: String, gravity: Int, @@ -205,6 +208,8 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() { alignmentPreference(gravity) textView.text = appHelper.gravityToString(alignmentGetter()) + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } companion object { diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/ColorBottomSheetDialogFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/ColorBottomSheetDialogFragment.kt index cc20c14..9f38867 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/ColorBottomSheetDialogFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/ColorBottomSheetDialogFragment.kt @@ -12,6 +12,7 @@ import androidx.annotation.RequiresApi import androidx.fragment.app.viewModels import com.github.droidworksstudio.common.showLongToast import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogColorSettingsBinding +import com.github.droidworksstudio.launcher.helper.AppHelper import com.github.droidworksstudio.launcher.helper.BottomDialogHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel @@ -29,6 +30,9 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() { @Inject lateinit var preferenceHelper: PreferenceHelper + @Inject + lateinit var appHelper: AppHelper + @Inject lateinit var bottomDialogHelper: BottomDialogHelper @@ -44,7 +48,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() { return binding.root } - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -102,6 +106,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() { } + @RequiresApi(Build.VERSION_CODES.Q) private fun observeClickListener() { binding.bottomColorDateView.setOnClickListener { showColorPickerDialog( @@ -168,6 +173,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() { } } + @RequiresApi(Build.VERSION_CODES.Q) private fun showColorPickerDialog(view: View, requestCode: String, color: Int) { ColorChooserDialog.show( this, requestCode, color, true, tabs = intArrayOf( @@ -223,6 +229,9 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() { Log.d("Tag", "Settings Widget Text Color: ${Integer.toHexString(color)}") } } + + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) }) { context?.showLongToast("onCancel") } diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/PaddingBottomSheetDialogFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/PaddingBottomSheetDialogFragment.kt index 4ec6e38..db797ac 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/PaddingBottomSheetDialogFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/PaddingBottomSheetDialogFragment.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import androidx.annotation.RequiresApi import androidx.fragment.app.viewModels import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogPaddingSettingsBinding +import com.github.droidworksstudio.launcher.helper.AppHelper import com.github.droidworksstudio.launcher.helper.BottomDialogHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel @@ -25,6 +26,9 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() { @Inject lateinit var preferenceHelper: PreferenceHelper + @Inject + lateinit var appHelper: AppHelper + @Inject lateinit var bottomDialogHelper: BottomDialogHelper @@ -38,7 +42,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() { return binding.root } - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -56,6 +60,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() { binding.selectAppPaddingSize.setText("${preferenceHelper.homeAppPadding}") } + @RequiresApi(Build.VERSION_CODES.Q) private fun observeValueChange() { val appValue = binding.selectAppPaddingSize.text.toString() @@ -63,6 +68,8 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() { dismiss() preferenceViewModel.setAppPaddingSize(appFloatValue) + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } private fun parseFloatValue(text: String, defaultValue: Float): Float { @@ -72,6 +79,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() { return text.toFloat() } + @RequiresApi(Build.VERSION_CODES.Q) override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/TextBottomSheetDialogFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/TextBottomSheetDialogFragment.kt index 1a14cba..b74ea8d 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/TextBottomSheetDialogFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/bottomsheetdialog/TextBottomSheetDialogFragment.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import androidx.annotation.RequiresApi import androidx.fragment.app.viewModels import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogTextSettingsBinding +import com.github.droidworksstudio.launcher.helper.AppHelper import com.github.droidworksstudio.launcher.helper.BottomDialogHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel @@ -25,6 +26,9 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() { @Inject lateinit var preferenceHelper: PreferenceHelper + @Inject + lateinit var appHelper: AppHelper + @Inject lateinit var bottomDialogHelper: BottomDialogHelper @@ -38,7 +42,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() { return binding.root } - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -61,6 +65,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() { binding.selectDailyWordTextSize.setText("${preferenceHelper.dailyWordTextSize}") } + @RequiresApi(Build.VERSION_CODES.Q) private fun observeValueChange() { val dateValue = binding.selectDateTextSize.text.toString() val timeValue = binding.selectTimeTextSize.text.toString() @@ -83,6 +88,9 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() { preferenceViewModel.setBatteryTextSize(batteryFloatValue) preferenceViewModel.setAlarmClockTextSize(alarmFloatValue) preferenceViewModel.setDailyWordTextSize(wordFloatValue) + + val feedbackType = "save" + appHelper.triggerHapticFeedback(context, feedbackType) } private fun parseFloatValue(text: String, defaultValue: Float): Float { @@ -92,6 +100,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() { return text.toFloat() } + @RequiresApi(Build.VERSION_CODES.Q) override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/home/HomeFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/home/HomeFragment.kt index 993ae14..6b860ea 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/home/HomeFragment.kt @@ -79,7 +79,6 @@ class HomeFragment : Fragment(), @Inject lateinit var appHelper: AppHelper - @Inject lateinit var fingerHelper: BiometricHelper 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 28771d6..93c0a8c 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 @@ -66,7 +66,7 @@ class SettingsFeaturesFragment : Fragment(), } // Called after the fragment view is created - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { navController = findNavController() // Set according to the system theme mode @@ -129,7 +129,7 @@ class SettingsFeaturesFragment : Fragment(), } } - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) private fun observeClickListener() { setupSwitchListeners() @@ -166,6 +166,7 @@ class SettingsFeaturesFragment : Fragment(), private var searchEngineDialog: AlertDialog? = null + @RequiresApi(Build.VERSION_CODES.Q) private fun showSearchEngineDialog() { // Dismiss any existing dialog to prevent multiple dialogs open simultaneously searchEngineDialog?.dismiss() @@ -181,8 +182,11 @@ class SettingsFeaturesFragment : Fragment(), val selectedItem = items[which] preferenceViewModel.setSearchEngine(selectedItem) binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } } + // Assign the created dialog to launcherFontDialog searchEngineDialog = dialogBuilder.create() searchEngineDialog?.show() @@ -190,7 +194,7 @@ class SettingsFeaturesFragment : Fragment(), private var filterStrengthDialog: AlertDialog? = null - @RequiresApi(Build.VERSION_CODES.O) + @RequiresApi(Build.VERSION_CODES.Q) private fun showFilterStrengthDialog() { // Dismiss any existing dialog to prevent multiple dialogs open simultaneously filterStrengthDialog?.dismiss() @@ -244,9 +248,13 @@ class SettingsFeaturesFragment : Fragment(), // Save the slider value when OK is pressed preferenceViewModel.setFilterStrength(currentValue) binding.miscellaneousFilterStrengthControl.text = "$currentValue" + + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } setNegativeButton("cancel", null) } + // Assign the created dialog to launcherFontDialog filterStrengthDialog = dialogBuilder.create() filterStrengthDialog?.show() @@ -254,6 +262,7 @@ class SettingsFeaturesFragment : Fragment(), private var appSelectionDialog: AlertDialog? = null + @RequiresApi(Build.VERSION_CODES.Q) private fun showAppSelectionDialog(swipeType: Constants.Swipe) { // Make sure this method is called within a lifecycle owner scope lifecycleScope.launch(Dispatchers.Main) { @@ -278,6 +287,8 @@ class SettingsFeaturesFragment : Fragment(), Constants.Swipe.Left, Constants.Swipe.Right -> handleSwipeAction(swipeType, selectedPackageName) } + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } } @@ -288,47 +299,66 @@ class SettingsFeaturesFragment : Fragment(), } } + @RequiresApi(Build.VERSION_CODES.Q) private fun setupSwitchListeners() { binding.apply { automaticKeyboardSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setAutoKeyboard(isChecked) + val feedbackType = if (isChecked) "short" else "long" + appHelper.triggerHapticFeedback(context, feedbackType) } automaticOpenAppSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setAutoOpenApp(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } searchFromStartSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setSearchFromStart(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } lockSettingsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setLockSettings(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } } } + private var swipeActionDialog: AlertDialog? = null + + @RequiresApi(Build.VERSION_CODES.Q) private fun swipeActionClickEvent(swipe: Constants.Swipe) { + // Dismiss any existing dialog to prevent multiple dialogs open simultaneously + swipeActionDialog?.dismiss() // 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) + val dialogBuilder = MaterialAlertDialogBuilder(context).apply { + setTitle("Select a Action") + 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) + } + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) } } - dialog.show() + + // Assign the created dialog to launcherFontDialog + swipeActionDialog = dialogBuilder.create() + swipeActionDialog?.show() } private fun handleSwipeAction(swipeType: Constants.Swipe, selectedPackageName: String) { @@ -363,6 +393,7 @@ class SettingsFeaturesFragment : Fragment(), } // Function to handle setting action and updating UI + @RequiresApi(Build.VERSION_CODES.Q) private fun handleSwipeAction(context: Context, swipe: Constants.Swipe, action: Constants.Action, binding: FragmentSettingsFeaturesBinding) { preferenceViewModel.setSwipeAction(swipe, action) @@ -413,6 +444,7 @@ class SettingsFeaturesFragment : Fragment(), } private fun dismissDialogs() { + swipeActionDialog?.dismiss() searchEngineDialog?.dismiss() filterStrengthDialog?.dismiss() appSelectionDialog?.dismiss() 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 8af8fde..6c4a110 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 @@ -2,12 +2,14 @@ package com.github.droidworksstudio.launcher.ui.settings import android.content.Context import android.content.Intent +import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.RequiresApi import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -61,6 +63,7 @@ class SettingsLookFeelFragment : Fragment(), } // Called after the fragment view is created + @RequiresApi(Build.VERSION_CODES.Q) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { navController = findNavController() // Set according to the system theme mode @@ -106,6 +109,7 @@ class SettingsLookFeelFragment : Fragment(), } } + @RequiresApi(Build.VERSION_CODES.Q) private fun observeClickListener() { setupSwitchListeners() @@ -141,34 +145,49 @@ class SettingsLookFeelFragment : Fragment(), } } + @RequiresApi(Build.VERSION_CODES.Q) private fun setupSwitchListeners() { binding.apply { statueBarSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowStatusBar(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } dateSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowDate(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } timeSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowTime(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } batterySwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowBattery(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } alarmClockSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowAlarmClock(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } dailyWordSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowDailyWord(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } appIconsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowAppIcons(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) // Disable and gray out the other setting if appIconsSwitchCompat is checked binding.appIconDotsSwitchCompat.isEnabled = isChecked @@ -177,6 +196,8 @@ class SettingsLookFeelFragment : Fragment(), appIconDotsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> preferenceViewModel.setShowAppIconDots(isChecked) + val feedbackType = if (isChecked) "on" else "off" + appHelper.triggerHapticFeedback(context, feedbackType) } } @@ -184,6 +205,7 @@ class SettingsLookFeelFragment : Fragment(), private var launcherFontDialog: AlertDialog? = null + @RequiresApi(Build.VERSION_CODES.Q) private fun showLauncherFontDialog() { // Dismiss any existing dialog to prevent multiple dialogs open simultaneously launcherFontDialog?.dismiss() @@ -201,6 +223,9 @@ class SettingsLookFeelFragment : Fragment(), preferenceViewModel.setLauncherFont(selectedItem) binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.name + val feedbackType = "select" + appHelper.triggerHapticFeedback(context, feedbackType) + // Delay the restart slightly to ensure preferences are saved Handler(Looper.getMainLooper()).postDelayed({ AppReloader.restartApp(context)