From e2cf32eec6d30b8af24271df02e9c711a42db3d2 Mon Sep 17 00:00:00 2001 From: ottoptj Date: Thu, 1 Aug 2024 00:15:13 +0300 Subject: [PATCH] Unhiding apps works now --- .../eu/ottop/yamlauncher/AppMenuAdapter.kt | 2 +- .../eu/ottop/yamlauncher/HiddenAppsAdapter.kt | 57 +----- .../ottop/yamlauncher/HiddenAppsFragment.kt | 126 ++++++++++--- .../ottop/yamlauncher/LocationListAdapter.kt | 171 ++++++++++++++++++ 4 files changed, 276 insertions(+), 80 deletions(-) create mode 100644 app/src/main/java/eu/ottop/yamlauncher/LocationListAdapter.kt diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt b/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt index d49cc59..f699424 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt @@ -24,7 +24,7 @@ import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView class AppMenuAdapter( - private val activity: MainActivity, + private val activity: Context, var apps: MutableList>>, private val itemClickListener: OnItemClickListener, private val shortcutListener: OnShortcutListener, diff --git a/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsAdapter.kt b/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsAdapter.kt index 9c74d09..0f767ca 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsAdapter.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsAdapter.kt @@ -14,43 +14,22 @@ import android.widget.FrameLayout import android.widget.LinearLayout import android.widget.TextView import androidx.core.content.res.ResourcesCompat -import androidx.fragment.app.FragmentActivity import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView +import kotlin.time.Duration.Companion.seconds class HiddenAppsAdapter( private val activity: Context, var apps: MutableList>>, - private val itemClickListener: OnItemClickListener, - private val shortcutListener: OnShortcutListener, - private val itemLongClickListener: OnItemLongClickListener + private val itemClickListener: OnItemClickListener ) : RecyclerView.Adapter() { - var menuMode: String = "app" - var shortcutTextView: TextView? = null - private val sharedPreferenceManager = SharedPreferenceManager() private var preferences = PreferenceManager.getDefaultSharedPreferences(activity) interface OnItemClickListener { - fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) - } - - interface OnShortcutListener { - fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView) - } - - interface OnItemLongClickListener { - fun onItemLongClick( - appInfo: LauncherActivityInfo, - userHandle: UserHandle, - userProfile: Int, - textView: TextView, - actionMenuLayout: LinearLayout, - editView: LinearLayout, - position: Int - ) + fun onItemClick(appInfo: LauncherActivityInfo, profile: Int) } inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { @@ -65,33 +44,9 @@ class HiddenAppsAdapter( editView.visibility = View.INVISIBLE textView.setOnClickListener { - val position = bindingAdapterPosition - val app = apps[position].first - if (menuMode == "shortcut") { - shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!) - } - else if (menuMode == "app") { - itemClickListener.onItemClick(app, apps[position].second.first) - } - } - - if (menuMode == "app") { - textView.setOnLongClickListener { - val position = bindingAdapterPosition - - val app = apps[position].first - itemLongClickListener.onItemLongClick( - app, - apps[position].second.first, - apps[position].second.second, - textView, - actionMenuLayout, - editView, - position - ) - return@setOnLongClickListener true - } - + val position = bindingAdapterPosition + val app = apps[position].first + itemClickListener.onItemClick(app, apps[position].second.second) } } diff --git a/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsFragment.kt b/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsFragment.kt index 130b397..94a186d 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsFragment.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/HiddenAppsFragment.kt @@ -1,18 +1,18 @@ package eu.ottop.yamlauncher import android.app.Activity +import android.app.AlertDialog import android.content.pm.LauncherActivityInfo import android.os.Bundle import android.os.UserHandle +import android.text.Editable +import android.text.TextWatcher import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.LinearLayout -import android.widget.TextView +import android.widget.EditText import androidx.recyclerview.widget.RecyclerView -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER @@ -24,11 +24,13 @@ private const val ARG_PARAM2 = "param2" * Use the [HiddenAppsFragment.newInstance] factory method to * create an instance of this fragment. */ -class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, HiddenAppsAdapter.OnShortcutListener, HiddenAppsAdapter.OnItemLongClickListener { +class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener { // TODO: Rename and change types of parameters private var param1: String? = null private var param2: String? = null private val appUtils = AppUtils() + private val sharedPreferenceManager = SharedPreferenceManager() + private var adapter: HiddenAppsAdapter? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -50,13 +52,100 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val adapter = HiddenAppsAdapter(requireContext(), appUtils.getHiddenApps(activity as Activity).toMutableList(), this, this, this) + adapter = HiddenAppsAdapter(requireContext(), appUtils.getHiddenApps(activity as Activity).toMutableList(), this) val recyclerView = view.findViewById(R.id.hidden_app_recycler) val appMenuEdgeFactory = AppMenuEdgeFactory(requireActivity()) recyclerView.edgeEffectFactory = appMenuEdgeFactory recyclerView.adapter = adapter + recyclerView.scrollToPosition(0) + + val searchView = view.findViewById(R.id.hiddenAppSearch) + + recyclerView.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom -> + + if (bottom - top > oldBottom - oldTop) { + searchView.clearFocus() + } + } + + searchView.addTextChangedListener(object : + TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + + filterItems(searchView.text.toString()) + + } + }) + } + + private fun filterItems(query: String?) { + + val cleanQuery = query?.clean() + val newFilteredApps = mutableListOf>>() + val updatedApps = appUtils.getHiddenApps(requireActivity()) + + getFilteredApps(cleanQuery, newFilteredApps, updatedApps) + + applySearch(newFilteredApps) + + } + + private fun getFilteredApps(cleanQuery: String?, newFilteredApps: MutableList>>, updatedApps: List>>) { + if (cleanQuery.isNullOrEmpty()) { + newFilteredApps.addAll(updatedApps) + } else { + updatedApps.forEach { + val cleanItemText = sharedPreferenceManager.getAppName(requireActivity(), it.first.applicationInfo.packageName, it.second.second, requireActivity().packageManager.getApplicationLabel(it.first.applicationInfo)).toString().clean() + if (cleanItemText.contains(cleanQuery, ignoreCase = true)) { + newFilteredApps.add(it) + } + } + } + } + + private fun applySearch(newFilteredApps: MutableList>>) { + adapter?.updateApps(newFilteredApps) + } + + private fun String.clean(): String { + return this.replace("[^a-zA-Z0-9]".toRegex(), "") + } + + private fun showConfirmationDialog(appInfo: LauncherActivityInfo, appName: String, profile: Int) { + AlertDialog.Builder(requireContext()).apply { + setTitle("Confirmation") + setMessage("Are you sure you want to unhide $appName?") + setPositiveButton("Yes") { _, _ -> + // Perform action on confirmation + performConfirmedAction(appInfo, appName, profile) + } + setNegativeButton("Cancel") { _, _ -> + // Handle cancellation + handleCancellation() + } + setOnCancelListener { + // Handle dialog cancel + handleCancellation() + } + }.create().show() + } + + private fun performConfirmedAction(appInfo: LauncherActivityInfo, appName: String, profile: Int) { + sharedPreferenceManager.setAppVisible(requireContext(), appInfo.applicationInfo.packageName, profile) + adapter?.updateApps(appUtils.getHiddenApps(requireActivity())) + } + + private fun handleCancellation() { + // Handle the cancellation of the dialog } companion object { @@ -79,29 +168,10 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi } } - override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) { - TODO("Not yet implemented") + override fun onItemClick(appInfo: LauncherActivityInfo, profile: Int) { + showConfirmationDialog(appInfo, sharedPreferenceManager.getAppName(requireContext(), appInfo.applicationInfo.packageName,profile, requireContext().packageManager.getApplicationLabel(appInfo.applicationInfo)).toString(), profile) } - override fun onShortcut( - appInfo: LauncherActivityInfo, - userHandle: UserHandle, - textView: TextView, - userProfile: Int, - shortcutView: TextView - ) { - TODO("Not yet implemented") - } - override fun onItemLongClick( - appInfo: LauncherActivityInfo, - userHandle: UserHandle, - userProfile: Int, - textView: TextView, - actionMenuLayout: LinearLayout, - editView: LinearLayout, - position: Int - ) { - TODO("Not yet implemented") - } + } \ No newline at end of file diff --git a/app/src/main/java/eu/ottop/yamlauncher/LocationListAdapter.kt b/app/src/main/java/eu/ottop/yamlauncher/LocationListAdapter.kt new file mode 100644 index 0000000..880bf71 --- /dev/null +++ b/app/src/main/java/eu/ottop/yamlauncher/LocationListAdapter.kt @@ -0,0 +1,171 @@ +package eu.ottop.yamlauncher + +import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.ApplicationInfo +import android.content.pm.LauncherActivityInfo +import android.os.UserHandle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.EditText +import android.widget.FrameLayout +import android.widget.LinearLayout +import android.widget.TextView +import androidx.core.content.res.ResourcesCompat +import androidx.preference.PreferenceManager +import androidx.recyclerview.widget.RecyclerView + +class LocationListAdapter( + private val activity: Context, + var apps: MutableList>>, + private val itemClickListener: OnItemClickListener, + private val shortcutListener: OnShortcutListener, + private val itemLongClickListener: OnItemLongClickListener +) : + RecyclerView.Adapter() { + + var menuMode: String = "app" + var shortcutTextView: TextView? = null + + private val sharedPreferenceManager = SharedPreferenceManager() + private var preferences = PreferenceManager.getDefaultSharedPreferences(activity) + + interface OnItemClickListener { + fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) + } + + interface OnShortcutListener { + fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView) + } + + interface OnItemLongClickListener { + fun onItemLongClick( + appInfo: LauncherActivityInfo, + userHandle: UserHandle, + userProfile: Int, + textView: TextView, + actionMenuLayout: LinearLayout, + editView: LinearLayout, + position: Int + ) + } + + inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val listItem: FrameLayout = itemView.findViewById(R.id.list_item) + val textView: TextView = listItem.findViewById(R.id.app_name) + val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.action_menu) + private val editView: LinearLayout = listItem.findViewById(R.id.rename_view) + val editText: EditText = editView.findViewById(R.id.app_name_edit) + + init { + actionMenuLayout.visibility = View.INVISIBLE + editView.visibility = View.INVISIBLE + + textView.setOnClickListener { + val position = bindingAdapterPosition + val app = apps[position].first + if (menuMode == "shortcut") { + shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!) + } + else if (menuMode == "app") { + itemClickListener.onItemClick(app, apps[position].second.first) + } + } + + if (menuMode == "app") { + textView.setOnLongClickListener { + val position = bindingAdapterPosition + + val app = apps[position].first + itemLongClickListener.onItemLongClick( + app, + apps[position].second.first, + apps[position].second.second, + textView, + actionMenuLayout, + editView, + position + ) + return@setOnLongClickListener true + } + + + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.app_item_layout, parent, false) + return AppViewHolder(view) + } + + override fun onBindViewHolder(holder: AppViewHolder, position: Int) { + val app = apps[position] + + if (app.second.second != 0) { + holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null,null,null) + } + else { + holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,null,null) + } + + when (preferences.getString("appMenuAlignment", "left")) { + "left" -> { + holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null, null, null) + holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.START + } + "center" -> { + holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null,holder.textView.compoundDrawables.filterNotNull().first(), null) + holder.textView.gravity = Gravity.CENTER + + } + "right" -> { + holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,null, holder.textView.compoundDrawables.filterNotNull().first(), null) + holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.END + } + } + + when (preferences.getString("appMenuSize", "medium")) { + "small" -> { + holder.textView.textSize = 24F + holder.editText.textSize = 24F + } + + "medium" -> { + holder.textView.textSize = 26F + holder.editText.textSize = 26F + } + + "large" -> { + holder.textView.textSize = 28F + holder.editText.textSize = 28F + } + } + + val appInfo = app.first.activityInfo.applicationInfo + holder.textView.text = sharedPreferenceManager.getAppName(activity, app.first.applicationInfo.packageName,app.second.second, holder.itemView.context.packageManager.getApplicationLabel(appInfo)) + holder.editText.setText(holder.textView.text) + + if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) { + holder.actionMenuLayout.findViewById(R.id.uninstall).visibility = View.GONE + } + else { + holder.actionMenuLayout.findViewById(R.id.uninstall).visibility = View.VISIBLE + } + + holder.textView.visibility = View.VISIBLE + } + + override fun getItemCount(): Int { + return apps.size + } + + @SuppressLint("NotifyDataSetChanged") + fun updateApps(newApps: List>>) { + apps = newApps.toMutableList() + notifyDataSetChanged() + } +} \ No newline at end of file