Skip to content

Commit

Permalink
Merge pull request #21 from ngthailam/enhance/9/refactor_shortcut_arg
Browse files Browse the repository at this point in the history
[Enhancement#9] Refactor ShortcutArg + Update README.md accordingly
  • Loading branch information
ngthailam authored May 21, 2022
2 parents 2a33d0e + a07c2fe commit b6233e6
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 97 deletions.
57 changes: 37 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ A plugin to implement Android native App shortcut and IOS quick actions
# Getting Started



## Where to get it?
Go to the plugin official pub.dev page to install
Go to the plugin official [pub.dev](https://pub.dev/packages/flutter_app_shortcut) page to install

<br>

Expand All @@ -22,14 +21,27 @@ Review [this](/example/lib/main.dart) file to get full example usages

## Arguments

| Name | Value | Requirements | Description | IOS | Android |
| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
| id | String | Unique | When pushing shortcuts with the same ID, the existing one is updated | Yes | Yes |
| shortLabel | String | Not empty | App short cut label (title) | Yes | Yes |
| longLabel | String | | App short cut label when there is a lot of space, in IOS, it will be a subtitle instead | Yes | Yes |
| iconResourceName | String | | Icon resource name (see below for usage) | Yes | Yes |
| uri | String | |Uri when click on shortcut | No | No |
| enabled | boolean | | If enabled == false, user cannot interact with app shortcut | No | No |
### ShortcutArg
| Name | Type | Requirements | Description |
| ------------- | ------------- | ------------- | ------------- |
| id | String | Unique | When pushing shortcuts with the same ID, the existing one is updated |
| title | String | Not empty | App short cut label (title) |
| iconResourceName | String | | Icon resource name (see below for usage) |
| androidArg | AndroidArg | | Extra arguments for Android shortcuts |
| iosArg | IosArg | | Extra arguments for IOS shortcuts |

### AndroidArg
| Name | Type | Requirements | Description |
| ------------- | ------------- | ------------- | ------------- |
| longLabel | String | | if there is enough space on the device, longLabel replaces title |
| uri | String | |Uri when click on shortcut |

<br>

### IosArg
| Name | Type | Requirements | Description |
| ------------- | ------------- | ------------- | ------------- |
| subtitle | String | | Subtitle of the shortcut |

<br>

Expand All @@ -42,11 +54,12 @@ Add a new shortcut
FlutterAppShortcut().push(
ShortcutArg(
id: 'id_1',
shortLabel: 'Home page',
longLabel: 'Go to Home page',
title: 'Home page',
iconResourceName: 'ic_android_black',
uri: 'https://www.google.com',
enabled: true,
androidArg: AndroidArg(
longLabel: 'Go to Home page',
uri: 'https://www.google.com',
)
);
)
```
Expand All @@ -60,9 +73,9 @@ Add a new icon
FlutterAppShortcut().push(
ShortcutArg(
id: 'id_1',
shortLabel: 'Home page',
longLabel: 'Subtitle' // in IOS longLabel serves as subtitle instead
iconResourceName: 'register'
title: 'Home page',
iconResourceName: 'register',
iosArg: IosArg(subtitle: "My subtitle),
);
)
```
Expand All @@ -76,11 +89,15 @@ Add a new icon

## Android
- Pinned shortcut cannot be removed, only disabled
- Shortcut after disabled cannot be enabled, however, pinned shortcut can
- Cannot return icon name when cal getShortcuts
- Cannot set disabled message (will implement in the future)
- Cannot use icon from flutter side (will implement in the future)
- On click short cut does nothing
## IOS
- On IOS, enable and disable shortcuts is not available
- Cannot return icon name when cal getShortcuts
- Does no support disable, enable icons
- Cannot use icon from flutter side (will implement in the future)
- On click short cut does nothing
<br><br>
Expand All @@ -89,13 +106,13 @@ Add a new icon
- [x] Reseach + Implement for IOS side
## Android
- [ ] Allow add disabled message to disabled shortcuts
- [ ] Implement get shortcuts
- [x] Implement get shortcuts
- [ ] Allow icon from flutter side
- [ ] Enable destination on click shortcut
- [ ] Provide accurate errors
## IOS
- [ ] Allow set subtitle
- [ ] Allow set icon
- [x] Allow set subtitle
- [x] Allow set icon
- [ ] Allow icon from flutter side
- [ ] Enable destination on click shortcut
- [ ] Provide accurate errors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class FlutterAppShortcutPlugin : FlutterPlugin, MethodCallHandler {
"getAllShortcuts" -> {
return try {
val shortcuts = ShortcutManagerCompat.getDynamicShortcuts(applicationContext!!)
result.success(shortcuts.associate { it.id to ShortcutArg.fromInfoCompat(it) })
result.success(shortcuts.associate { it.id to ShortcutArg.fromInfoCompat(it).toMap() })
} catch (t: Throwable) {
result.error("getAllShortcuts", t.message, args)
}
Expand All @@ -59,8 +59,8 @@ class FlutterAppShortcutPlugin : FlutterPlugin, MethodCallHandler {
}
"enableShortcuts" -> {
return try {
val enabledIds = args?.toList()
?.map { entry -> entry.first } ?: return result.error("enableShortcut", "Invalid args=$args", args)
val enabledIds = args?.toList()?.map { entry -> entry.first }
?: return result.error("enableShortcut", "Invalid args=$args", args)
val shortcutsDynamic = ShortcutManagerCompat.getShortcuts(applicationContext!!, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC)
val shortcutsCached = ShortcutManagerCompat.getShortcuts(applicationContext!!, ShortcutManagerCompat.FLAG_MATCH_CACHED)
val shortcutsPinned = ShortcutManagerCompat.getShortcuts(applicationContext!!, ShortcutManagerCompat.FLAG_MATCH_PINNED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ data class ShortcutArg(
val iconResourceName: String = "",
val uri: String = "",
) {
fun toMap(): Map<String, Any> {
return mapOf(
"id" to id,
"title" to shortLabel,
"iconResourceName" to iconResourceName,
"androidArg" to mapOf<String, Any>(
"longLabel" to longLabel,
"uri" to uri
)
)
}

companion object {
fun fromInfoCompat(infoCompat: ShortcutInfoCompat): ShortcutArg {
return ShortcutArg(
Expand All @@ -22,13 +34,13 @@ data class ShortcutArg(
}

fun fromHashMap(map: Map<String, Any>): ShortcutArg {
val shortLabel = map["shortLabel"] as String;
val androidArg = map["androidArg"] as Map<String, Any>
return ShortcutArg(
id = map["id"] as String,
shortLabel = shortLabel,
longLabel = map["longLabel"] as String,
shortLabel = map["title"] as String,
longLabel = androidArg["longLabel"] as String,
iconResourceName = map["iconResourceName"] as String,
uri = map["uri"] as String
uri = androidArg["uri"] as String
)
}
}
Expand Down
79 changes: 51 additions & 28 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
Expand Down Expand Up @@ -61,7 +62,6 @@ class _MyAppState extends State<MyApp> {
return Container(
margin:
const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
color: item.enabled ? Colors.blueAccent : Colors.grey,
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: Column(
Expand All @@ -81,10 +81,11 @@ class _MyAppState extends State<MyApp> {

ShortcutArg _randomShortcut() => ShortcutArg(
id: getRandomString(5),
shortLabel: getRandomString(10),
iconResourceName: 'register',
uri: 'https://www.google.com',
);
title: getRandomString(10),
iconResourceName: 'ic_android_black',
androidArg: AndroidArg(
uri: 'https://www.google.com', longLabel: "Very long label"),
iosArg: IosArg(subtitle: 'my subtitle'));

Widget _getAllBtn() {
return Builder(builder: (context) {
Expand All @@ -97,9 +98,7 @@ class _MyAppState extends State<MyApp> {
text += "id=" + element.id + "|";
}
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(content: Text(text))
);
.showSnackBar(SnackBar(content: Text(text)));
},
child: const Text('Get current shortcuts'));
});
Expand Down Expand Up @@ -157,28 +156,52 @@ class _MyAppState extends State<MyApp> {
}

Widget _enableBtn() {
return TextButton(
onPressed: () async {
await flutterAppShortcut
.enableShortcuts(_shortcuts.map((e) => e.id).toList());
setState(() {
_shortcuts =
_shortcuts.map((e) => e.copyWith(enabled: true)).toList();
});
},
child: const Text('Enable shortcut'));
return Builder(
builder: (ctx) => TextButton(
onPressed: () async {
if (_isIos(ctx)) {
return;
}
await flutterAppShortcut
.enableShortcuts(_shortcuts.map((e) => e.id).toList());
setState(() {
_shortcuts = _shortcuts
.map((e) => e.copyWith(
androidArg: e.androidArg?.copyWith(enabled: true)))
.toList();
});
},
child: const Text('Enable shortcut')),
);
}

bool _isIos(BuildContext context) {
if (Platform.isIOS) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Function on available on IOS')));
return true;
}

return false;
}

Widget _disableBtn() {
return TextButton(
onPressed: () async {
await flutterAppShortcut
.disableShortcuts(_shortcuts.map((e) => e.id).toList());
setState(() {
_shortcuts =
_shortcuts.map((e) => e.copyWith(enabled: false)).toList();
});
},
child: const Text('Disable shortcut'));
return Builder(
builder: (ctx) => TextButton(
onPressed: () async {
if (_isIos(ctx)) {
return;
}
await flutterAppShortcut
.disableShortcuts(_shortcuts.map((e) => e.id).toList());
setState(() {
_shortcuts = _shortcuts
.map((e) => e.copyWith(
androidArg: e.androidArg?.copyWith(enabled: false)))
.toList();
});
},
child: const Text('Disable shortcut')),
);
}
}
16 changes: 12 additions & 4 deletions ios/Classes/SwiftFlutterAppShortcutPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ struct ShortcutArg {

init(dict: Dictionary<String, Any>) {
self.id = dict["id"] as? String ?? ""
self.title = dict["shortLabel"] as? String ?? ""
self.subtitle = dict["longLabel"] as? String ?? ""
self.title = dict["title"] as? String ?? ""
self.icon = dict["iconResourceName"] as? String ?? ""
// Set subtitle
var subtitle: String = ""
if let iosArg = dict["iosArg"] as? [String: Any] {
subtitle = iosArg["subtitle"] as? String ?? ""
}
self.subtitle = subtitle
}
}

Expand Down Expand Up @@ -78,12 +83,15 @@ public class SwiftFlutterAppShortcutPlugin: NSObject, FlutterPlugin {
}

private func getAllShortcuts(call: FlutterMethodCall, result: FlutterResult) {
var shortcutItems = UIApplication.shared.shortcutItems ?? []
let shortcutItems = UIApplication.shared.shortcutItems ?? []
var resultDict = [String: Any]()
for (_, item) in shortcutItems.enumerated() {
resultDict[item.type] = [
"id": item.type,
"shortLabel": item.localizedTitle,
"title": item.localizedTitle,
"iosArg": [
"subtitle": item.localizedSubtitle
]
]
}

Expand Down
Loading

0 comments on commit b6233e6

Please sign in to comment.