improvement: Add a button to add a Custom filter to the Home screen

This commit is contained in:
Artem Chepurnoy 2024-03-07 12:13:23 +02:00
parent 81d98764ea
commit f423826252
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
8 changed files with 110 additions and 18 deletions

View File

@ -1,19 +1,17 @@
package com.artemchep.keyguard package com.artemchep.keyguard
import android.content.Context import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.artemchep.bindin.bindBlock import com.artemchep.bindin.bindBlock
import com.artemchep.keyguard.android.BaseApp import com.artemchep.keyguard.android.BaseApp
import com.artemchep.keyguard.android.MainActivity
import com.artemchep.keyguard.android.downloader.journal.DownloadRepository import com.artemchep.keyguard.android.downloader.journal.DownloadRepository
import com.artemchep.keyguard.android.downloader.worker.AttachmentDownloadAllWorker import com.artemchep.keyguard.android.downloader.worker.AttachmentDownloadAllWorker
import com.artemchep.keyguard.android.passkeysModule import com.artemchep.keyguard.android.passkeysModule
import com.artemchep.keyguard.android.util.ShortcutIds
import com.artemchep.keyguard.android.util.ShortcutInfo
import com.artemchep.keyguard.billing.BillingManager import com.artemchep.keyguard.billing.BillingManager
import com.artemchep.keyguard.billing.BillingManagerImpl import com.artemchep.keyguard.billing.BillingManagerImpl
import com.artemchep.keyguard.common.AppWorker import com.artemchep.keyguard.common.AppWorker
@ -250,7 +248,7 @@ class Main : BaseApp(), DIAware {
.map { it.id } .map { it.id }
.toSet() .toSet()
val newDynamicShortcutsIds = filters val newDynamicShortcutsIds = filters
.map { it.id } .map { ShortcutIds.forFilter(it.id) }
.toSet() .toSet()
oldDynamicShortcutsIds - newDynamicShortcutsIds oldDynamicShortcutsIds - newDynamicShortcutsIds
} }
@ -260,18 +258,11 @@ class Main : BaseApp(), DIAware {
} }
val shortcuts = filters val shortcuts = filters
.map { .map { filter ->
val intent = MainActivity.getIntent(this@Main).apply { ShortcutInfo.forFilter(
action = Intent.ACTION_VIEW context = this@Main,
putExtra("customFilter", it.id) filter = filter,
} )
val icon = IconCompat.createWithResource(this@Main, com.artemchep.keyguard.common.R.drawable.ic_shortcut_keyguard)
ShortcutInfoCompat.Builder(this@Main, it.id)
.setIcon(icon)
.setShortLabel(it.name)
.setIntent(intent)
.addCapabilityBinding("actions.intent.OPEN_APP_FEATURE")
.build()
} }
ShortcutManagerCompat.addDynamicShortcuts(this@Main, shortcuts) ShortcutManagerCompat.addDynamicShortcuts(this@Main, shortcuts)
} }

View File

@ -0,0 +1,35 @@
package com.artemchep.keyguard.android.util
import android.content.Context
import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.graphics.drawable.IconCompat
import com.artemchep.keyguard.android.MainActivity
import com.artemchep.keyguard.common.R
import com.artemchep.keyguard.common.model.DCipherFilter
object ShortcutIds {
fun forFilter(filterId: String): String {
return "filter=$filterId"
}
}
object ShortcutInfo {
fun forFilter(
context: Context,
filter: DCipherFilter,
): ShortcutInfoCompat {
val id = ShortcutIds.forFilter(filter.id)
val intent = MainActivity.getIntent(context).apply {
action = Intent.ACTION_VIEW
putExtra("customFilter", filter.id)
}
val icon = IconCompat.createWithResource(context, R.drawable.ic_shortcut_keyguard)
return ShortcutInfoCompat.Builder(context, id)
.setIcon(icon)
.setShortLabel(filter.name)
.setIntent(intent)
.addCapabilityBinding("actions.intent.OPEN_APP_FEATURE")
.build()
}
}

View File

@ -0,0 +1,33 @@
package com.artemchep.keyguard.feature.filter.util
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.AddToHomeScreen
import androidx.core.content.pm.ShortcutManagerCompat
import com.artemchep.keyguard.android.util.ShortcutInfo
import com.artemchep.keyguard.common.model.DCipherFilter
import com.artemchep.keyguard.feature.navigation.state.RememberStateFlowScope
import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.ui.FlatItemAction
import com.artemchep.keyguard.ui.icons.iconSmall
context(RememberStateFlowScope)
actual fun CipherFilterUtil.addShortcutActionOrNull(
filter: DCipherFilter,
): FlatItemAction? {
val androidContext = context.context
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(androidContext)) {
return null
}
val shortcut = ShortcutInfo.forFilter(
context = androidContext,
filter = filter,
)
return FlatItemAction(
leading = iconSmall(Icons.AutoMirrored.Outlined.AddToHomeScreen),
title = translate(Res.strings.add_to_home_screen),
onClick = {
ShortcutManagerCompat.requestPinShortcut(androidContext, shortcut, null)
},
)
}

View File

