diff --git a/.changeset/famous-pumas-argue.md b/.changeset/famous-pumas-argue.md new file mode 100644 index 00000000..906bcc9f --- /dev/null +++ b/.changeset/famous-pumas-argue.md @@ -0,0 +1,5 @@ +--- +'@capawesome/capacitor-app-shortcuts': minor +--- + +feat(app-shortcuts): add support for icon and description diff --git a/packages/app-shortcuts/README.md b/packages/app-shortcuts/README.md index 6403dada..bdf58537 100644 --- a/packages/app-shortcuts/README.md +++ b/packages/app-shortcuts/README.md @@ -193,18 +193,19 @@ Remove all listeners for this plugin. #### Shortcut -| Prop | Type | Description | Since | -| ----------------- | ------------------- | ------------------------------------------- | ----- | -| **`description`** | string | The description. Only available on Android. | 6.0.0 | -| **`id`** | string | The unique identifier. | 6.0.0 | -| **`title`** | string | The display name. | 6.0.0 | +| Prop | Type | Description | Since | +| ----------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | +| **`description`** | string | The description. On **Android**, the launcher shows this instead of the short title when it has enough space. **Attention**: On **iOS**, the icon and the description must be used together. | 6.0.0 | +| **`id`** | string | The unique identifier. | 6.0.0 | +| **`title`** | string | The display name. | 6.0.0 | +| **`icon`** | number | The icon to display. On **Android**, the icon is the constant value of the `R.drawable` enum. On **iOS**, the icon is the constant value of the `UIApplicationShortcutIcon.IconType` enum. **Attention**: On **iOS**, the icon and the description must be used together. | 6.1.0 | #### SetOptions -| Prop | Type | Description | Since | -| --------------- | ----------------------- | ------------------------- | ----- | -| **`shortcuts`** | Shortcut[] | Th list of app shortcuts. | 6.0.0 | +| Prop | Type | Description | Since | +| --------------- | ----------------------- | -------------------------- | ----- | +| **`shortcuts`** | Shortcut[] | The list of app shortcuts. | 6.0.0 | #### PluginListenerHandle diff --git a/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/AppShortcutsHelper.java b/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/AppShortcutsHelper.java index a69114d7..f0bf59e3 100644 --- a/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/AppShortcutsHelper.java +++ b/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/AppShortcutsHelper.java @@ -9,12 +9,12 @@ public class AppShortcutsHelper { @NonNull - public static HashMap createHashMapFromJSONObject(@NonNull JSONObject object) throws JSONException { - HashMap map = new HashMap<>(); + public static HashMap createHashMapFromJSONObject(@NonNull JSONObject object) throws JSONException { + HashMap map = new HashMap<>(); Iterator keys = object.keys(); while (keys.hasNext()) { String key = keys.next(); - map.put(key, (String) object.get(key)); + map.put(key, object.get(key)); } return map; } diff --git a/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/classes/options/SetOptions.java b/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/classes/options/SetOptions.java index c5fba513..62ad52d5 100644 --- a/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/classes/options/SetOptions.java +++ b/packages/app-shortcuts/android/src/main/java/io/capawesome/capacitorjs/plugins/appshortcuts/classes/options/SetOptions.java @@ -4,6 +4,7 @@ import android.content.Intent; import androidx.annotation.NonNull; import androidx.core.content.pm.ShortcutInfoCompat; +import androidx.core.graphics.drawable.IconCompat; import com.getcapacitor.Bridge; import com.getcapacitor.JSArray; import com.getcapacitor.PluginCall; @@ -35,26 +36,31 @@ private List createShortcutInfoCompatList(JSArray shortcuts, ArrayList shortcutInfoCompatList = new ArrayList<>(); List shortcutsList = shortcuts.toList(); for (JSONObject shortcut : shortcutsList) { - HashMap shortcutMap = AppShortcutsHelper.createHashMapFromJSONObject(shortcut); - String id = shortcutMap.get("id"); + HashMap shortcutMap = AppShortcutsHelper.createHashMapFromJSONObject(shortcut); + Object id = shortcutMap.get("id"); if (id == null) { throw new Exception(AppShortcutsPlugin.ERROR_ID_MISSING); } - String title = shortcutMap.get("title"); + Object title = shortcutMap.get("title"); if (title == null) { throw new Exception(AppShortcutsPlugin.ERROR_TITLE_MISSING); } - String description = shortcutMap.get("description"); + String description = (String) shortcutMap.get("description"); + Object icon = shortcutMap.get("icon"); - ShortcutInfoCompat.Builder shortcutInfoCompat = new ShortcutInfoCompat.Builder(context, id); - shortcutInfoCompat.setShortLabel(title); + ShortcutInfoCompat.Builder shortcutInfoCompat = new ShortcutInfoCompat.Builder(context, (String) id); + shortcutInfoCompat.setShortLabel((String) title); if (description != null) { shortcutInfoCompat.setLongLabel(description); } shortcutInfoCompat.setIntent( new Intent(Intent.ACTION_VIEW, bridge.getIntentUri(), bridge.getContext(), bridge.getActivity().getClass()) - .putExtra(AppShortcutsPlugin.INTENT_EXTRA_ITEM_NAME, id) + .putExtra(AppShortcutsPlugin.INTENT_EXTRA_ITEM_NAME, (String) id) ); + if (icon != null) { + shortcutInfoCompat.setIcon(IconCompat.createWithResource(context, (int) icon)); + } + shortcutInfoCompatList.add(shortcutInfoCompat.build()); } return shortcutInfoCompatList; diff --git a/packages/app-shortcuts/example/src/js/script.js b/packages/app-shortcuts/example/src/js/script.js index bea4e832..011468c6 100644 --- a/packages/app-shortcuts/example/src/js/script.js +++ b/packages/app-shortcuts/example/src/js/script.js @@ -1,4 +1,5 @@ import { AppShortcuts } from '@capawesome/capacitor-app-shortcuts'; +import { Capacitor } from '@capacitor/core'; document.addEventListener('DOMContentLoaded', () => { const initialize = async () => { @@ -23,6 +24,7 @@ document.addEventListener('DOMContentLoaded', () => { description: 'Let us know how we can improve', id: 'feedback', title: 'Feedback', + icon: Capacitor.getPlatform() === 'ios' ? 6 : 17301547, }, ], }); diff --git a/packages/app-shortcuts/ios/Plugin/Classes/Options/SetOptions.swift b/packages/app-shortcuts/ios/Plugin/Classes/Options/SetOptions.swift index 625f0aec..0ac1b242 100644 --- a/packages/app-shortcuts/ios/Plugin/Classes/Options/SetOptions.swift +++ b/packages/app-shortcuts/ios/Plugin/Classes/Options/SetOptions.swift @@ -23,7 +23,18 @@ import Capacitor guard let title = shortcut["title"] as? String, !title.isEmpty else { throw CustomError.titleMissing } - return UIApplicationShortcutItem(type: type, localizedTitle: title) + let description = shortcut["description"] as? String + let icon = shortcut["icon"] as? Int + + if description != nil && icon != nil { + if let iconType = UIApplicationShortcutIcon.IconType(rawValue: icon!) { + return UIApplicationShortcutItem(type: type, localizedTitle: title, localizedSubtitle: description, icon: UIApplicationShortcutIcon(type: iconType)) + } else { + return UIApplicationShortcutItem(type: type, localizedTitle: title) + } + } else { + return UIApplicationShortcutItem(type: type, localizedTitle: title) + } } } } diff --git a/packages/app-shortcuts/src/definitions.ts b/packages/app-shortcuts/src/definitions.ts index 30f1f19c..396f767c 100644 --- a/packages/app-shortcuts/src/definitions.ts +++ b/packages/app-shortcuts/src/definitions.ts @@ -61,7 +61,7 @@ export interface GetResult { */ export interface SetOptions { /** - * Th list of app shortcuts. + * The list of app shortcuts. * * @since 6.0.0 */ @@ -75,7 +75,9 @@ export interface Shortcut { /** * The description. * - * Only available on Android. + * On **Android**, the launcher shows this instead of the short title when it has enough space. + * + * **Attention**: On **iOS**, the icon and the description must be used together. * * @since 6.0.0 */ @@ -92,6 +94,22 @@ export interface Shortcut { * @since 6.0.0 */ title: string; + /** + * The icon to display. + * + * On **Android**, the icon is the constant value of the `R.drawable` enum. + * + * On **iOS**, the icon is the constant value of the `UIApplicationShortcutIcon.IconType` enum. + * + * **Attention**: On **iOS**, the icon and the description must be used together. + * + * @since 6.1.0 + * @example 17301547 + * @example 6 + * @see https://developer.android.com/reference/android/R.drawable + * @see https://developer.apple.com/documentation/uikit/uiapplicationshortcuticon/icontype + */ + icon?: number; } /**