Shortcut icon (#1486)

* Allow custom icon selection for shortcuts

* Pull in fix for webview flags

* Review comments

* Fix syntax per review comment
This commit is contained in:
Daniel Shokouhi 2021-04-06 08:51:50 -07:00 committed by GitHub
parent 9210a1ab14
commit 87ad57ef0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 6 deletions

View file

@ -3,6 +3,8 @@ package io.homeassistant.companion.android.settings.shortcuts
import android.content.Intent import android.content.Intent
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -10,11 +12,18 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.maltaisn.icondialog.IconDialog
import com.maltaisn.icondialog.IconDialogSettings
import com.maltaisn.icondialog.pack.IconPack
import com.maltaisn.icondialog.pack.IconPackLoader
import com.maltaisn.iconpack.mdi.createMaterialDesignIconPack
import io.homeassistant.companion.android.R import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.common.dagger.GraphComponentAccessor import io.homeassistant.companion.android.common.dagger.GraphComponentAccessor
import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.IntegrationRepository
@ -24,7 +33,7 @@ import java.lang.Exception
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() { class ManageShortcutsSettingsFragment : PreferenceFragmentCompat(), IconDialog.Callback {
companion object { companion object {
private const val MAX_SHORTCUTS = 5 private const val MAX_SHORTCUTS = 5
@ -37,12 +46,15 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
private const val DELETE_SUFFIX = "_delete" private const val DELETE_SUFFIX = "_delete"
private const val TYPE_SUFFIX = "_type" private const val TYPE_SUFFIX = "_type"
private const val ENTITY_SUFFIX = "_entity_list" private const val ENTITY_SUFFIX = "_entity_list"
private const val ICON_PREFIX = "_icon"
private const val TAG = "ManageShortcutFrag" private const val TAG = "ManageShortcutFrag"
fun newInstance(): ManageShortcutsSettingsFragment { fun newInstance(): ManageShortcutsSettingsFragment {
return ManageShortcutsSettingsFragment() return ManageShortcutsSettingsFragment()
} }
} }
private lateinit var iconPack: IconPack
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
@ -67,6 +79,16 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val loader = IconPackLoader(requireContext())
iconPack = createMaterialDesignIconPack(loader)
iconPack.loadDrawables(loader.drawableLoader)
val settings = IconDialogSettings {
searchVisibility = IconDialog.SearchVisibility.ALWAYS
}
val iconDialog = IconDialog.newInstance(settings)
val iconId = 62017
onIconDialogIconsSelected(iconDialog, listOf(iconPack.icons[iconId]!!))
activity?.title = getString(R.string.shortcuts) activity?.title = getString(R.string.shortcuts)
DaggerSettingsComponent.builder() DaggerSettingsComponent.builder()
.appComponent((activity?.applicationContext as GraphComponentAccessor).appComponent) .appComponent((activity?.applicationContext as GraphComponentAccessor).appComponent)
@ -133,6 +155,13 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
} }
} }
findPreference<Preference>(SHORTCUT_PREFIX + i + ICON_PREFIX)?.let {
it.setOnPreferenceClickListener {
iconDialog.show(childFragmentManager, SHORTCUT_PREFIX + i)
return@setOnPreferenceClickListener true
}
}
findPreference<EditTextPreference>(SHORTCUT_PREFIX + i + LABEL_SUFFIX)?.let { findPreference<EditTextPreference>(SHORTCUT_PREFIX + i + LABEL_SUFFIX)?.let {
it.title = "${getString(R.string.shortcut)} $i ${getString(R.string.label)}" it.title = "${getString(R.string.shortcut)} $i ${getString(R.string.label)}"
it.dialogTitle = "${getString(R.string.shortcut)} $i ${getString(R.string.label)}" it.dialogTitle = "${getString(R.string.shortcut)} $i ${getString(R.string.label)}"
@ -166,7 +195,7 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
if (!shortcutLabel.isNullOrEmpty() && !shortcutDesc.isNullOrEmpty() && !shortcutPath.isNullOrEmpty()) { if (!shortcutLabel.isNullOrEmpty() && !shortcutDesc.isNullOrEmpty() && !shortcutPath.isNullOrEmpty()) {
if (shortcutType?.value == getString(R.string.entity_id)) if (shortcutType?.value == getString(R.string.entity_id))
shortcutPath = "entityId:${shortcutEntityList?.value}" shortcutPath = "entityId:${shortcutEntityList?.value}"
val shortcut = createShortcut(SHORTCUT_PREFIX + i, shortcutLabel!!, shortcutDesc!!, shortcutPath!!) val shortcut = createShortcut(SHORTCUT_PREFIX + i, shortcutLabel!!, shortcutDesc!!, shortcutPath!!, findPreference<Preference>(SHORTCUT_PREFIX + i + ICON_PREFIX)?.icon?.toBitmap())
shortcutManager!!.addDynamicShortcuts(listOf(shortcut)) shortcutManager!!.addDynamicShortcuts(listOf(shortcut))
} }
dynamicShortcuts = shortcutManager.dynamicShortcuts dynamicShortcuts = shortcutManager.dynamicShortcuts
@ -263,6 +292,13 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
} }
} }
findPreference<Preference>("pinned_shortcut_icon")?.let {
it.setOnPreferenceClickListener {
iconDialog.show(childFragmentManager, "pinned")
return@setOnPreferenceClickListener true
}
}
findPreference<EditTextPreference>("pinned_shortcut_label")?.let { findPreference<EditTextPreference>("pinned_shortcut_label")?.let {
it.setOnPreferenceChangeListener { _, newValue -> it.setOnPreferenceChangeListener { _, newValue ->
pinnedShortcutLabel = newValue.toString() pinnedShortcutLabel = newValue.toString()
@ -293,7 +329,7 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
Log.d(TAG, "Attempt to add $pinnedShortcutId") Log.d(TAG, "Attempt to add $pinnedShortcutId")
if (pinnedShortcutType?.value == getString(R.string.entity_id)) if (pinnedShortcutType?.value == getString(R.string.entity_id))
pinnedShortcutPath = "entityId:${pinnedShortcutEntityList?.value}" pinnedShortcutPath = "entityId:${pinnedShortcutEntityList?.value}"
val shortcut = createShortcut(pinnedShortcutId!!, pinnedShortcutLabel!!, pinnedShortcutDesc!!, pinnedShortcutPath!!) val shortcut = createShortcut(pinnedShortcutId!!, pinnedShortcutLabel!!, pinnedShortcutDesc!!, pinnedShortcutPath!!, findPreference<Preference>("pinned_shortcut_icon")?.icon?.toBitmap())
var isNewPinned = true var isNewPinned = true
for (item in pinnedShortcuts) { for (item in pinnedShortcuts) {
@ -318,14 +354,20 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
} }
@RequiresApi(Build.VERSION_CODES.N_MR1) @RequiresApi(Build.VERSION_CODES.N_MR1)
private fun createShortcut(shortcutId: String, shortcutLabel: String, shortcutDesc: String, shortcutPath: String): ShortcutInfo { private fun createShortcut(shortcutId: String, shortcutLabel: String, shortcutDesc: String, shortcutPath: String, bitmap: Bitmap? = null): ShortcutInfo {
val intent = Intent(WebViewActivity.newInstance(requireContext(), shortcutPath).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) val intent = Intent(WebViewActivity.newInstance(requireContext(), shortcutPath).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
intent.action = shortcutPath intent.action = shortcutPath
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
return ShortcutInfo.Builder(requireContext(), shortcutId) return ShortcutInfo.Builder(requireContext(), shortcutId)
.setShortLabel(shortcutLabel) .setShortLabel(shortcutLabel)
.setLongLabel(shortcutDesc) .setLongLabel(shortcutDesc)
.setIcon(Icon.createWithResource(requireContext(), R.drawable.ic_stat_ic_notification_blue)) .setIcon(
if (bitmap != null)
Icon.createWithBitmap(bitmap)
else
Icon.createWithResource(requireContext(), R.drawable.ic_stat_ic_notification_blue)
)
.setIntent(intent) .setIntent(intent)
.build() .build()
} }
@ -355,4 +397,27 @@ class ManageShortcutsSettingsFragment : PreferenceFragmentCompat() {
} }
} }
} }
override val iconDialogIconPack: IconPack
get() = iconPack
override fun onIconDialogIconsSelected(dialog: IconDialog, icons: List<com.maltaisn.icondialog.data.Icon>) {
Log.d(TAG, "Selected icon: ${icons.firstOrNull()}")
val selectedIcon = icons.firstOrNull()
if (selectedIcon != null) {
val iconDrawable = selectedIcon.drawable
if (iconDrawable != null) {
val icon = DrawableCompat.wrap(iconDrawable)
icon.setColorFilter(resources.getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN)
when (dialog.tag) {
"pinned" -> findPreference<Preference>("pinned_shortcut_icon")?.icon = icon
"${SHORTCUT_PREFIX}1" -> findPreference<Preference>(SHORTCUT_PREFIX + "1_icon")?.icon = icon
"${SHORTCUT_PREFIX}2" -> findPreference<Preference>(SHORTCUT_PREFIX + "2_icon")?.icon = icon
"${SHORTCUT_PREFIX}3" -> findPreference<Preference>(SHORTCUT_PREFIX + "3_icon")?.icon = icon
"${SHORTCUT_PREFIX}4" -> findPreference<Preference>(SHORTCUT_PREFIX + "4_icon")?.icon = icon
"${SHORTCUT_PREFIX}5" -> findPreference<Preference>(SHORTCUT_PREFIX + "5_icon")?.icon = icon
}
}
}
}
} }

