diff --git a/androidApp/src/main/java/com/artemchep/keyguard/Main.kt b/androidApp/src/main/java/com/artemchep/keyguard/Main.kt
index 2ce3e97..1b6e7e9 100644
--- a/androidApp/src/main/java/com/artemchep/keyguard/Main.kt
+++ b/androidApp/src/main/java/com/artemchep/keyguard/Main.kt
@@ -1,19 +1,17 @@
package com.artemchep.keyguard
import android.content.Context
-import android.content.Intent
import androidx.core.content.ContextCompat
-import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
-import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.artemchep.bindin.bindBlock
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.worker.AttachmentDownloadAllWorker
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.BillingManagerImpl
import com.artemchep.keyguard.common.AppWorker
@@ -250,7 +248,7 @@ class Main : BaseApp(), DIAware {
.map { it.id }
.toSet()
val newDynamicShortcutsIds = filters
- .map { it.id }
+ .map { ShortcutIds.forFilter(it.id) }
.toSet()
oldDynamicShortcutsIds - newDynamicShortcutsIds
}
@@ -260,18 +258,11 @@ class Main : BaseApp(), DIAware {
}
val shortcuts = filters
- .map {
- val intent = MainActivity.getIntent(this@Main).apply {
- action = Intent.ACTION_VIEW
- putExtra("customFilter", it.id)
- }
- 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()
+ .map { filter ->
+ ShortcutInfo.forFilter(
+ context = this@Main,
+ filter = filter,
+ )
}
ShortcutManagerCompat.addDynamicShortcuts(this@Main, shortcuts)
}
diff --git a/common/src/androidMain/kotlin/com/artemchep/keyguard/android/util/shortcut.kt b/common/src/androidMain/kotlin/com/artemchep/keyguard/android/util/shortcut.kt
new file mode 100644
index 0000000..e5f56eb
--- /dev/null
+++ b/common/src/androidMain/kotlin/com/artemchep/keyguard/android/util/shortcut.kt
@@ -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()
+ }
+}
diff --git a/common/src/androidMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.android.kt b/common/src/androidMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.android.kt
new file mode 100644
index 0000000..5a1988c
--- /dev/null
+++ b/common/src/androidMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.android.kt
@@ -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)
+ },
+ )
+}
diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/list/CipherFiltersListStateProducer.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/list/CipherFiltersListStateProducer.kt
index e3d4a2f..a328c76 100644
--- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/list/CipherFiltersListStateProducer.kt
+++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/list/CipherFiltersListStateProducer.kt
@@ -17,6 +17,7 @@ import com.artemchep.keyguard.feature.attachments.SelectableItemStateRaw
import com.artemchep.keyguard.feature.crashlytics.crashlyticsAttempt
import com.artemchep.keyguard.feature.filter.CipherFiltersRoute
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.CipherFilterViewFullRoute
import com.artemchep.keyguard.feature.generator.wordlist.util.WordlistUtil
@@ -211,8 +212,13 @@ fun produceCipherFiltersListState(
val actions = buildContextItems {
if (selectedItems.size == 1) {
+ val selectedItem = selectedItems.first()
+ section {
+ this += CipherFilterUtil.addShortcutActionOrNull(
+ filter = selectedItem,
+ )
+ }
section {
- val selectedItem = selectedItems.first()
this += FlatItemAction(
icon = Icons.Outlined.Edit,
title = translate(Res.strings.edit),
diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.kt
index 5215911..dfc5df8 100644
--- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.kt
+++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.kt
@@ -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.ConfirmationRoute
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.registerRouteResultReceiver
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.ui.FlatItemAction
+import com.artemchep.keyguard.ui.icons.ChevronIcon
import com.artemchep.keyguard.ui.icons.KeyguardCipherFilter
import com.artemchep.keyguard.ui.icons.KeyguardWordlist
import com.artemchep.keyguard.ui.icons.icon
+import com.artemchep.keyguard.ui.icons.iconSmall
object CipherFilterUtil {
context(RememberStateFlowScope)
@@ -92,3 +97,8 @@ object CipherFilterUtil {
navigate(intent)
}
}
+
+context(RememberStateFlowScope)
+expect fun CipherFilterUtil.addShortcutActionOrNull(
+ filter: DCipherFilter,
+): FlatItemAction?
diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/view/CipherFilterViewStateProducer.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/view/CipherFilterViewStateProducer.kt
index 3e6dd29..cb21166 100644
--- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/view/CipherFilterViewStateProducer.kt
+++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/filter/view/CipherFilterViewStateProducer.kt
@@ -20,6 +20,7 @@ import com.artemchep.keyguard.common.usecase.GetOrganizations
import com.artemchep.keyguard.common.usecase.GetProfiles
import com.artemchep.keyguard.common.util.flow.foldAsList
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.screen.FilterSection
import com.artemchep.keyguard.feature.navigation.state.navigatePopSelf
@@ -264,6 +265,11 @@ fun produceCipherFilterViewState(
filter
?: return@run persistentListOf()
buildContextItems {
+ section {
+ this += CipherFilterUtil.addShortcutActionOrNull(
+ filter = filter,
+ )
+ }
section {
this += FlatItemAction(
icon = Icons.Outlined.Edit,
diff --git a/common/src/commonMain/resources/MR/base/strings.xml b/common/src/commonMain/resources/MR/base/strings.xml
index 83f38f6..2ea9e28 100644
--- a/common/src/commonMain/resources/MR/base/strings.xml
+++ b/common/src/commonMain/resources/MR/base/strings.xml
@@ -142,6 +142,7 @@
Ignored alerts
API key
Domain
+ Add to Home screen
Edit
Delete
Remove
diff --git a/common/src/desktopMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.desktop.kt b/common/src/desktopMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.desktop.kt
new file mode 100644
index 0000000..a8a198a
--- /dev/null
+++ b/common/src/desktopMain/kotlin/com/artemchep/keyguard/feature/filter/util/CipherFilterUtil.desktop.kt
@@ -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