From 131acb3039dcb29d5b4d37b80246f01fbf57b32c Mon Sep 17 00:00:00 2001 From: ottoptj Date: Mon, 20 May 2024 04:01:28 +0300 Subject: [PATCH] Specific item updates added. Still needs testing and refinement. --- .../eu/ottop/yamlauncher/AppActionMenu.kt | 6 +- .../eu/ottop/yamlauncher/AppMenuActivity.kt | 98 +++++++++++++++---- .../eu/ottop/yamlauncher/AppMenuAdapter.kt | 24 +++-- .../java/eu/ottop/yamlauncher/MainActivity.kt | 6 -- 4 files changed, 100 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt index 11b6437..90a5ba7 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt @@ -36,6 +36,7 @@ class AppActionMenu { workProfile: Int, launcherApps: LauncherApps, mainActivity: LauncherActivityInfo?, + position: Int ){ actionMenu.findViewById(R.id.info).setOnClickListener { @@ -93,7 +94,7 @@ class AppActionMenu { imm.hideSoftInputFromWindow(editText.windowToken, 0) sharedPreferenceManager.setAppName(activity, appInfo.packageName, workProfile, editText.text.toString()) uiScope.launch { - activity.manualRefreshApps() + activity.updateItem(position,Pair(mainActivity!!, Pair(userHandle, workProfile))) } return@setOnEditorActionListener true @@ -104,7 +105,8 @@ class AppActionMenu { actionMenu.findViewById(R.id.hide).setOnClickListener { sharedPreferenceManager.setAppHidden(activity, appInfo.packageName, workProfile, true) - activity.manualRefreshApps() + textView.visibility = View.GONE + editLayout.visibility = View.GONE actionMenu.visibility = View.GONE } diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt b/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt index a3340d7..e9ceebf 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt @@ -1,6 +1,5 @@ package eu.ottop.yamlauncher -import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.LauncherActivityInfo @@ -9,7 +8,6 @@ import android.os.Bundle import android.os.UserHandle import android.text.Editable import android.text.TextWatcher -import android.util.Log import android.view.View import android.widget.EditText import android.widget.LinearLayout @@ -45,7 +43,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, companion object { private lateinit var callback: (Pair, Pair>) -> Unit - private const val MENU_MODE = "abcd" + private const val MENU_MODE = "app" fun start(context: Context, param1: String = "app", callback: (Pair, Pair>) -> Unit) { val intent = Intent(context, AppMenuActivity::class.java).apply { @@ -77,7 +75,9 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, recyclerView.layoutManager = LinearLayoutManager(this) installedApps = getInstalledApps() filteredApps = mutableListOf() - adapter = AppMenuAdapter(this@AppMenuActivity, installedApps, this, this,this, menuMode) + val newApps = mutableListOf>>() + newApps.addAll(installedApps) + adapter = AppMenuAdapter(this@AppMenuActivity, newApps, this, this,this, menuMode) recyclerView.adapter = adapter setupSearch() @@ -94,7 +94,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, } override fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int) { - callback.invoke(Pair(Pair(textView.text.toString(), userProfile), Pair(appInfo, userHandle,))) + callback.invoke(Pair(Pair(textView.text.toString(), userProfile), Pair(appInfo, userHandle))) finish() } @@ -104,7 +104,8 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, userProfile: Int, textView: TextView, actionMenuLayout: LinearLayout, - editView: LinearLayout + editView: LinearLayout, + position: Int ) { textView.visibility = View.INVISIBLE actionMenuLayout.visibility = View.VISIBLE @@ -123,7 +124,8 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, userHandle, userProfile, launcherApps, - mainActivity + mainActivity, + position ) } @@ -166,7 +168,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, } } withContext(Dispatchers.Main) { - adapter.updateApps(filteredApps) + //adapter.updateApps(filteredApps) } } @@ -209,9 +211,10 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, while (true) { val updatedApps = getInstalledApps() if (!listsEqual(installedApps, updatedApps)) { + val changes = detectChanges(installedApps, updatedApps) installedApps = updatedApps withContext(Dispatchers.Main) { - adapter.updateApps(installedApps) + applyChanges(changes, installedApps) } } delay(5000) @@ -219,15 +222,6 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, } } - fun manualRefreshApps() { - CoroutineScope(Dispatchers.Default).launch { - installedApps = getInstalledApps() - withContext(Dispatchers.Main) { - adapter.updateApps(installedApps) - } - } - } - private fun listsEqual( list1: List>>, list2: List>> @@ -243,4 +237,72 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, return true } + data class Change(val type: ChangeType, val position: Int) + + enum class ChangeType { + INSERT, REMOVE, UPDATE + } + + private fun detectChanges(oldList: List>>, newList: List>>): List { + val changes = mutableListOf() + val oldSet = oldList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet() + val newSet = newList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet() + + // Detect removals + oldList.forEachIndexed { index, oldItem -> + if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) { + changes.add(Change(ChangeType.REMOVE, index)) + } + } + + // Detect insertions + newList.forEachIndexed { index, newItem -> + if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) { + changes.add(Change(ChangeType.INSERT, index)) + } + } + + // Detect updates + oldList.forEachIndexed { index, oldItem -> + if (newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) { + val newIndex = newList.indexOfFirst { it.first.applicationInfo.packageName == oldItem.first.applicationInfo.packageName } + if (oldItem.first.applicationInfo.packageName != newList[newIndex].first.applicationInfo.packageName) { + changes.add(Change(ChangeType.UPDATE, index)) + } + } + } + + return changes + } + + private fun applyChanges(changes: List, updatedApps: List>>) { + changes.forEach { change -> + when (change.type) { + ChangeType.INSERT -> { + insertItem(change.position, updatedApps[change.position]) + } + ChangeType.REMOVE -> { + removeItem(change.position) + } + ChangeType.UPDATE -> { + updateItem(change.position, updatedApps[change.position]) + } + } + } + } + + private fun insertItem(position: Int, app: Pair>) { + adapter.addApp(position, app) + adapter.notifyItemInserted(position) + } + private fun removeItem(position: Int) { + adapter.removeApp(position) + adapter.notifyItemRemoved(position) + } + + fun updateItem(position: Int, app: Pair>) { + adapter.updateApp(position, app) + adapter.notifyItemChanged(position) + } + } \ 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 11484ab..0d6c4eb 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppMenuAdapter.kt @@ -2,7 +2,6 @@ package eu.ottop.yamlauncher import android.content.Context import android.content.pm.LauncherActivityInfo -import android.content.res.Resources import android.os.UserHandle import android.view.LayoutInflater import android.view.View @@ -18,7 +17,7 @@ import androidx.recyclerview.widget.RecyclerView class AppMenuAdapter( private val activity: AppMenuActivity, - var apps: List>>, + var apps: MutableList>>, private val itemClickListener: OnItemClickListener, private val shortcutListener: OnShortcutListener, private val itemLongClickListener: OnItemLongClickListener, @@ -43,7 +42,8 @@ class AppMenuAdapter( userProfile: Int, textView: TextView, actionMenuLayout: LinearLayout, - editView: LinearLayout + editView: LinearLayout, + position: Int ) } @@ -78,7 +78,8 @@ class AppMenuAdapter( apps[position].second.second, textView, actionMenuLayout, - editView + editView, + position ) return@setOnLongClickListener true } @@ -115,7 +116,7 @@ class AppMenuAdapter( val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(holder.editView.windowToken, 0) sharedPreferenceManager.resetAppName(activity, app.first.applicationInfo.packageName, app.second.second) - activity.manualRefreshApps() + updateApp(position, app) } } @@ -123,8 +124,15 @@ class AppMenuAdapter( return apps.size } - fun updateApps(newApps: List>>) { - apps = newApps - notifyDataSetChanged() + fun addApp(position: Int, app: Pair>) { + apps.add(position, app) + } + + fun removeApp(position: Int) { + apps.removeAt(position) + } + + fun updateApp(position: Int, app: Pair>) { + apps[position] = app } } \ No newline at end of file diff --git a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt index bec15c4..2140e3f 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt @@ -1,19 +1,13 @@ package eu.ottop.yamlauncher -import android.app.Activity import android.content.Context -import android.content.Intent import android.content.pm.LauncherApps import android.os.Bundle -import android.util.Log import android.view.GestureDetector import android.view.MotionEvent -import android.view.View import android.widget.LinearLayout import android.widget.TextView import android.widget.Toast -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.content.res.ResourcesCompat import androidx.core.view.children