View file

@ -24,7 +24,8 @@ object NotificationActionContentHandler {
} }
} ?: WebViewActivity.newInstance(context) } ?: WebViewActivity.newInstance(context)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
context.startActivity(intent) context.startActivity(intent)
onComplete() onComplete()
} }

View file

@ -560,4 +560,5 @@ like to connect to:</string>
<string name="remaining">Remaining</string> <string name="remaining">Remaining</string>
<string name="maximum">Maximum</string> <string name="maximum">Maximum</string>
<string name="resets_at">Resets at</string> <string name="resets_at">Resets at</string>
<string name="shortcut_icon">Shortcut Icon</string>
</resources> </resources>

View file

@ -11,6 +11,10 @@
<PreferenceCategory <PreferenceCategory
android:key="shortcut1_category" android:key="shortcut1_category"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<Preference
android:key="shortcut1_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="shortcut1_label" android:key="shortcut1_label"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
@ -49,6 +53,10 @@
<PreferenceCategory <PreferenceCategory
android:key="shortcut2_category" android:key="shortcut2_category"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<Preference
android:key="shortcut2_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="shortcut2_label" android:key="shortcut2_label"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
@ -87,6 +95,10 @@
<PreferenceCategory <PreferenceCategory
android:key="shortcut3_category" android:key="shortcut3_category"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<Preference
android:key="shortcut3_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="shortcut3_label" android:key="shortcut3_label"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
@ -125,6 +137,10 @@
<PreferenceCategory <PreferenceCategory
android:key="shortcut4_category" android:key="shortcut4_category"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<Preference
android:key="shortcut4_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="shortcut4_label" android:key="shortcut4_label"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
@ -168,6 +184,10 @@
android:summary="@string/shortcut5_note" android:summary="@string/shortcut5_note"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
android:selectable="false" /> android:selectable="false" />
<Preference
android:key="shortcut5_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="shortcut5_label" android:key="shortcut5_label"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
@ -224,6 +244,10 @@
android:title="@string/shortcut_pinned_id" android:title="@string/shortcut_pinned_id"
app:useSimpleSummaryProvider="true" app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<Preference
android:key="pinned_shortcut_icon"
android:title="@string/shortcut_icon"
android:icon="@drawable/ic_stat_ic_notification_blue"/>
<EditTextPreference <EditTextPreference
android:key="pinned_shortcut_label" android:key="pinned_shortcut_label"
android:title="@string/shortcut_pinned_label" android:title="@string/shortcut_pinned_label"