WIP: new-activity notification #231
@@ -16,8 +16,11 @@ public class NotificationInspectorPlugin: CAPPlugin, CAPBridgedPlugin {
|
||||
]
|
||||
}
|
||||
|
||||
/// Stable wall-clock target: plugin `userInfo["scheduled_time"]`, or epoch ms in `predictive_<ms>` identifiers.
|
||||
/// Stable wall-clock target: plugin `userInfo["scheduled_time"]`, or epoch ms in API notification identifiers.
|
||||
/// (Apple documents `UNTimeIntervalNotificationTrigger.nextTriggerDate()` as resampling ~now+interval when queried.)
|
||||
/// API notification identifiers use the `api_` prefix.
|
||||
private static let apiNotificationIdentifierPrefix = "api_"
|
||||
|
||||
private func wallClockMillis(from request: UNNotificationRequest) -> (ms: Int64, source: String)? {
|
||||
let info = request.content.userInfo
|
||||
if let v = info["scheduled_time"] as? Int64 {
|
||||
@@ -29,11 +32,11 @@ public class NotificationInspectorPlugin: CAPPlugin, CAPBridgedPlugin {
|
||||
if let i = info["scheduled_time"] as? Int {
|
||||
return (Int64(i), "userInfo.scheduled_time")
|
||||
}
|
||||
let prefix = "predictive_"
|
||||
let prefix = Self.apiNotificationIdentifierPrefix
|
||||
if request.identifier.hasPrefix(prefix) {
|
||||
let suffix = String(request.identifier.dropFirst(prefix.count))
|
||||
if let ms = Int64(suffix) {
|
||||
return (ms, "identifier(predictive_)")
|
||||
return (ms, "identifier (API notification)")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
70
package-lock.json
generated
70
package-lock.json
generated
@@ -4459,9 +4459,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli": {
|
||||
"version": "56.1.13",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-56.1.13.tgz",
|
||||
"integrity": "sha512-7n5VzlBr7TKW0BgWgpEopWy+v8buPhMvbSEsuXD+bI1YIJBopkfWAub0qTvlc357E8wWOvV5MJXYyoeRvoOjoQ==",
|
||||
"version": "56.1.14",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-56.1.14.tgz",
|
||||
"integrity": "sha512-rSH3ygjEPipEYG6dgiJ116J8KqCQ/BYKcwQDipStSh4IFWJ10RZaYP4u5B74jxfeIWjWrOeqvwB6NZfQBjaQ4Q==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -4471,7 +4471,7 @@
|
||||
"@expo/devcert": "^1.2.1",
|
||||
"@expo/env": "~2.3.0",
|
||||
"@expo/image-utils": "^0.10.1",
|
||||
"@expo/inline-modules": "^0.0.10",
|
||||
"@expo/inline-modules": "^0.0.11",
|
||||
"@expo/json-file": "^10.2.0",
|
||||
"@expo/log-box": "^56.0.12",
|
||||
"@expo/metro": "~56.0.0",
|
||||
@@ -4480,9 +4480,9 @@
|
||||
"@expo/osascript": "^2.6.0",
|
||||
"@expo/package-manager": "^1.12.1",
|
||||
"@expo/plist": "^0.7.0",
|
||||
"@expo/prebuild-config": "^56.0.14",
|
||||
"@expo/prebuild-config": "^56.0.15",
|
||||
"@expo/require-utils": "^56.1.3",
|
||||
"@expo/router-server": "^56.0.12",
|
||||
"@expo/router-server": "^56.0.13",
|
||||
"@expo/schema-utils": "^56.0.0",
|
||||
"@expo/spawn-async": "^1.8.0",
|
||||
"@expo/ws-tunnel": "^1.0.1",
|
||||
@@ -4498,7 +4498,7 @@
|
||||
"connect": "^3.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"dnssd-advertise": "^1.1.4",
|
||||
"expo-server": "^56.0.4",
|
||||
"expo-server": "^56.0.5",
|
||||
"fetch-nodeshim": "^0.4.10",
|
||||
"getenv": "^2.0.0",
|
||||
"glob": "^13.0.0",
|
||||
@@ -5275,9 +5275,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@expo/fingerprint": {
|
||||
"version": "0.19.3",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.19.3.tgz",
|
||||
"integrity": "sha512-w9Au2IVrtc0Ct+WRa05DVHGNHXYq6VyPZWuFP+5x055OeZ5q6k5Yg+aJ1gfShmjdOhDftRcsvmWmTdTZlWaTZw==",
|
||||
"version": "0.19.4",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.19.4.tgz",
|
||||
"integrity": "sha512-PsowRlO8+S7JlO8go7yhNEXp7sqlsWDE2AlCwoss7zH0dcajXFo74Fy0KdXEc4UXK7kKoHD37oDgsZ8aHSLr7A==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -5418,9 +5418,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/inline-modules": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@expo/inline-modules/-/inline-modules-0.0.10.tgz",
|
||||
"integrity": "sha512-DKEfq877UTAmL/gOT5aFhlLNDg/EVmTSca7JQMKDGR6mjFSAcrmQf4GJNsi6ztiaqj6cTnIfoSz0hAYdnr6RJQ==",
|
||||
"version": "0.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@expo/inline-modules/-/inline-modules-0.0.11.tgz",
|
||||
"integrity": "sha512-ZlIfKL61DPnW8YUTdMEjMA31xrDDV6p7Xi8rWYyhd5qXBV8MwGwjuJ7vKeaVaMjRqxJk1N9lv7zlfyvQpRCNNw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -6602,9 +6602,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config": {
|
||||
"version": "56.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-56.0.14.tgz",
|
||||
"integrity": "sha512-JHdMqR7Mf5ApLC50ZwTL0Z86ezrHOMYwoSHcWT6Pha/+1TcC+/J+i7vjhP06wGXQ2Kvjt74p/3mKg2Pd12KjhQ==",
|
||||
"version": "56.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-56.0.15.tgz",
|
||||
"integrity": "sha512-6GC+QjdCkzp/5wjsqgfu/B2+2yf5MyZMtzf9szIPrLt9uKhzV2PdyM0vU0kvbj1YT8weHCtO7bsrzimman0sjA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -6615,7 +6615,7 @@
|
||||
"@expo/json-file": "^10.2.0",
|
||||
"@react-native/normalize-colors": "0.85.3",
|
||||
"debug": "^4.3.1",
|
||||
"expo-modules-autolinking": "~56.0.14",
|
||||
"expo-modules-autolinking": "~56.0.15",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.6.0"
|
||||
}
|
||||
@@ -6631,9 +6631,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config/node_modules/expo-modules-autolinking": {
|
||||
"version": "56.0.14",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-56.0.14.tgz",
|
||||
"integrity": "sha512-9ugtZkheNPYDkW4DZopY1rH2BCbUICaafUEPxRgbLDR5UNRF5K3cdHMIMEt8pxZPq2+eX4wCm+6pbSvdY/DPHg==",
|
||||
"version": "56.0.15",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-56.0.15.tgz",
|
||||
"integrity": "sha512-WqpBFwLzn7DsrUkWltIjVmAjwuI1VdQ2jRMlvk1nh2kVadwdJBkSjUBQWRifsEePNhiMT/rFOovBolUU/ARt5w==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -6677,21 +6677,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/router-server": {
|
||||
"version": "56.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-56.0.12.tgz",
|
||||
"integrity": "sha512-RqKV2/Z8BH/z8l0ngSpG6//5xxJPaF5dTQvSfPQ0nrvCjikGMeIvyj3B9BeLnmZZhxb3gBtXqrj3irAoiIp2aQ==",
|
||||
"version": "56.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-56.0.13.tgz",
|
||||
"integrity": "sha512-M2H2zHlRBKIPENCWV8Gqo3/9WANCS9vvOMCcdWfS9wD8XXMnDASFniS0bBoGwwS1qq1LIpYzX8m8wdv7Awy88g==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@expo/metro-runtime": "^56.0.13",
|
||||
"@expo/metro-runtime": "^56.0.14",
|
||||
"expo": "*",
|
||||
"expo-constants": "^56.0.16",
|
||||
"expo-constants": "^56.0.17",
|
||||
"expo-font": "^56.0.5",
|
||||
"expo-router": "*",
|
||||
"expo-server": "^56.0.4",
|
||||
"expo-server": "^56.0.5",
|
||||
"react": "*",
|
||||
"react-dom": "*",
|
||||
"react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
|
||||
@@ -9923,8 +9923,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@timesafari/daily-notification-plugin": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "git+https://gitea.anomalistdesign.com/trent_larson/daily-notification-plugin.git#750343ddb945b9688a46b34abcfc31116f1e4586",
|
||||
"version": "3.0.4",
|
||||
"resolved": "git+https://gitea.anomalistdesign.com/trent_larson/daily-notification-plugin.git#6de300b7d4d50eae8feef09ba9f7238c210866f0",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@@ -16412,14 +16412,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-asset": {
|
||||
"version": "56.0.15",
|
||||
"resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-56.0.15.tgz",
|
||||
"integrity": "sha512-BHGi2IAOPQTcOelkUdcz1WIknfCTRjkcpYHX1azjMwgYenrVC+J5qcqJGaC8eUOWLCRtkRJWGnmFQRYtLU1nUQ==",
|
||||
"version": "56.0.16",
|
||||
"resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-56.0.16.tgz",
|
||||
"integrity": "sha512-iIxPo6C6+/d8JxGV74ZKZbIcCz2s8//dVl7oBAj124NcPMFhzdwycFBpMqq5LUxin+lVy5cCoEjv2LD8ulnkiQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@expo/image-utils": "^0.10.1",
|
||||
"expo-constants": "~56.0.16"
|
||||
"expo-constants": "~56.0.17"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
@@ -16496,9 +16496,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-modules-jsi": {
|
||||
"version": "56.0.7",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-jsi/-/expo-modules-jsi-56.0.7.tgz",
|
||||
"integrity": "sha512-iBAj4Xeh/8HT201VVxFlmf+VBfmtQV1ZUoJdLQQENm0+j9gnD2QswZLJyNo3CmNNXl46esJeLR5lpGpYZts/zA==",
|
||||
"version": "56.0.8",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-jsi/-/expo-modules-jsi-56.0.8.tgz",
|
||||
"integrity": "sha512-tXqFU1MHrf7Ctq+Pw0qOeIPDFl1W51p9nRRZy9vVUn4GNuAk1Av0vrj0SGLvcxJvDf3aGwSzr8o8dgUsX5sG0g==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -4,7 +4,7 @@ export type PendingNotificationInfo = {
|
||||
identifier: string;
|
||||
nextTriggerDate?: number | null;
|
||||
triggerType?: string | null;
|
||||
/** Epoch ms for intended fire time when known (userInfo or predictive_ id); stable across Refresh. */
|
||||
/** Epoch ms for intended fire time when known (userInfo or API notification id); stable across refresh. */
|
||||
wallClockMillis?: number | null;
|
||||
wallClockSource?: string | null;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
getTestMode,
|
||||
} from "./NotificationDebugConfig";
|
||||
import {
|
||||
logNotificationClearing,
|
||||
logRefreshFailure,
|
||||
logRefreshStarted,
|
||||
logRefreshSuccess,
|
||||
@@ -708,6 +707,7 @@ export async function applyNotificationRefreshPayload(
|
||||
|
||||
logScheduleReplacement(timestamps.length);
|
||||
|
||||
// Plugin API still exposes clearPredictiveNotifications(); it clears API-managed notifications only.
|
||||
const plugin = DailyNotification as unknown as {
|
||||
clearPredictiveNotifications?: () => Promise<void>;
|
||||
scheduleNotifications?: (options: {
|
||||
@@ -717,19 +717,17 @@ export async function applyNotificationRefreshPayload(
|
||||
|
||||
if (typeof plugin.clearPredictiveNotifications !== "function") {
|
||||
logger.warn(
|
||||
"[NativeNotificationService] No clearPredictiveNotifications on plugin; cannot replace schedule",
|
||||
"[NativeNotificationService] API notification clear unavailable (plugin clearPredictiveNotifications missing); cannot replace schedule",
|
||||
);
|
||||
logNotification(
|
||||
"Schedule replacement aborted (clearPredictiveNotifications unavailable on plugin)",
|
||||
"Schedule replacement aborted (API notification clear unavailable on plugin)",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"[Notifications] Clearing predictive notifications before refresh",
|
||||
);
|
||||
logNotificationClearing("clearPredictiveNotifications");
|
||||
logNotification("Clearing API notifications before refresh");
|
||||
await plugin.clearPredictiveNotifications();
|
||||
logNotification("Cleared API notifications");
|
||||
|
||||
if (typeof plugin.scheduleNotifications !== "function") {
|
||||
logger.warn(
|
||||
|
||||
@@ -742,7 +742,8 @@
|
||||
>
|
||||
Logs
|
||||
</router-link>
|
||||
<!-- Non-production bundles only; route `dev-notifications` must exist (see `includeDevToolkitRoutes`). -->
|
||||
<!-- Non-production bundles only; route `dev-notifications` must exist
|
||||
(see `includeDevToolkitRoutes`). -->
|
||||
<router-link
|
||||
v-if="isDev"
|
||||
:to="{ name: 'dev-notifications' }"
|
||||
|
||||
Reference in New Issue
Block a user