expo-invoke 2.6.11 → 2.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -1
- package/android/src/main/java/expo/modules/invoke/ExpoInvokeModule.kt +21 -14
- package/build/plugin/codegen/generateShortcutsXml.js +5 -0
- package/build/plugin/codegen/generateShortcutsXml.js.map +1 -1
- package/build/plugin/codegen/generateSwiftWidget.d.ts +10 -0
- package/build/plugin/codegen/generateSwiftWidget.js +10 -10
- package/build/plugin/codegen/generateSwiftWidget.js.map +1 -1
- package/build/plugin/ios/withIOSInvoke.d.ts +10 -0
- package/build/plugin/ios/withIOSInvoke.js +6 -1
- package/build/plugin/ios/withIOSInvoke.js.map +1 -1
- package/build/plugin/src/withInvoke.d.ts +10 -0
- package/build/plugin/src/withInvoke.js +24 -1
- package/build/plugin/src/withInvoke.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -140,6 +140,8 @@ eas build --platform android --local
|
|
|
140
140
|
"enableWidget": true,
|
|
141
141
|
"widgetTitle": "My App",
|
|
142
142
|
"widgetAccentColor": "#267AD9",
|
|
143
|
+
"widgetBgColor": "#E6F4FF",
|
|
144
|
+
"widgetIcon": "square.grid.2x2.fill",
|
|
143
145
|
"widgetDeepLink": "myapp://home",
|
|
144
146
|
"widgetSizes": ["small", "medium"],
|
|
145
147
|
|
|
@@ -359,6 +361,11 @@ expo-invoke includes a **zero-native-code** WidgetKit extension. Enable it in `a
|
|
|
359
361
|
"widgetDescription": "Quick access from your home screen.",
|
|
360
362
|
"widgetDataKey": "myWidgetData",
|
|
361
363
|
"widgetAccentColor": "#267AD9",
|
|
364
|
+
"widgetBgColor": "#E6F4FF",
|
|
365
|
+
"widgetIcon": "square.grid.2x2.fill",
|
|
366
|
+
"widgetDetailIcon": "person.fill",
|
|
367
|
+
"widgetEmptyText": "Nothing here yet",
|
|
368
|
+
"widgetRefreshMinutes": 15,
|
|
362
369
|
"widgetDeepLink": "myapp://home",
|
|
363
370
|
"widgetSizes": ["small", "medium", "large"],
|
|
364
371
|
|
|
@@ -368,6 +375,24 @@ expo-invoke includes a **zero-native-code** WidgetKit extension. Enable it in `a
|
|
|
368
375
|
|
|
369
376
|
> `appGroupId` is required for widget data sharing — the app and the widget extension read/write the same UserDefaults container.
|
|
370
377
|
|
|
378
|
+
**Widget configuration reference:**
|
|
379
|
+
|
|
380
|
+
| Option | Type | Default | Description |
|
|
381
|
+
|---|---|---|---|
|
|
382
|
+
| `enableWidget` | `boolean` | `false` | Enable the built-in WidgetKit extension |
|
|
383
|
+
| `appGroupId` | `string` | — | **Required.** App Group shared between app and widget. Must start with `group.` |
|
|
384
|
+
| `widgetTitle` | `string` | App name | Display name shown in the iOS widget picker |
|
|
385
|
+
| `widgetDescription` | `string` | `"Quick access from your home screen."` | Description shown in the widget picker |
|
|
386
|
+
| `widgetDataKey` | `string` | `"invokeWidgetData"` | UserDefaults key to read widget data from — must match your `setWidgetData()` call |
|
|
387
|
+
| `widgetAccentColor` | `string` | `"#267AD9"` | Hex accent color used for count, icon, and badge (e.g. `"#3B82F6"`) |
|
|
388
|
+
| `widgetBgColor` | `string` | `"#E6F4FF"` | Hex background color for all widget sizes (e.g. `"#EFF6FF"`) |
|
|
389
|
+
| `widgetIcon` | `string` | `"square.grid.2x2.fill"` | SF Symbol name for the main widget icon (e.g. `"bag.fill"`, `"car.fill"`) |
|
|
390
|
+
| `widgetDetailIcon` | `string` | `"person.fill"` | SF Symbol name for detail rows — assignee, carrier, etc. |
|
|
391
|
+
| `widgetEmptyText` | `string` | `"Nothing here yet"` | Text shown in the large widget when there is no data |
|
|
392
|
+
| `widgetRefreshMinutes` | `number` | `15` | How often (in minutes) the widget timeline refreshes. Must be 1–60. |
|
|
393
|
+
| `widgetDeepLink` | `string` | `""` | URL scheme opened when the widget is tapped (e.g. `"myapp://home"`) |
|
|
394
|
+
| `widgetSizes` | `string[]` | `["small","medium"]` | Sizes to generate: `"small"`, `"medium"`, `"large"` |
|
|
395
|
+
|
|
371
396
|
#### 2. Push data from TypeScript
|
|
372
397
|
|
|
373
398
|
```tsx
|
|
@@ -402,7 +427,35 @@ function syncWidget(activeItems: MyItem[]) {
|
|
|
402
427
|
| `detail` | `string \| null` | Extra detail (e.g. assignee name) |
|
|
403
428
|
| `deepLink` | `string \| null` | Optional per-item deep-link URL override |
|
|
404
429
|
|
|
405
|
-
#### 3.
|
|
430
|
+
#### 3. Fix the splash screen for widget launches
|
|
431
|
+
|
|
432
|
+
> **Common gotcha — app freezes on widget tap**
|
|
433
|
+
>
|
|
434
|
+
> If you use `NativeSplash.preventAutoHideAsync()`, add a `hideAsync()` call in your **root `_layout.tsx`** — not just in `index.tsx`.
|
|
435
|
+
> When the app opens from a widget tap, Expo Router routes directly to the deep-link destination screen. `index.tsx` is never mounted, so any `hideAsync()` call inside it is never reached. The native splash stays on screen forever.
|
|
436
|
+
>
|
|
437
|
+
> Calling `hideAsync()` twice (once in `_layout.tsx` and once in `index.tsx`) is safe — the second call is a no-op.
|
|
438
|
+
|
|
439
|
+
```tsx
|
|
440
|
+
// app/_layout.tsx
|
|
441
|
+
import * as NativeSplash from 'expo-splash-screen';
|
|
442
|
+
NativeSplash.preventAutoHideAsync().catch(() => {});
|
|
443
|
+
|
|
444
|
+
export default function RootLayout() {
|
|
445
|
+
React.useEffect(() => {
|
|
446
|
+
NativeSplash.hideAsync().catch(() => {}); // always fires — covers widget/deep-link entry
|
|
447
|
+
}, []);
|
|
448
|
+
return <Stack />;
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Also make sure `widgetDeepLink` points to a **real route** in your app. In Expo Router, group folders like `(tabs)` are transparent in URLs:
|
|
453
|
+
- `app/(tabs)/orders.tsx` → `myapp://orders` ✓
|
|
454
|
+
- `myapp://errands` with no `app/errands.tsx` → 404 screen ✗
|
|
455
|
+
|
|
456
|
+
Test the deep link before shipping: `xcrun simctl openurl booted "myapp://your/path"`
|
|
457
|
+
|
|
458
|
+
#### 4. Prebuild + run
|
|
406
459
|
|
|
407
460
|
```bash
|
|
408
461
|
npx expo prebuild --platform ios --clean
|
|
@@ -414,6 +467,7 @@ The widget is generated entirely by the plugin — `InvokeWidget.swift` is writt
|
|
|
414
467
|
**Testing in the simulator:**
|
|
415
468
|
- Long-press the home screen → tap **+** → search "My App"
|
|
416
469
|
- Choose small, medium, or large size
|
|
470
|
+
- Tap the widget — verify the app opens to the correct screen without freezing
|
|
417
471
|
- Long-press the app icon for Quick Action shortcuts
|
|
418
472
|
|
|
419
473
|
---
|
|
@@ -15,8 +15,10 @@ private const val DEFAULT_TTL_MS = 30_000L
|
|
|
15
15
|
|
|
16
16
|
class ExpoInvokeModule : Module() {
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Nullable — reactContext is unavailable during background wakeup or after process death.
|
|
19
|
+
// Every caller must handle the null case rather than crashing.
|
|
20
|
+
private val prefs: SharedPreferences?
|
|
21
|
+
get() = appContext.reactContext?.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
20
22
|
|
|
21
23
|
override fun definition() = ModuleDefinition {
|
|
22
24
|
Name("ExpoInvoke")
|
|
@@ -25,12 +27,12 @@ class ExpoInvokeModule : Module() {
|
|
|
25
27
|
|
|
26
28
|
// ── configure ────────────────────────────────────────────────────────────
|
|
27
29
|
Function("configure") { configJson: String ->
|
|
28
|
-
prefs
|
|
30
|
+
prefs?.edit()?.putString(KEY_CONFIG, configJson)?.apply()
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
// ── getInitialIntent ─────────────────────────────────────────────────────
|
|
32
34
|
Function("getInitialIntent") {
|
|
33
|
-
consumePendingIntent(
|
|
35
|
+
prefs?.let { consumePendingIntent(it) }
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// ── Donations (no-op on Android — Google handles via App Actions) ────────
|
|
@@ -40,17 +42,19 @@ class ExpoInvokeModule : Module() {
|
|
|
40
42
|
|
|
41
43
|
// ── Dynamic shortcuts ─────────────────────────────────────────────────────
|
|
42
44
|
Function("setDynamicShortcuts") { json: String ->
|
|
43
|
-
prefs
|
|
44
|
-
|
|
45
|
+
prefs?.edit()?.putString(KEY_SHORTCUTS, json)?.apply()
|
|
46
|
+
val ctx = appContext.reactContext ?: return@Function Unit
|
|
47
|
+
ShortcutsHelper.setDynamicShortcuts(ctx, json)
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
Function("getDynamicShortcuts") {
|
|
48
|
-
prefs
|
|
51
|
+
prefs?.getString(KEY_SHORTCUTS, "[]") ?: "[]"
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
Function("clearDynamicShortcuts") {
|
|
52
|
-
prefs
|
|
53
|
-
|
|
55
|
+
prefs?.edit()?.remove(KEY_SHORTCUTS)?.apply()
|
|
56
|
+
val ctx = appContext.reactContext ?: return@Function Unit
|
|
57
|
+
ShortcutsHelper.clearDynamicShortcuts(ctx)
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
// ── Spotlight — no-op on Android ─────────────────────────────────────────
|
|
@@ -59,18 +63,19 @@ class ExpoInvokeModule : Module() {
|
|
|
59
63
|
|
|
60
64
|
// ── Widget data (SharedPreferences — readable by AppWidgetProvider) ──────
|
|
61
65
|
Function("setWidgetData") { key: String, value: String ->
|
|
62
|
-
prefs
|
|
66
|
+
prefs?.edit()?.putString("widget.$key", value)?.apply()
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
Function("getWidgetData") { key: String ->
|
|
66
|
-
prefs
|
|
70
|
+
prefs?.getString("widget.$key", null)
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
// ── Quick tile ────────────────────────────────────────────────────────────
|
|
70
74
|
Function("updateQuickTile") { state: String, label: String ->
|
|
71
75
|
QuickTileService.pendingState = state
|
|
72
76
|
QuickTileService.pendingLabel = label
|
|
73
|
-
|
|
77
|
+
val ctx = appContext.reactContext ?: return@Function Unit
|
|
78
|
+
QuickTileService.requestUpdate(ctx)
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
// ── Handoff — no-op on Android ────────────────────────────────────────────
|
|
@@ -88,13 +93,15 @@ class ExpoInvokeModule : Module() {
|
|
|
88
93
|
|
|
89
94
|
// ── Warm start ────────────────────────────────────────────────────────────
|
|
90
95
|
OnActivityEntersForeground {
|
|
91
|
-
val
|
|
96
|
+
val p = prefs ?: return@OnActivityEntersForeground
|
|
97
|
+
val json = consumePendingIntent(p) ?: return@OnActivityEntersForeground
|
|
92
98
|
sendEvent("onIntent", mapOf("json" to json))
|
|
93
99
|
}
|
|
94
100
|
|
|
95
101
|
// ── New intent (App Actions / deep links fire here) ───────────────────────
|
|
96
102
|
OnNewIntent { intent ->
|
|
97
|
-
val
|
|
103
|
+
val p = prefs ?: return@OnNewIntent
|
|
104
|
+
val json = AppActionsHandler.handleIntent(intent, p) ?: return@OnNewIntent
|
|
98
105
|
sendEvent("onIntent", mapOf("json" to json))
|
|
99
106
|
}
|
|
100
107
|
}
|
|
@@ -16,6 +16,11 @@ function generateShortcutsXml(intents, packageName) {
|
|
|
16
16
|
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" />
|
|
17
17
|
`;
|
|
18
18
|
}
|
|
19
|
+
if (shortcutIntents.length > 5) {
|
|
20
|
+
console.warn(`[expo-invoke] Android only supports 5 static shortcuts. ` +
|
|
21
|
+
`You have ${shortcutIntents.length} intents with shortTitle — ` +
|
|
22
|
+
`only the first 5 will be included. Remove shortTitle from lower-priority intents.`);
|
|
23
|
+
}
|
|
19
24
|
const items = shortcutIntents.slice(0, 5).map((intent, idx) => {
|
|
20
25
|
var _a;
|
|
21
26
|
const rank = idx + 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateShortcutsXml.js","sourceRoot":"","sources":["../../../plugin/codegen/generateShortcutsXml.ts"],"names":[],"mappings":";;AAUA,
|
|
1
|
+
{"version":3,"file":"generateShortcutsXml.js","sourceRoot":"","sources":["../../../plugin/codegen/generateShortcutsXml.ts"],"names":[],"mappings":";;AAUA,oDA8CC;AAtDD,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,oBAAoB,CAClC,OAA2B,EAC3B,WAAmB;IAEnB,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAE5D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;;;CAGV,CAAC;IACA,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CACV,0DAA0D;YAC1D,YAAY,eAAe,CAAC,MAAM,6BAA6B;YAC/D,mFAAmF,CACpF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;;QAC5D,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;QACrB,OAAO;0BACe,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;;kCAEZ,SAAS,CAAC,CAAC,MAAA,MAAM,CAAC,UAAU,mCAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;iCAC5D,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnD,IAAI;;wBAEA,SAAS,CAAC,WAAW,CAAC;+BACf,SAAS,CAAC,WAAW,CAAC;6BACxB,SAAS,CAAC,WAAW,CAAC;sBAC7B,SAAS,CAAC,WAAW,CAAC,aAAa,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;;cAE/D,CAAC;IACb,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;EAIP,KAAK;;;CAGN,CAAC;AACF,CAAC"}
|
|
@@ -7,6 +7,16 @@ export interface WidgetCodegenOptions {
|
|
|
7
7
|
widgetDataKey: string;
|
|
8
8
|
/** Hex accent colour, e.g. "#267AD9" */
|
|
9
9
|
widgetAccentColor: string;
|
|
10
|
+
/** Hex background colour for all widget sizes, e.g. "#E6F4FF" */
|
|
11
|
+
widgetBgColor: string;
|
|
12
|
+
/** SF Symbol name used as the main widget icon, e.g. "square.grid.2x2.fill" */
|
|
13
|
+
widgetIcon: string;
|
|
14
|
+
/** SF Symbol name used on detail rows (carrier, assignee, etc.), e.g. "person.fill" */
|
|
15
|
+
widgetDetailIcon: string;
|
|
16
|
+
/** Text shown in the large widget empty state, e.g. "Nothing here yet" */
|
|
17
|
+
widgetEmptyText: string;
|
|
18
|
+
/** How often (in minutes) the widget timeline refreshes. Defaults to 15. */
|
|
19
|
+
widgetRefreshMinutes: number;
|
|
10
20
|
/** URL scheme deep-link opened when widget is tapped, e.g. "myapp://home" */
|
|
11
21
|
widgetDeepLink: string;
|
|
12
22
|
/** iOS App Group identifier shared between app and widget */
|
|
@@ -42,9 +42,9 @@ function familiesClause(sizes) {
|
|
|
42
42
|
* }
|
|
43
43
|
*/
|
|
44
44
|
function generateSwiftWidget(opts) {
|
|
45
|
-
const { widgetTitle, widgetDescription, widgetDataKey, widgetAccentColor, widgetDeepLink, appGroupId, widgetSizes, } = opts;
|
|
45
|
+
const { widgetTitle, widgetDescription, widgetDataKey, widgetAccentColor, widgetBgColor, widgetIcon, widgetDetailIcon, widgetEmptyText, widgetRefreshMinutes, widgetDeepLink, appGroupId, widgetSizes, } = opts;
|
|
46
46
|
const accentColor = hexToSwiftColor(widgetAccentColor);
|
|
47
|
-
const bgColor =
|
|
47
|
+
const bgColor = hexToSwiftColor(widgetBgColor);
|
|
48
48
|
const families = familiesClause(widgetSizes);
|
|
49
49
|
const hasSmall = widgetSizes.includes('small');
|
|
50
50
|
const hasMedium = widgetSizes.includes('medium');
|
|
@@ -101,7 +101,7 @@ struct InvokeWidgetProvider: TimelineProvider {
|
|
|
101
101
|
|
|
102
102
|
func getTimeline(in context: Context, completion: @escaping (Timeline<InvokeWidgetEntry>) -> Void) {
|
|
103
103
|
let entry = InvokeWidgetEntry(date: Date(), data: load())
|
|
104
|
-
let refresh = Calendar.current.date(byAdding: .minute, value:
|
|
104
|
+
let refresh = Calendar.current.date(byAdding: .minute, value: ${widgetRefreshMinutes}, to: Date()) ?? Date()
|
|
105
105
|
completion(Timeline(entries: [entry], policy: .after(refresh)))
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -152,7 +152,7 @@ ${hasSmall ? `struct SmallInvokeView: View {
|
|
|
152
152
|
invokeBgColor.ignoresSafeArea()
|
|
153
153
|
VStack(alignment: .leading, spacing: 6) {
|
|
154
154
|
HStack {
|
|
155
|
-
Image(systemName: "
|
|
155
|
+
Image(systemName: "${escapeSwift(widgetIcon)}")
|
|
156
156
|
.font(.system(size: 16, weight: .semibold))
|
|
157
157
|
.foregroundStyle(invokeAccentColor)
|
|
158
158
|
Spacer()
|
|
@@ -192,7 +192,7 @@ ${hasMedium ? `struct MediumInvokeView: View {
|
|
|
192
192
|
invokeBgColor.ignoresSafeArea()
|
|
193
193
|
HStack(spacing: 0) {
|
|
194
194
|
VStack(alignment: .leading, spacing: 8) {
|
|
195
|
-
Image(systemName: "
|
|
195
|
+
Image(systemName: "${escapeSwift(widgetIcon)}")
|
|
196
196
|
.font(.system(size: 20, weight: .semibold))
|
|
197
197
|
.foregroundStyle(invokeAccentColor)
|
|
198
198
|
Text("\\(entry.data.count)")
|
|
@@ -231,7 +231,7 @@ ${hasMedium ? `struct MediumInvokeView: View {
|
|
|
231
231
|
}
|
|
232
232
|
if let detail = entry.data.detail {
|
|
233
233
|
HStack(spacing: 4) {
|
|
234
|
-
Image(systemName: "
|
|
234
|
+
Image(systemName: "${escapeSwift(widgetDetailIcon)}")
|
|
235
235
|
.font(.system(size: 9))
|
|
236
236
|
.foregroundStyle(.secondary)
|
|
237
237
|
Text(detail)
|
|
@@ -256,7 +256,7 @@ ${hasLarge ? `struct LargeInvokeView: View {
|
|
|
256
256
|
invokeBgColor.ignoresSafeArea()
|
|
257
257
|
VStack(alignment: .leading, spacing: 14) {
|
|
258
258
|
HStack {
|
|
259
|
-
Image(systemName: "
|
|
259
|
+
Image(systemName: "${escapeSwift(widgetIcon)}")
|
|
260
260
|
.font(.system(size: 18, weight: .semibold))
|
|
261
261
|
.foregroundStyle(invokeAccentColor)
|
|
262
262
|
Text("${escapeSwift(widgetTitle)}")
|
|
@@ -286,7 +286,7 @@ ${hasLarge ? `struct LargeInvokeView: View {
|
|
|
286
286
|
}
|
|
287
287
|
if let detail = entry.data.detail {
|
|
288
288
|
HStack(spacing: 6) {
|
|
289
|
-
Image(systemName: "
|
|
289
|
+
Image(systemName: "${escapeSwift(widgetDetailIcon)}")
|
|
290
290
|
.font(.system(size: 13))
|
|
291
291
|
.foregroundStyle(invokeAccentColor)
|
|
292
292
|
Text(detail)
|
|
@@ -301,10 +301,10 @@ ${hasLarge ? `struct LargeInvokeView: View {
|
|
|
301
301
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
302
302
|
} else {
|
|
303
303
|
VStack(spacing: 10) {
|
|
304
|
-
Image(systemName: "
|
|
304
|
+
Image(systemName: "${escapeSwift(widgetIcon)}")
|
|
305
305
|
.font(.system(size: 34))
|
|
306
306
|
.foregroundStyle(invokeAccentColor.opacity(0.4))
|
|
307
|
-
Text("
|
|
307
|
+
Text("${escapeSwift(widgetEmptyText)}")
|
|
308
308
|
.font(.system(size: 13))
|
|
309
309
|
.foregroundStyle(.secondary)
|
|
310
310
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateSwiftWidget.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftWidget.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generateSwiftWidget.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftWidget.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,16 @@ interface IOSInvokeOptions {
|
|
|
24
24
|
widgetDataKey?: string;
|
|
25
25
|
/** Hex accent colour for the widget UI (defaults to "#267AD9") */
|
|
26
26
|
widgetAccentColor?: string;
|
|
27
|
+
/** Hex background colour for all widget sizes (defaults to "#E6F4FF") */
|
|
28
|
+
widgetBgColor?: string;
|
|
29
|
+
/** SF Symbol name used as the main widget icon (defaults to "square.grid.2x2.fill") */
|
|
30
|
+
widgetIcon?: string;
|
|
31
|
+
/** SF Symbol name used on detail rows, e.g. carrier/assignee (defaults to "person.fill") */
|
|
32
|
+
widgetDetailIcon?: string;
|
|
33
|
+
/** Text shown in the large widget empty state (defaults to "Nothing here yet") */
|
|
34
|
+
widgetEmptyText?: string;
|
|
35
|
+
/** How often in minutes the widget timeline refreshes (defaults to 15) */
|
|
36
|
+
widgetRefreshMinutes?: number;
|
|
27
37
|
/** URL scheme deep-link opened when widget is tapped */
|
|
28
38
|
widgetDeepLink?: string;
|
|
29
39
|
/** Widget sizes to support (defaults to ["small","medium"]) */
|
|
@@ -44,7 +44,7 @@ const generateSwiftAppClip_1 = require("../codegen/generateSwiftAppClip");
|
|
|
44
44
|
const withWidgetExtension_1 = require("./withWidgetExtension");
|
|
45
45
|
const withIOSInvoke = (config, options) => {
|
|
46
46
|
var _a, _b, _c;
|
|
47
|
-
const { intents, voiceUsageDescription, appGroupId, entities = [], focusFilters = [], appClips = [], enablePushToTalk = false, pttUsageDescription, enableLiveActivities = false, enableWidget = false, widgetTitle, widgetDescription = 'Quick access from your home screen.', widgetDataKey = 'invokeWidgetData', widgetAccentColor = '#267AD9', widgetDeepLink = '', widgetSizes = ['small', 'medium'], } = options;
|
|
47
|
+
const { intents, voiceUsageDescription, appGroupId, entities = [], focusFilters = [], appClips = [], enablePushToTalk = false, pttUsageDescription, enableLiveActivities = false, enableWidget = false, widgetTitle, widgetDescription = 'Quick access from your home screen.', widgetDataKey = 'invokeWidgetData', widgetAccentColor = '#267AD9', widgetBgColor = '#E6F4FF', widgetIcon = 'square.grid.2x2.fill', widgetDetailIcon = 'person.fill', widgetEmptyText = 'Nothing here yet', widgetRefreshMinutes = 15, widgetDeepLink = '', widgetSizes = ['small', 'medium'], } = options;
|
|
48
48
|
// 1. Info.plist usage descriptions + feature flags
|
|
49
49
|
config = (0, config_plugins_1.withInfoPlist)(config, (cfg) => {
|
|
50
50
|
var _a;
|
|
@@ -145,6 +145,11 @@ const withIOSInvoke = (config, options) => {
|
|
|
145
145
|
widgetDescription,
|
|
146
146
|
widgetDataKey,
|
|
147
147
|
widgetAccentColor,
|
|
148
|
+
widgetBgColor,
|
|
149
|
+
widgetIcon,
|
|
150
|
+
widgetDetailIcon,
|
|
151
|
+
widgetEmptyText,
|
|
152
|
+
widgetRefreshMinutes,
|
|
148
153
|
widgetDeepLink,
|
|
149
154
|
widgetSizes,
|
|
150
155
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withIOSInvoke.js","sourceRoot":"","sources":["../../../plugin/ios/withIOSInvoke.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yDAK8B;AAC9B,uCAAyB;AACzB,2CAA6B;AAC7B,0EAAuE;AACvE,4EAAyE;AACzE,oFAAiF;AACjF,0EAAuE;AACvE,+DAA4D;
|
|
1
|
+
{"version":3,"file":"withIOSInvoke.js","sourceRoot":"","sources":["../../../plugin/ios/withIOSInvoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,16 @@ export interface InvokePluginOptions {
|
|
|
49
49
|
widgetDataKey?: string;
|
|
50
50
|
/** Hex accent colour for widget UI (defaults to "#267AD9") */
|
|
51
51
|
widgetAccentColor?: string;
|
|
52
|
+
/** Hex background colour for all widget sizes (defaults to "#E6F4FF") */
|
|
53
|
+
widgetBgColor?: string;
|
|
54
|
+
/** SF Symbol name used as the main widget icon (defaults to "square.grid.2x2.fill") */
|
|
55
|
+
widgetIcon?: string;
|
|
56
|
+
/** SF Symbol name used on detail rows, e.g. carrier/assignee (defaults to "person.fill") */
|
|
57
|
+
widgetDetailIcon?: string;
|
|
58
|
+
/** Text shown in the large widget empty state (defaults to "Nothing here yet") */
|
|
59
|
+
widgetEmptyText?: string;
|
|
60
|
+
/** How often in minutes the widget timeline refreshes (defaults to 15) */
|
|
61
|
+
widgetRefreshMinutes?: number;
|
|
52
62
|
/** URL scheme deep-link opened when the widget is tapped (e.g. "myapp://home") */
|
|
53
63
|
widgetDeepLink?: string;
|
|
54
64
|
/** Widget sizes to generate. Defaults to ["small", "medium"] */
|
|
@@ -4,8 +4,14 @@ const config_plugins_1 = require("@expo/config-plugins");
|
|
|
4
4
|
const withIOSInvoke_1 = require("../ios/withIOSInvoke");
|
|
5
5
|
const withAndroidInvoke_1 = require("../android/withAndroidInvoke");
|
|
6
6
|
const validation_1 = require("../../src/utils/validation");
|
|
7
|
+
function assertHex(value, optionName) {
|
|
8
|
+
if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {
|
|
9
|
+
throw new Error(`[expo-invoke] ${optionName} must be a 6-digit hex color (e.g. "#3B82F6"), got "${value}".\n` +
|
|
10
|
+
`Fix: Use format "#RRGGBB" in your expo-invoke plugin config.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
7
13
|
const withInvoke = (config, options) => {
|
|
8
|
-
const { intents = [], widgets: _widgets, notificationActions, voiceUsageDescription, appGroupId, entities = [], focusFilters = [], appClips = [], slices = [], enableInteractiveWidgets = false, enablePushToTalk = false, pttUsageDescription, enableLiveActivities = false, liveActivityTypes = [], enableWidget = false, widgetTitle, widgetDescription, widgetDataKey, widgetAccentColor, widgetDeepLink, widgetSizes, } = options;
|
|
14
|
+
const { intents = [], widgets: _widgets, notificationActions, voiceUsageDescription, appGroupId, entities = [], focusFilters = [], appClips = [], slices = [], enableInteractiveWidgets = false, enablePushToTalk = false, pttUsageDescription, enableLiveActivities = false, liveActivityTypes = [], enableWidget = false, widgetTitle, widgetDescription, widgetDataKey, widgetAccentColor, widgetBgColor, widgetIcon, widgetDetailIcon, widgetEmptyText, widgetRefreshMinutes, widgetDeepLink, widgetSizes, } = options;
|
|
9
15
|
// Validate options early — throws with a helpful message if misconfigured
|
|
10
16
|
(0, validation_1.validatePluginOptions)({ enablePushToTalk, pttUsageDescription, enableLiveActivities, liveActivityTypes });
|
|
11
17
|
// Widget-specific validation
|
|
@@ -22,6 +28,18 @@ const withInvoke = (config, options) => {
|
|
|
22
28
|
throw new Error('[expo-invoke] widgetDeepLink cannot be an empty string when enableWidget is true.\n' +
|
|
23
29
|
'Fix: Set widgetDeepLink to your app URL scheme, e.g. "myapp://home".');
|
|
24
30
|
}
|
|
31
|
+
if (widgetAccentColor !== undefined)
|
|
32
|
+
assertHex(widgetAccentColor, 'widgetAccentColor');
|
|
33
|
+
if (widgetBgColor !== undefined)
|
|
34
|
+
assertHex(widgetBgColor, 'widgetBgColor');
|
|
35
|
+
if (widgetRefreshMinutes !== undefined && (widgetRefreshMinutes < 1 || widgetRefreshMinutes > 60)) {
|
|
36
|
+
throw new Error(`[expo-invoke] widgetRefreshMinutes must be between 1 and 60 (got ${widgetRefreshMinutes}).\n` +
|
|
37
|
+
'Fix: Use a value like 15 for a 15-minute refresh interval.');
|
|
38
|
+
}
|
|
39
|
+
if (widgetSizes !== undefined && widgetSizes.length === 0) {
|
|
40
|
+
throw new Error('[expo-invoke] widgetSizes cannot be empty.\n' +
|
|
41
|
+
'Fix: Use ["small"], ["medium"], or ["small", "medium", "large"].');
|
|
42
|
+
}
|
|
25
43
|
}
|
|
26
44
|
config = (0, withIOSInvoke_1.withIOSInvoke)(config, {
|
|
27
45
|
intents,
|
|
@@ -39,6 +57,11 @@ const withInvoke = (config, options) => {
|
|
|
39
57
|
widgetDescription,
|
|
40
58
|
widgetDataKey,
|
|
41
59
|
widgetAccentColor,
|
|
60
|
+
widgetBgColor,
|
|
61
|
+
widgetIcon,
|
|
62
|
+
widgetDetailIcon,
|
|
63
|
+
widgetEmptyText,
|
|
64
|
+
widgetRefreshMinutes,
|
|
42
65
|
widgetDeepLink,
|
|
43
66
|
widgetSizes,
|
|
44
67
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withInvoke.js","sourceRoot":"","sources":["../../../plugin/src/withInvoke.ts"],"names":[],"mappings":";;AAAA,yDAA8E;AAC9E,wDAAqD;AACrD,oEAAiE;AACjE,2DAAmE;
|
|
1
|
+
{"version":3,"file":"withInvoke.js","sourceRoot":"","sources":["../../../plugin/src/withInvoke.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-invoke",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.13",
|
|
4
4
|
"description": "The complete native-surface-to-JS bridge for Expo. One intent config → Siri, Google Assistant, home screen widgets, Dynamic Island, app icon menus, notification actions, NFC, QR, deep links and more — all through a single useInvoke() hook.",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"module": "build/src/index.js",
|