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

View File

@@ -11,6 +11,9 @@ import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.ImageSpan import android.text.style.ImageSpan
import android.util.Log 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) { fun dayNightMod(context: Context, view: View) {
when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> { Configuration.UI_MODE_NIGHT_YES -> {

View File

@@ -46,7 +46,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() {
return binding.root return binding.root
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -83,6 +83,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() {
} }
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun observeClickListener() { private fun observeClickListener() {
binding.bottomAlignmentDateView.setOnClickListener { binding.bottomAlignmentDateView.setOnClickListener {
selectedAlignment = REQUEST_KEY_DATE_ALIGNMENT selectedAlignment = REQUEST_KEY_DATE_ALIGNMENT
@@ -111,6 +112,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() {
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun showListDialog(selectedAlignment: String) { private fun showListDialog(selectedAlignment: String) {
val items = resources.getStringArray(R.array.alignment_options) val items = resources.getStringArray(R.array.alignment_options)
@@ -166,6 +168,7 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() {
dialog.show() dialog.show()
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun setAlignment( private fun setAlignment(
alignmentType: String, alignmentType: String,
gravity: Int, gravity: Int,
@@ -205,6 +208,8 @@ class AlignmentBottomSheetDialogFragment : BottomSheetDialogFragment() {
alignmentPreference(gravity) alignmentPreference(gravity)
textView.text = appHelper.gravityToString(alignmentGetter()) textView.text = appHelper.gravityToString(alignmentGetter())
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
companion object { companion object {

View File

@@ -12,6 +12,7 @@ import androidx.annotation.RequiresApi
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.github.droidworksstudio.common.showLongToast import com.github.droidworksstudio.common.showLongToast
import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogColorSettingsBinding 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.BottomDialogHelper
import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
@@ -29,6 +30,9 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() {
@Inject @Inject
lateinit var preferenceHelper: PreferenceHelper lateinit var preferenceHelper: PreferenceHelper
@Inject
lateinit var appHelper: AppHelper
@Inject @Inject
lateinit var bottomDialogHelper: BottomDialogHelper lateinit var bottomDialogHelper: BottomDialogHelper
@@ -44,7 +48,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() {
return binding.root return binding.root
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -102,6 +106,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() {
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun observeClickListener() { private fun observeClickListener() {
binding.bottomColorDateView.setOnClickListener { binding.bottomColorDateView.setOnClickListener {
showColorPickerDialog( showColorPickerDialog(
@@ -168,6 +173,7 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() {
} }
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun showColorPickerDialog(view: View, requestCode: String, color: Int) { private fun showColorPickerDialog(view: View, requestCode: String, color: Int) {
ColorChooserDialog.show( ColorChooserDialog.show(
this, requestCode, color, true, tabs = intArrayOf( this, requestCode, color, true, tabs = intArrayOf(
@@ -223,6 +229,9 @@ class ColorBottomSheetDialogFragment : BottomSheetDialogFragment() {
Log.d("Tag", "Settings Widget Text Color: ${Integer.toHexString(color)}") Log.d("Tag", "Settings Widget Text Color: ${Integer.toHexString(color)}")
} }
} }
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
}) { }) {
context?.showLongToast("onCancel") context?.showLongToast("onCancel")
} }

View File

@@ -9,6 +9,7 @@ import android.view.ViewGroup
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogPaddingSettingsBinding 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.BottomDialogHelper
import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
@@ -25,6 +26,9 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() {
@Inject @Inject
lateinit var preferenceHelper: PreferenceHelper lateinit var preferenceHelper: PreferenceHelper
@Inject
lateinit var appHelper: AppHelper
@Inject @Inject
lateinit var bottomDialogHelper: BottomDialogHelper lateinit var bottomDialogHelper: BottomDialogHelper
@@ -38,7 +42,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() {
return binding.root return binding.root
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -56,6 +60,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() {
binding.selectAppPaddingSize.setText("${preferenceHelper.homeAppPadding}") binding.selectAppPaddingSize.setText("${preferenceHelper.homeAppPadding}")
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun observeValueChange() { private fun observeValueChange() {
val appValue = binding.selectAppPaddingSize.text.toString() val appValue = binding.selectAppPaddingSize.text.toString()
@@ -63,6 +68,8 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() {
dismiss() dismiss()
preferenceViewModel.setAppPaddingSize(appFloatValue) preferenceViewModel.setAppPaddingSize(appFloatValue)
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
private fun parseFloatValue(text: String, defaultValue: Float): Float { private fun parseFloatValue(text: String, defaultValue: Float): Float {
@@ -72,6 +79,7 @@ class PaddingBottomSheetDialogFragment : BottomSheetDialogFragment() {
return text.toFloat() return text.toFloat()
} }
@RequiresApi(Build.VERSION_CODES.Q)
override fun onDismiss(dialog: DialogInterface) { override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog) super.onDismiss(dialog)

View File

@@ -9,6 +9,7 @@ import android.view.ViewGroup
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.github.droidworksstudio.launcher.databinding.BottomsheetdialogTextSettingsBinding 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.BottomDialogHelper
import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
@@ -25,6 +26,9 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() {
@Inject @Inject
lateinit var preferenceHelper: PreferenceHelper lateinit var preferenceHelper: PreferenceHelper
@Inject
lateinit var appHelper: AppHelper
@Inject @Inject
lateinit var bottomDialogHelper: BottomDialogHelper lateinit var bottomDialogHelper: BottomDialogHelper
@@ -38,7 +42,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() {
return binding.root return binding.root
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -61,6 +65,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() {
binding.selectDailyWordTextSize.setText("${preferenceHelper.dailyWordTextSize}") binding.selectDailyWordTextSize.setText("${preferenceHelper.dailyWordTextSize}")
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun observeValueChange() { private fun observeValueChange() {
val dateValue = binding.selectDateTextSize.text.toString() val dateValue = binding.selectDateTextSize.text.toString()
val timeValue = binding.selectTimeTextSize.text.toString() val timeValue = binding.selectTimeTextSize.text.toString()
@@ -83,6 +88,9 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() {
preferenceViewModel.setBatteryTextSize(batteryFloatValue) preferenceViewModel.setBatteryTextSize(batteryFloatValue)
preferenceViewModel.setAlarmClockTextSize(alarmFloatValue) preferenceViewModel.setAlarmClockTextSize(alarmFloatValue)
preferenceViewModel.setDailyWordTextSize(wordFloatValue) preferenceViewModel.setDailyWordTextSize(wordFloatValue)
val feedbackType = "save"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
private fun parseFloatValue(text: String, defaultValue: Float): Float { private fun parseFloatValue(text: String, defaultValue: Float): Float {
@@ -92,6 +100,7 @@ class TextBottomSheetDialogFragment : BottomSheetDialogFragment() {
return text.toFloat() return text.toFloat()
} }
@RequiresApi(Build.VERSION_CODES.Q)
override fun onDismiss(dialog: DialogInterface) { override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog) super.onDismiss(dialog)

View File

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

View File

@@ -66,7 +66,7 @@ class SettingsFeaturesFragment : Fragment(),
} }
// Called after the fragment view is created // Called after the fragment view is created
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
navController = findNavController() navController = findNavController()
// Set according to the system theme mode // 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() { private fun observeClickListener() {
setupSwitchListeners() setupSwitchListeners()
@@ -166,6 +166,7 @@ class SettingsFeaturesFragment : Fragment(),
private var searchEngineDialog: AlertDialog? = null private var searchEngineDialog: AlertDialog? = null
@RequiresApi(Build.VERSION_CODES.Q)
private fun showSearchEngineDialog() { private fun showSearchEngineDialog() {
// Dismiss any existing dialog to prevent multiple dialogs open simultaneously // Dismiss any existing dialog to prevent multiple dialogs open simultaneously
searchEngineDialog?.dismiss() searchEngineDialog?.dismiss()
@@ -181,8 +182,11 @@ class SettingsFeaturesFragment : Fragment(),
val selectedItem = items[which] val selectedItem = items[which]
preferenceViewModel.setSearchEngine(selectedItem) preferenceViewModel.setSearchEngine(selectedItem)
binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
} }
// Assign the created dialog to launcherFontDialog // Assign the created dialog to launcherFontDialog
searchEngineDialog = dialogBuilder.create() searchEngineDialog = dialogBuilder.create()
searchEngineDialog?.show() searchEngineDialog?.show()
@@ -190,7 +194,7 @@ class SettingsFeaturesFragment : Fragment(),
private var filterStrengthDialog: AlertDialog? = null private var filterStrengthDialog: AlertDialog? = null
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.Q)
private fun showFilterStrengthDialog() { private fun showFilterStrengthDialog() {
// Dismiss any existing dialog to prevent multiple dialogs open simultaneously // Dismiss any existing dialog to prevent multiple dialogs open simultaneously
filterStrengthDialog?.dismiss() filterStrengthDialog?.dismiss()
@@ -244,9 +248,13 @@ class SettingsFeaturesFragment : Fragment(),
// Save the slider value when OK is pressed // Save the slider value when OK is pressed
preferenceViewModel.setFilterStrength(currentValue) preferenceViewModel.setFilterStrength(currentValue)
binding.miscellaneousFilterStrengthControl.text = "$currentValue" binding.miscellaneousFilterStrengthControl.text = "$currentValue"
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
setNegativeButton("cancel", null) setNegativeButton("cancel", null)
} }
// Assign the created dialog to launcherFontDialog // Assign the created dialog to launcherFontDialog
filterStrengthDialog = dialogBuilder.create() filterStrengthDialog = dialogBuilder.create()
filterStrengthDialog?.show() filterStrengthDialog?.show()
@@ -254,6 +262,7 @@ class SettingsFeaturesFragment : Fragment(),
private var appSelectionDialog: AlertDialog? = null private var appSelectionDialog: AlertDialog? = null
@RequiresApi(Build.VERSION_CODES.Q)
private fun showAppSelectionDialog(swipeType: Constants.Swipe) { private fun showAppSelectionDialog(swipeType: Constants.Swipe) {
// Make sure this method is called within a lifecycle owner scope // Make sure this method is called within a lifecycle owner scope
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
@@ -278,6 +287,8 @@ class SettingsFeaturesFragment : Fragment(),
Constants.Swipe.Left, Constants.Swipe.Left,
Constants.Swipe.Right -> handleSwipeAction(swipeType, selectedPackageName) 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() { private fun setupSwitchListeners() {
binding.apply { binding.apply {
automaticKeyboardSwitchCompat.setOnCheckedChangeListener { _, isChecked -> automaticKeyboardSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setAutoKeyboard(isChecked) preferenceViewModel.setAutoKeyboard(isChecked)
val feedbackType = if (isChecked) "short" else "long"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
automaticOpenAppSwitchCompat.setOnCheckedChangeListener { _, isChecked -> automaticOpenAppSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setAutoOpenApp(isChecked) preferenceViewModel.setAutoOpenApp(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
searchFromStartSwitchCompat.setOnCheckedChangeListener { _, isChecked -> searchFromStartSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setSearchFromStart(isChecked) preferenceViewModel.setSearchFromStart(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
lockSettingsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> lockSettingsSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setLockSettings(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) { 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 // Get the array of Action enum values
val actions = Constants.Action.entries.toTypedArray() val actions = Constants.Action.entries.toTypedArray()
// Map the enum values to their string representations // Map the enum values to their string representations
val actionStrings = actions.map { it.getString(context) }.toTypedArray() val actionStrings = actions.map { it.getString(context) }.toTypedArray()
val dialog = MaterialAlertDialogBuilder(context) val dialogBuilder = MaterialAlertDialogBuilder(context).apply {
setTitle("Select a Action")
dialog.setTitle("Select a Action") setItems(actionStrings) { _, which ->
dialog.setItems(actionStrings) { _, which -> val selectedAction = actions[which]
val selectedAction = actions[which] when (swipe) {
when (swipe) { Constants.Swipe.DoubleTap -> handleSwipeAction(context, Constants.Swipe.DoubleTap, selectedAction, binding)
Constants.Swipe.DoubleTap -> handleSwipeAction(context, Constants.Swipe.DoubleTap, selectedAction, binding) Constants.Swipe.Up -> handleSwipeAction(context, Constants.Swipe.Up, selectedAction, binding)
Constants.Swipe.Up -> handleSwipeAction(context, Constants.Swipe.Up, selectedAction, binding) Constants.Swipe.Down -> handleSwipeAction(context, Constants.Swipe.Down, selectedAction, binding)
Constants.Swipe.Down -> handleSwipeAction(context, Constants.Swipe.Down, selectedAction, binding) Constants.Swipe.Left -> handleSwipeAction(context, Constants.Swipe.Left, selectedAction, binding)
Constants.Swipe.Left -> handleSwipeAction(context, Constants.Swipe.Left, selectedAction, binding) Constants.Swipe.Right -> handleSwipeAction(context, Constants.Swipe.Right, 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) { private fun handleSwipeAction(swipeType: Constants.Swipe, selectedPackageName: String) {
@@ -363,6 +393,7 @@ class SettingsFeaturesFragment : Fragment(),
} }
// Function to handle setting action and updating UI // 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) { private fun handleSwipeAction(context: Context, swipe: Constants.Swipe, action: Constants.Action, binding: FragmentSettingsFeaturesBinding) {
preferenceViewModel.setSwipeAction(swipe, action) preferenceViewModel.setSwipeAction(swipe, action)
@@ -413,6 +444,7 @@ class SettingsFeaturesFragment : Fragment(),
} }
private fun dismissDialogs() { private fun dismissDialogs() {
swipeActionDialog?.dismiss()
searchEngineDialog?.dismiss() searchEngineDialog?.dismiss()
filterStrengthDialog?.dismiss() filterStrengthDialog?.dismiss()
appSelectionDialog?.dismiss() appSelectionDialog?.dismiss()

View File

@@ -2,12 +2,14 @@ package com.github.droidworksstudio.launcher.ui.settings
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
@@ -61,6 +63,7 @@ class SettingsLookFeelFragment : Fragment(),
} }
// Called after the fragment view is created // Called after the fragment view is created
@RequiresApi(Build.VERSION_CODES.Q)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
navController = findNavController() navController = findNavController()
// Set according to the system theme mode // Set according to the system theme mode
@@ -106,6 +109,7 @@ class SettingsLookFeelFragment : Fragment(),
} }
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun observeClickListener() { private fun observeClickListener() {
setupSwitchListeners() setupSwitchListeners()
@@ -141,34 +145,49 @@ class SettingsLookFeelFragment : Fragment(),
} }
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun setupSwitchListeners() { private fun setupSwitchListeners() {
binding.apply { binding.apply {
statueBarSwitchCompat.setOnCheckedChangeListener { _, isChecked -> statueBarSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowStatusBar(isChecked) preferenceViewModel.setShowStatusBar(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
dateSwitchCompat.setOnCheckedChangeListener { _, isChecked -> dateSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowDate(isChecked) preferenceViewModel.setShowDate(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
timeSwitchCompat.setOnCheckedChangeListener { _, isChecked -> timeSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowTime(isChecked) preferenceViewModel.setShowTime(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
batterySwitchCompat.setOnCheckedChangeListener { _, isChecked -> batterySwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowBattery(isChecked) preferenceViewModel.setShowBattery(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
alarmClockSwitchCompat.setOnCheckedChangeListener { _, isChecked -> alarmClockSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowAlarmClock(isChecked) preferenceViewModel.setShowAlarmClock(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
dailyWordSwitchCompat.setOnCheckedChangeListener { _, isChecked -> dailyWordSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowDailyWord(isChecked) preferenceViewModel.setShowDailyWord(isChecked)
val feedbackType = if (isChecked) "on" else "off"
appHelper.triggerHapticFeedback(context, feedbackType)
} }
appIconsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> appIconsSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowAppIcons(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 // Disable and gray out the other setting if appIconsSwitchCompat is checked
binding.appIconDotsSwitchCompat.isEnabled = isChecked binding.appIconDotsSwitchCompat.isEnabled = isChecked
@@ -177,6 +196,8 @@ class SettingsLookFeelFragment : Fragment(),
appIconDotsSwitchCompat.setOnCheckedChangeListener { _, isChecked -> appIconDotsSwitchCompat.setOnCheckedChangeListener { _, isChecked ->
preferenceViewModel.setShowAppIconDots(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 private var launcherFontDialog: AlertDialog? = null
@RequiresApi(Build.VERSION_CODES.Q)
private fun showLauncherFontDialog() { private fun showLauncherFontDialog() {
// Dismiss any existing dialog to prevent multiple dialogs open simultaneously // Dismiss any existing dialog to prevent multiple dialogs open simultaneously
launcherFontDialog?.dismiss() launcherFontDialog?.dismiss()
@@ -201,6 +223,9 @@ class SettingsLookFeelFragment : Fragment(),
preferenceViewModel.setLauncherFont(selectedItem) preferenceViewModel.setLauncherFont(selectedItem)
binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.name binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.name
val feedbackType = "select"
appHelper.triggerHapticFeedback(context, feedbackType)
// Delay the restart slightly to ensure preferences are saved // Delay the restart slightly to ensure preferences are saved
Handler(Looper.getMainLooper()).postDelayed({ Handler(Looper.getMainLooper()).postDelayed({
AppReloader.restartApp(context) AppReloader.restartApp(context)