Feature: Adding haptic feedback if enabled in android base settings.

This commit is contained in:
HeCodes2Much
2024-11-25 15:05:39 +00:00
parent f7e050f3f6
commit 507a7139a1
9 changed files with 164 additions and 34 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:dist="http://schemas.android.com/apk/distribution">
xmlns:dist="http://schemas.android.com/apk/distribution"
xmlns:tools="http://schemas.android.com/tools">
<dist:module dist:instant="true" />
@@ -10,15 +10,13 @@
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission
android:name="android.permission.BIND_APPWIDGET"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="${fineLocationPermission}" />
<uses-permission android:name="${coarseLocationPermission}" />
@@ -32,15 +30,15 @@
<application
android:name=".Application"
android:allowBackup="true"
android:clearTaskOnLaunch="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/app_launcher"
android:label="@string/app_name"
android:launchMode="singleTop"
android:supportsRtl="true"
android:theme="@style/Theme.Launcher"
android:enableOnBackInvokedCallback="true"
android:launchMode="singleTop"
android:clearTaskOnLaunch="true"
tools:targetApi="tiramisu">
<activity
android:name=".ui.activities.LauncherActivity"
@@ -59,10 +57,10 @@
android:name=".ui.activities.MainActivity"
android:configChanges="uiMode"
android:excludeFromRecents="true"
android:exported="true"
android:launchMode="singleTask"
android:taskAffinity=""
android:windowSoftInputMode="stateHidden"
android:exported="true">
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -74,8 +72,8 @@
<receiver
android:name=".listener.DeviceAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN"
android:exported="false">
android:exported="false"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
@@ -99,8 +97,8 @@
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:grantUriPermissions="true"
android:exported="false">
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />

View File

@@ -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 -> {

View File

@@ -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 {

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -79,7 +79,6 @@ class HomeFragment : Fragment(),
@Inject
lateinit var appHelper: AppHelper
@Inject
lateinit var fingerHelper: BiometricHelper

View File

@@ -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()

View File

@@ -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)