@ -17,6 +17,7 @@ import com.artemchep.keyguard.feature.attachments.SelectableItemStateRaw
import com.artemchep.keyguard.feature.crashlytics.crashlyticsAttempt import com.artemchep.keyguard.feature.crashlytics.crashlyticsAttempt
import com.artemchep.keyguard.feature.filter.CipherFiltersRoute import com.artemchep.keyguard.feature.filter.CipherFiltersRoute
import com.artemchep.keyguard.feature.filter.util.CipherFilterUtil import com.artemchep.keyguard.feature.filter.util.CipherFilterUtil
import com.artemchep.keyguard.feature.filter.util.addShortcutActionOrNull
import com.artemchep.keyguard.feature.filter.view.CipherFilterViewDialogRoute import com.artemchep.keyguard.feature.filter.view.CipherFilterViewDialogRoute
import com.artemchep.keyguard.feature.filter.view.CipherFilterViewFullRoute import com.artemchep.keyguard.feature.filter.view.CipherFilterViewFullRoute
import com.artemchep.keyguard.feature.generator.wordlist.util.WordlistUtil import com.artemchep.keyguard.feature.generator.wordlist.util.WordlistUtil
@ -211,8 +212,13 @@ fun produceCipherFiltersListState(
val actions = buildContextItems { val actions = buildContextItems {
if (selectedItems.size == 1) { if (selectedItems.size == 1) {
section {
val selectedItem = selectedItems.first() val selectedItem = selectedItems.first()
section {
this += CipherFilterUtil.addShortcutActionOrNull(
filter = selectedItem,
)
}
section {
this += FlatItemAction( this += FlatItemAction(
icon = Icons.Outlined.Edit, icon = Icons.Outlined.Edit,
title = translate(Res.strings.edit), title = translate(Res.strings.edit),

View File

@ -11,13 +11,18 @@ import com.artemchep.keyguard.common.service.filter.model.RenameCipherFilterRequ
import com.artemchep.keyguard.feature.confirmation.ConfirmationResult import com.artemchep.keyguard.feature.confirmation.ConfirmationResult
import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute
import com.artemchep.keyguard.feature.confirmation.createConfirmationDialogIntent import com.artemchep.keyguard.feature.confirmation.createConfirmationDialogIntent
import com.artemchep.keyguard.feature.filter.CipherFiltersRoute
import com.artemchep.keyguard.feature.navigation.NavigationIntent import com.artemchep.keyguard.feature.navigation.NavigationIntent
import com.artemchep.keyguard.feature.navigation.registerRouteResultReceiver import com.artemchep.keyguard.feature.navigation.registerRouteResultReceiver
import com.artemchep.keyguard.feature.navigation.state.RememberStateFlowScope import com.artemchep.keyguard.feature.navigation.state.RememberStateFlowScope
import com.artemchep.keyguard.feature.navigation.state.TranslatorScope
import com.artemchep.keyguard.res.Res import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.ui.FlatItemAction
import com.artemchep.keyguard.ui.icons.ChevronIcon
import com.artemchep.keyguard.ui.icons.KeyguardCipherFilter import com.artemchep.keyguard.ui.icons.KeyguardCipherFilter
import com.artemchep.keyguard.ui.icons.KeyguardWordlist import com.artemchep.keyguard.ui.icons.KeyguardWordlist
import com.artemchep.keyguard.ui.icons.icon import com.artemchep.keyguard.ui.icons.icon
import com.artemchep.keyguard.ui.icons.iconSmall
object CipherFilterUtil { object CipherFilterUtil {
context(RememberStateFlowScope) context(RememberStateFlowScope)
@ -92,3 +97,8 @@ object CipherFilterUtil {
navigate(intent) navigate(intent)
} }
} }
context(RememberStateFlowScope)
expect fun CipherFilterUtil.addShortcutActionOrNull(
filter: DCipherFilter,
): FlatItemAction?

View File

@ -20,6 +20,7 @@ import com.artemchep.keyguard.common.usecase.GetOrganizations
import com.artemchep.keyguard.common.usecase.GetProfiles import com.artemchep.keyguard.common.usecase.GetProfiles
import com.artemchep.keyguard.common.util.flow.foldAsList import com.artemchep.keyguard.common.util.flow.foldAsList
import com.artemchep.keyguard.feature.filter.util.CipherFilterUtil import com.artemchep.keyguard.feature.filter.util.CipherFilterUtil
import com.artemchep.keyguard.feature.filter.util.addShortcutActionOrNull
import com.artemchep.keyguard.feature.home.vault.model.FilterItem import com.artemchep.keyguard.feature.home.vault.model.FilterItem
import com.artemchep.keyguard.feature.home.vault.screen.FilterSection import com.artemchep.keyguard.feature.home.vault.screen.FilterSection
import com.artemchep.keyguard.feature.navigation.state.navigatePopSelf import com.artemchep.keyguard.feature.navigation.state.navigatePopSelf
@ -264,6 +265,11 @@ fun produceCipherFilterViewState(
filter filter
?: return@run persistentListOf() ?: return@run persistentListOf()
buildContextItems { buildContextItems {
section {
this += CipherFilterUtil.addShortcutActionOrNull(
filter = filter,
)
}
section { section {
this += FlatItemAction( this += FlatItemAction(
icon = Icons.Outlined.Edit, icon = Icons.Outlined.Edit,

View File

@ -142,6 +142,7 @@
<string name="ignored_alerts">Ignored alerts</string> <string name="ignored_alerts">Ignored alerts</string>
<string name="api_key">API key</string> <string name="api_key">API key</string>
<string name="domain">Domain</string> <string name="domain">Domain</string>
<string name="add_to_home_screen">Add to Home screen</string>
<string name="edit">Edit</string> <string name="edit">Edit</string>
<string name="delete">Delete</string> <string name="delete">Delete</string>
<string name="remove">Remove</string> <string name="remove">Remove</string>

View File

@ -0,0 +1,10 @@
package com.artemchep.keyguard.feature.filter.util
import com.artemchep.keyguard.common.model.DCipherFilter
import com.artemchep.keyguard.feature.navigation.state.RememberStateFlowScope
import com.artemchep.keyguard.ui.FlatItemAction
context(RememberStateFlowScope)
actual fun CipherFilterUtil.addShortcutActionOrNull(
filter: DCipherFilter,
): FlatItemAction? = null