diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7b774e8d..dccbd13e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,10 +6,10 @@ + - (R.id.app_drawer_fragment_list) val homeView = findViewById(R.id.home_fragment) - if(homeView != null) { - findNavController(homeView).navigate(R.id.action_homeFragment_to_optionsFragment, null) + + if(homeView != null && recyclerView != null) + { + if(isVisible(recyclerView)) + recyclerView.performLongClick() + else // we are in the homeFragment + findNavController(homeView).navigate(R.id.action_homeFragment_to_optionsFragment, null) + } } diff --git a/app/src/main/java/com/sduduzog/slimlauncher/adapters/AppDrawerAdapter.kt b/app/src/main/java/com/sduduzog/slimlauncher/adapters/AppDrawerAdapter.kt index ca2709c4..ed7d6f9e 100644 --- a/app/src/main/java/com/sduduzog/slimlauncher/adapters/AppDrawerAdapter.kt +++ b/app/src/main/java/com/sduduzog/slimlauncher/adapters/AppDrawerAdapter.kt @@ -20,7 +20,6 @@ class AppDrawerAdapter( appsRepo: UnlauncherAppsRepository ) : RecyclerView.Adapter() { private val regex = Regex("[!@#\$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>/? ]") - private var apps: List = listOf() private var filteredApps: List = listOf() private var filterQuery = "" @@ -40,6 +39,9 @@ class AppDrawerAdapter( holder.itemView.setOnClickListener { listener.onAppClicked(item) } + holder.itemView.setOnLongClickListener { + listener.onAppLongClicked(item, it) + } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/java/com/sduduzog/slimlauncher/datasource/apps/UnlauncherAppsRepository.kt b/app/src/main/java/com/sduduzog/slimlauncher/datasource/apps/UnlauncherAppsRepository.kt index 85e5520c..b5883d8b 100644 --- a/app/src/main/java/com/sduduzog/slimlauncher/datasource/apps/UnlauncherAppsRepository.kt +++ b/app/src/main/java/com/sduduzog/slimlauncher/datasource/apps/UnlauncherAppsRepository.kt @@ -123,6 +123,25 @@ class UnlauncherAppsRepository( } } + fun updateDisplayName(appToUpdate: UnlauncherApp, displayName: String) { + lifecycleScope.launch { + unlauncherAppsStore.updateData { currentApps -> + val builder = currentApps.toBuilder() + val index = builder.appsList.indexOf(appToUpdate) + if (index >= 0) { + builder.setApps( + index, + appToUpdate.toBuilder().setDisplayName(displayName) + ) + } + + sortAppsAlphabetically(builder) + builder.build() + } + } + } + + fun updateDisplayInDrawer(appToUpdate: UnlauncherApp, displayInDrawer: Boolean) { lifecycleScope.launch { unlauncherAppsStore.updateData { currentApps -> diff --git a/app/src/main/java/com/sduduzog/slimlauncher/ui/dialogs/RenameAppDisplayNameDialog.kt b/app/src/main/java/com/sduduzog/slimlauncher/ui/dialogs/RenameAppDisplayNameDialog.kt new file mode 100644 index 00000000..7fd5bd52 --- /dev/null +++ b/app/src/main/java/com/sduduzog/slimlauncher/ui/dialogs/RenameAppDisplayNameDialog.kt @@ -0,0 +1,57 @@ +package com.sduduzog.slimlauncher.ui.dialogs + +import android.app.Dialog +import android.os.Bundle +import android.view.LayoutInflater +import android.widget.EditText +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import com.jkuester.unlauncher.datastore.UnlauncherApp +import com.sduduzog.slimlauncher.R +import com.sduduzog.slimlauncher.datasource.apps.UnlauncherAppsRepository +import kotlinx.android.synthetic.main.customise_apps_fragment.* + +class RenameAppDisplayNameDialog : DialogFragment() { + private lateinit var app: UnlauncherApp + private lateinit var unlauncherAppsRepo: UnlauncherAppsRepository + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val view = LayoutInflater.from(context).inflate(R.layout.rename_dialog_edit_text, customise_apps_fragment, false) + val editText: EditText = view.findViewById(R.id.rename_editText) + val appName: String = app.displayName + editText.text.append(appName) + val builder = AlertDialog.Builder(requireContext()) + builder.setTitle("Rename $appName") + builder.setView(view) + builder.setPositiveButton("DONE") { _, _ -> + val name = editText.text.toString() + updateApp(name) + } + editText.setOnEditorActionListener { v, _, _ -> + val name = v.text.toString() + updateApp(name) + this@RenameAppDisplayNameDialog.dismiss() + true + } + + return builder.create() + } + + private fun updateApp(newName: String) { + if (newName.isNotEmpty()) { + unlauncherAppsRepo.updateDisplayName(app, newName) + } else { + Toast.makeText(context, "Couldn't save, App name shouldn't be empty", Toast.LENGTH_LONG).show() + } + } + + companion object { + fun getInstance(app: UnlauncherApp, unlauncherAppsRepo : UnlauncherAppsRepository) : RenameAppDisplayNameDialog { + return RenameAppDisplayNameDialog().apply { + this.app = app + this.unlauncherAppsRepo = unlauncherAppsRepo + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sduduzog/slimlauncher/ui/main/HomeFragment.kt b/app/src/main/java/com/sduduzog/slimlauncher/ui/main/HomeFragment.kt index 70424d26..9c1bbb33 100644 --- a/app/src/main/java/com/sduduzog/slimlauncher/ui/main/HomeFragment.kt +++ b/app/src/main/java/com/sduduzog/slimlauncher/ui/main/HomeFragment.kt @@ -3,15 +3,20 @@ package com.sduduzog.slimlauncher.ui.main import android.app.Activity import android.content.* import android.content.pm.LauncherApps +import android.net.Uri import android.os.Bundle import android.os.UserManager import android.provider.AlarmClock import android.provider.CalendarContract import android.provider.MediaStore +import android.provider.Settings import android.view.LayoutInflater +import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager +import android.widget.PopupMenu +import android.widget.Toast import androidx.constraintlayout.motion.widget.MotionLayout import androidx.constraintlayout.motion.widget.MotionLayout.TransitionListener import androidx.fragment.app.viewModels @@ -25,6 +30,7 @@ import com.sduduzog.slimlauncher.adapters.HomeAdapter import com.sduduzog.slimlauncher.datasource.UnlauncherDataSource import com.sduduzog.slimlauncher.models.HomeApp import com.sduduzog.slimlauncher.models.MainViewModel +import com.sduduzog.slimlauncher.ui.dialogs.RenameAppDisplayNameDialog import com.sduduzog.slimlauncher.utils.BaseFragment import com.sduduzog.slimlauncher.utils.OnLaunchAppListener import dagger.hilt.android.AndroidEntryPoint @@ -36,6 +42,7 @@ import java.text.SimpleDateFormat import java.util.* import javax.inject.Inject + @AndroidEntryPoint class HomeFragment : BaseFragment(), OnLaunchAppListener { @Inject @@ -279,6 +286,51 @@ class HomeFragment : BaseFragment(), OnLaunchAppListener { } inner class AppDrawerListener { + fun onAppLongClicked(app : UnlauncherApp, view: View) : Boolean { + val popupMenu = PopupMenu(context, view) + popupMenu.inflate(R.menu.app_long_press_menu) + + popupMenu.setOnMenuItemClickListener { item: MenuItem? -> + + when (item!!.itemId) { + R.id.open -> { + onAppClicked(app) + } + R.id.info -> { + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + intent.addCategory(Intent.CATEGORY_DEFAULT) + intent.data = Uri.parse("package:" + app.packageName) + startActivity(intent) + } + R.id.hide -> { + unlauncherDataSource.unlauncherAppsRepo.updateDisplayInDrawer(app, false) + Toast.makeText(context, "Unhide under Unlauncher's Options > Customize Drawer > Visible Apps", Toast.LENGTH_LONG).show() + } + R.id.rename -> { + RenameAppDisplayNameDialog.getInstance(app, unlauncherDataSource.unlauncherAppsRepo).show(childFragmentManager, "AppListAdapter") + } + R.id.uninstall -> { + val intent = Intent(Intent.ACTION_DELETE) + intent.data = Uri.parse("package:" + app.packageName) + startActivity(intent) + //appDrawerAdapter.notifyDataSetChanged() + // TODO: Handle the case when this is done for system apps + } + } + true + } + + val fieldMPopup = PopupMenu::class.java.getDeclaredField("mPopup") + fieldMPopup.isAccessible = true + val mPopup = fieldMPopup.get(popupMenu) + mPopup.javaClass + .getDeclaredMethod("setForceShowIcon", Boolean::class.java) + .invoke(mPopup, true) + + popupMenu.show() + return true + } + fun onAppClicked(app: UnlauncherApp) { launchApp(app.packageName, app.className, app.userSerial) home_fragment.transitionToStart() diff --git a/app/src/main/res/drawable/ic_app_info.xml b/app/src/main/res/drawable/ic_app_info.xml new file mode 100644 index 00000000..8f88947b --- /dev/null +++ b/app/src/main/res/drawable/ic_app_info.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_hide_app.xml b/app/src/main/res/drawable/ic_hide_app.xml new file mode 100644 index 00000000..1b5757c8 --- /dev/null +++ b/app/src/main/res/drawable/ic_hide_app.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_open_app.xml b/app/src/main/res/drawable/ic_open_app.xml new file mode 100644 index 00000000..5ef5bb63 --- /dev/null +++ b/app/src/main/res/drawable/ic_open_app.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_rename_app.xml b/app/src/main/res/drawable/ic_rename_app.xml new file mode 100644 index 00000000..6a9d9a46 --- /dev/null +++ b/app/src/main/res/drawable/ic_rename_app.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_uninstall_app.xml b/app/src/main/res/drawable/ic_uninstall_app.xml new file mode 100644 index 00000000..4d8ca3e7 --- /dev/null +++ b/app/src/main/res/drawable/ic_uninstall_app.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/menu/app_long_press_menu.xml b/app/src/main/res/menu/app_long_press_menu.xml new file mode 100644 index 00000000..689ed1e7 --- /dev/null +++ b/app/src/main/res/menu/app_long_press_menu.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7af7f65c..ea0ac3d8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -57,5 +57,10 @@ Remove All Apps "This action will not uninstall your apps." "It is just to confirm if you're clearing this list on purpose" + Open App + App Info + Hide App + Rename App + Uninstall