diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt index e7d60a7..d2731f2 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt @@ -16,136 +16,67 @@ import android.widget.EditText import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.widget.AppCompatButton +import androidx.core.view.ViewCompat import androidx.lifecycle.lifecycleScope import eu.ottop.yamlauncher.databinding.ActivityMainBinding import eu.ottop.yamlauncher.settings.SharedPreferenceManager import eu.ottop.yamlauncher.utils.Animations import kotlinx.coroutines.launch -class AppActionMenu { +class AppActionMenu(private val activity: MainActivity, private val binding: ActivityMainBinding, private val launcherApps: LauncherApps, private val searchView: EditText) { + + private val animations = Animations(activity) + private val sharedPreferenceManager = SharedPreferenceManager(activity) fun setActionListeners( - activity: MainActivity, - binding: ActivityMainBinding, textView: TextView, editLayout: LinearLayout, actionMenu: View, - searchView: EditText, appInfo: ApplicationInfo, userHandle: UserHandle, workProfile: Int, - launcherApps: LauncherApps, appActivity: LauncherActivityInfo? ){ - val animations = Animations(activity) - val sharedPreferenceManager = SharedPreferenceManager(activity) + + + ViewCompat.addAccessibilityAction(textView, "App info") { _, _ -> + appInfo(appActivity, userHandle) + true + } actionMenu.findViewById(R.id.info).setOnClickListener { - - // Launch app info in phone settings - if (appActivity != null) { - launcherApps.startAppDetailsActivity( - appActivity.componentName, - userHandle, - null, - null - ) - } - + appInfo(appActivity, userHandle) animations.fadeViewOut(actionMenu) textView.visibility = View.VISIBLE } + ViewCompat.addAccessibilityAction(textView, "Uninstall app") { _, _ -> + uninstallApp(appInfo, userHandle) + true + } + actionMenu.findViewById(R.id.uninstall).setOnClickListener { - val intent = Intent(Intent.ACTION_DELETE) - intent.data = Uri.parse("package:${appInfo.packageName}") - intent.putExtra(Intent.EXTRA_USER, userHandle) - activity.startActivity(intent) - + uninstallApp(appInfo, userHandle) animations.fadeViewOut(actionMenu) - textView.visibility = View.VISIBLE } + ViewCompat.addAccessibilityAction(textView, "Rename app") { _, _ -> + renameApp(textView, editLayout, actionMenu, appActivity, appInfo, userHandle, workProfile) + true + } + actionMenu.findViewById(R.id.rename).setOnClickListener { - textView.visibility = View.INVISIBLE - animations.fadeViewIn(editLayout) - animations.fadeViewOut(actionMenu) - val editText = editLayout.findViewById(R.id.appNameEdit) - val resetButton = editLayout.findViewById(R.id.reset) + renameApp(textView, editLayout, actionMenu, appActivity, appInfo, userHandle, workProfile) + } - val app = Triple(appActivity!!, userHandle, workProfile) - - searchView.visibility = View.INVISIBLE - editText.requestFocus() - - // Open keyboard - val handler = Handler(Looper.getMainLooper()) - handler.postDelayed({ - val imm = - activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT) - }, 100) - - binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom -> - - // If the keyboard is closed, exit editing mode - if (bottom - top > oldBottom - oldTop) { - editLayout.clearFocus() - - animations.fadeViewOut(editLayout) - textView.visibility = View.VISIBLE - searchView.visibility = View.VISIBLE - } - } - - editText.setOnEditorActionListener { _, actionId, _ -> - - // Once the new name is confirmed, close the keyboard, save the new app name and update the apps on screen - if (actionId == EditorInfo.IME_ACTION_DONE) { - val imm = - activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(editText.windowToken, 0) - sharedPreferenceManager.setAppName( - appInfo.packageName, - workProfile, - editText.text.toString() - ) - activity.lifecycleScope.launch { - activity.applySearch() - } - - - return@setOnEditorActionListener true - } - false - } - - resetButton.setOnClickListener { - - // If reset is pressed, close keyboard, remove saved edited name and update the apps on screen - val imm = - activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(editLayout.windowToken, 0) - sharedPreferenceManager.resetAppName( - app.first.applicationInfo.packageName, - app.third - ) - - activity.lifecycleScope.launch { - activity.applySearch() - } - } + ViewCompat.addAccessibilityAction(textView, "Hide app") { _, _ -> + hideApp(editLayout, textView, actionMenu, appInfo, workProfile) + true } actionMenu.findViewById(R.id.hide).setOnClickListener { - editLayout.visibility = View.GONE - textView.visibility = View.GONE - actionMenu.visibility = View.GONE - activity.lifecycleScope.launch { - sharedPreferenceManager.setAppHidden(appInfo.packageName, workProfile, true) - activity.refreshAppMenu() - } + hideApp(editLayout, textView, actionMenu, appInfo, workProfile) } actionMenu.findViewById(R.id.close).setOnClickListener { @@ -153,4 +84,107 @@ class AppActionMenu { textView.visibility = View.VISIBLE } } + + private fun appInfo( + appActivity: LauncherActivityInfo?, + userHandle: UserHandle + ) { + // Launch app info in phone settings + if (appActivity != null) { + launcherApps.startAppDetailsActivity( + appActivity.componentName, + userHandle, + null, + null + ) + } + } + + private fun uninstallApp(appInfo: ApplicationInfo, userHandle: UserHandle) { + val intent = Intent(Intent.ACTION_DELETE) + intent.data = Uri.parse("package:${appInfo.packageName}") + intent.putExtra(Intent.EXTRA_USER, userHandle) + activity.startActivity(intent) + } + + private fun renameApp(textView: TextView, editLayout: LinearLayout, actionMenu: View, appActivity: LauncherActivityInfo?, appInfo: ApplicationInfo, userHandle: UserHandle, workProfile: Int) { + textView.visibility = View.INVISIBLE + animations.fadeViewIn(editLayout) + animations.fadeViewOut(actionMenu) + val editText = editLayout.findViewById(R.id.appNameEdit) + val resetButton = editLayout.findViewById(R.id.reset) + + val app = Triple(appActivity!!, userHandle, workProfile) + + searchView.visibility = View.INVISIBLE + editText.requestFocus() + + // Open keyboard + val handler = Handler(Looper.getMainLooper()) + handler.postDelayed({ + val imm = + activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT) + }, 100) + + binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom -> + + // If the keyboard is closed, exit editing mode + if (bottom - top > oldBottom - oldTop) { + editLayout.clearFocus() + + animations.fadeViewOut(editLayout) + textView.visibility = View.VISIBLE + searchView.visibility = View.VISIBLE + } + } + + editText.setOnEditorActionListener { _, actionId, _ -> + + // Once the new name is confirmed, close the keyboard, save the new app name and update the apps on screen + if (actionId == EditorInfo.IME_ACTION_DONE) { + val imm = + activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(editText.windowToken, 0) + sharedPreferenceManager.setAppName( + appInfo.packageName, + workProfile, + editText.text.toString() + ) + activity.lifecycleScope.launch { + activity.applySearch() + } + + + return@setOnEditorActionListener true + } + false + } + + resetButton.setOnClickListener { + + // If reset is pressed, close keyboard, remove saved edited name and update the apps on screen + val imm = + activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(editLayout.windowToken, 0) + sharedPreferenceManager.resetAppName( + app.first.applicationInfo.packageName, + app.third + ) + + activity.lifecycleScope.launch { + activity.applySearch() + } + } + } + + private fun hideApp(editLayout: LinearLayout, textView: TextView, actionMenu: View, appInfo: ApplicationInfo, workProfile: Int) { + editLayout.visibility = View.GONE + textView.visibility = View.GONE + actionMenu.visibility = View.GONE + activity.lifecycleScope.launch { + sharedPreferenceManager.setAppHidden(appInfo.packageName, workProfile, true) + activity.refreshAppMenu() + } + } } \ No newline at end of file diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt b/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt index 0eaecec..a8b976d 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt @@ -1,7 +1,6 @@ package eu.ottop.yamlauncher import android.annotation.SuppressLint -import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherApps @@ -17,28 +16,30 @@ import android.widget.TextView import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView import com.google.android.material.textfield.TextInputEditText +import eu.ottop.yamlauncher.databinding.ActivityMainBinding import eu.ottop.yamlauncher.settings.SharedPreferenceManager import eu.ottop.yamlauncher.utils.AppUtils import eu.ottop.yamlauncher.utils.UIUtils class AppMenuAdapter( - - private val context: Context, + private val activity: MainActivity, + binding: ActivityMainBinding, private var apps: MutableList>, private val itemClickListener: OnItemClickListener, private val shortcutListener: OnShortcutListener, private val itemLongClickListener: OnItemLongClickListener, - launcherApps: LauncherApps + private val launcherApps: LauncherApps ) : RecyclerView.Adapter() { // If the menu is opened to select shortcuts, the below variable is set var shortcutTextView: TextView? = null - private val sharedPreferenceManager = SharedPreferenceManager(context) - private val uiUtils = UIUtils(context) - private val appUtils = AppUtils(context, launcherApps) + private val sharedPreferenceManager = SharedPreferenceManager(activity) + private val uiUtils = UIUtils(activity) + private val appUtils = AppUtils(activity, launcherApps) + private var appActionMenu = AppActionMenu(activity, binding, launcherApps, activity.findViewById(R.id.searchView)) interface OnItemClickListener { fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) @@ -64,7 +65,7 @@ class AppMenuAdapter( private val listItem: FrameLayout = itemView.findViewById(R.id.listItem) val textView: TextView = listItem.findViewById(R.id.appName) val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.actionMenu) - private val editView: LinearLayout = listItem.findViewById(R.id.renameView) + val editView: LinearLayout = listItem.findViewById(R.id.renameView) val editText: TextInputEditText = editView.findViewById(R.id.appNameEdit) init { @@ -121,12 +122,12 @@ class AppMenuAdapter( // Set initial drawables if (app.third != 0) { - holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_work_app, null),null, ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null) + holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null, ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null) holder.textView.compoundDrawables[0].colorFilter = BlendModeColorFilter(sharedPreferenceManager.getTextColor(), BlendMode.SRC_ATOP) } else { - holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null,ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null) + holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null) } uiUtils.setAppAlignment(holder.textView, holder.editText) @@ -142,7 +143,7 @@ class AppMenuAdapter( holder.textView.setTextColor(sharedPreferenceManager.getTextColor()) // Set app name on the menu. If the app has been uninstalled, replace it with "Removing" until the app menu updates. - val appLabel: CharSequence = appInfo?.let { context.packageManager.getApplicationLabel(it) } ?: "Removing..." + val appLabel: CharSequence = appInfo?.let { activity.packageManager.getApplicationLabel(it) } ?: "Removing..." if (appInfo != null) { holder.textView.text = sharedPreferenceManager.getAppName( @@ -165,6 +166,21 @@ class AppMenuAdapter( else {holder.textView.text = appLabel} holder.textView.visibility = View.VISIBLE + + if (appInfo != null) { + + val appActivity = launcherApps.getActivityList(appInfo.packageName, app.second).firstOrNull() + + appActionMenu.setActionListeners( + holder.textView, + holder.editView, + holder.actionMenuLayout, + appInfo, + app.second, + app.third, + appActivity + ) + } } override fun getItemCount(): Int { diff --git a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt index b400b39..216485d 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.activity.OnBackPressedCallback import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import androidx.core.content.res.ResourcesCompat +import androidx.core.view.ViewCompat import androidx.core.view.marginLeft import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -64,7 +65,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh private lateinit var uiUtils: UIUtils private lateinit var gestureUtils: GestureUtils - private var appActionMenu = AppActionMenu() private val appMenuLinearLayoutManager = AppMenuLinearLayoutManager(this@MainActivity) private val appMenuEdgeFactory = AppMenuEdgeFactory(this@MainActivity) @@ -317,6 +317,11 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh true } + ViewCompat.addAccessibilityAction(binding.homeView, "Preferences") { _, _ -> + startActivity(Intent(this@MainActivity, SettingsActivity::class.java)) + true + } + // Return to home on back onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { @@ -526,7 +531,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh } private suspend fun setupRecyclerView(newApps: MutableList>) { - adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity, launcherApps) + adapter = AppMenuAdapter(this@MainActivity, binding, newApps, this@MainActivity, this@MainActivity, this@MainActivity, launcherApps) appMenuLinearLayoutManager.stackFromEnd = true recyclerView = findViewById(R.id.recyclerView) withContext(Dispatchers.Main) { @@ -696,22 +701,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh ) { textView.visibility = View.INVISIBLE animations.fadeViewIn(actionMenuLayout) - val appActivity = - launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle) - .firstOrNull() - appActionMenu.setActionListeners( - this@MainActivity, - binding, - textView, - editView, - actionMenuLayout, - searchView, - appInfo.applicationInfo, - userHandle, - userProfile, - launcherApps, - appActivity - ) } open inner class GestureListener : GestureDetector.SimpleOnGestureListener() {