@livx.cc/appwrap 0.60.0 → 0.60.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livx.cc/appwrap",
3
- "version": "0.60.0",
3
+ "version": "0.60.1",
4
4
  "description": "Wrap any PWA into a native app with native capabilities (appwrap runtime + @livx.cc/native-kit).",
5
5
  "license": "MIT",
6
6
  "author": "Elya Livshitz",
@@ -66,7 +66,7 @@ export function registerAndroidHandlers(): void {
66
66
  return ok ? 'granted' : 'denied';
67
67
  });
68
68
 
69
- bridge.register('notifications.schedule', ({ id, title, body, delaySec, deepLink, sender, icon }: any) => {
69
+ bridge.register('notifications.schedule', ({ id, title, body, delaySec, deepLink, sender, icon, silent }: any) => {
70
70
  const ident = notifIdentity({ title, body, sender, icon });
71
71
  // Per-sender channel gives the mini-app its own identity + settings row; else the shared one.
72
72
  const channelId = ident.useIdentity && ident.senderName ? senderChannelId(ident.senderName) : CHANNEL_ID;
@@ -82,6 +82,10 @@ export function registerAndroidHandlers(): void {
82
82
  .setSmallIcon(ctx.getApplicationInfo().icon)
83
83
  .setContentTitle(ident.title)
84
84
  .setAutoCancel(true);
85
+ // The channel already carries the alert sound (IMPORTANCE_DEFAULT); `silent: true` is the
86
+ // per-notification opt-out that matches iOS's nil-sound path. API 29+ only — below that the
87
+ // channel's sound wins and there is nothing to suppress.
88
+ if (silent && android.os.Build.VERSION.SDK_INT >= 29) builder.setSilent(true);
85
89
  if (ident.subtitle) builder.setSubText(ident.subtitle);
86
90
  if (ident.body) builder.setContentText(ident.body);
87
91
  // Tap → re-open the (singleTask) activity with a VIEW intent; onNewIntent
@@ -227,7 +227,7 @@ export function registerExtendedHandlers(): void {
227
227
  });
228
228
  });
229
229
 
230
- bridge.register('notifications.schedule', ({ id, title, body, delaySec, deepLink, sender, icon, badge }: { id?: number; title?: string; body?: string; delaySec?: number; deepLink?: string; sender?: string; icon?: string; badge?: number }) => {
230
+ bridge.register('notifications.schedule', ({ id, title, body, delaySec, deepLink, sender, icon, badge, silent }: { id?: number; title?: string; body?: string; delaySec?: number; deepLink?: string; sender?: string; icon?: string; badge?: number; silent?: boolean }) => {
231
231
  if (!isIOS) throw Object.assign(new Error('iOS only for now'), { code: 'UNSUPPORTED' });
232
232
  const nid = id ?? Math.floor(Math.random() * 100000);
233
233
  const ident = notifIdentity({ title, body, sender, icon });
@@ -238,6 +238,13 @@ export function registerExtendedHandlers(): void {
238
238
  if (ident.body) content.body = ident.body;
239
239
  // App-icon badge on delivery (set before the communication-style wrap so it's carried through).
240
240
  if (typeof badge === 'number') content.badge = badge;
241
+ // ALERT SOUND. iOS leaves `content.sound` nil by default, which delivers the notification
242
+ // SILENTLY — so a scheduled timer/alarm fired while the app was backgrounded made no noise at
243
+ // all, with nothing in the API to hint why. Android's side has always played one (its channel
244
+ // is IMPORTANCE_DEFAULT), so the platforms disagreed on the same call. Default to the system
245
+ // alert sound and let a caller opt out with `silent: true`; set BEFORE the communication-style
246
+ // wrap so contentByUpdatingWithProvider carries it through.
247
+ if (!silent) content.sound = UNNotificationSound.defaultSound;
241
248
  // Group per-sender so the mini-app's notifications thread together (iOS 15+ also
242
249
  // uses this alongside the communication-style avatar below).
243
250
  if (ident.useIdentity && ident.senderName) content.threadIdentifier = ident.senderName;