authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 10:58:39-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 10:58:39-07:00
logf7867addbe18ebb55c916041dc168aa4b8f39335
treef99e004d8d1bee21c2b8d10d6982486aaf253cca
parent7a8bab5d9df80e06782033d1ee252400e6f048b1
signature Signed by PGP key B5690EEEBB952194

[codex] Structure mobile notification setting failures (#3391)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 40 insertions(+), 4 deletions(-)

apps/mobile/src/features/agent-awareness/liveActivityPreferences.ts+14-1
......@@ -1,4 +1,5 @@
11import * as Effect from "effect/Effect";
2import * as Schema from "effect/Schema";
23import { HttpClient } from "effect/unstable/http";
34import { ManagedRelay } from "@t3tools/client-runtime/relay";
45
......@@ -7,6 +8,18 @@ import { savePreferencesPatch } from "../../lib/storage";
78import { linkEnvironmentToCloud } from "../cloud/linkEnvironment";
89import { refreshAgentAwarenessRegistration } from "./remoteRegistration";
910
11export class LiveActivityPreferenceSaveError extends Schema.TaggedErrorClass<LiveActivityPreferenceSaveError>()(
12 "LiveActivityPreferenceSaveError",
13 {
14 enabled: Schema.Boolean,
15 cause: Schema.Defect(),
16 },
17) {
18 override get message(): string {
19 return `Failed to save the Live Activity updates setting (enabled: ${this.enabled}).`;
20 }
21}
22
1023export function setLiveActivityUpdatesEnabled(input: {
1124 readonly enabled: boolean;
1225 readonly clerkToken: string | null;
......@@ -15,7 +28,7 @@ export function setLiveActivityUpdatesEnabled(input: {
1528 return Effect.gen(function* () {
1629 yield* Effect.tryPromise({
1730 try: () => savePreferencesPatch({ liveActivitiesEnabled: input.enabled }),
18 catch: (error) => error,
31 catch: (cause) => new LiveActivityPreferenceSaveError({ enabled: input.enabled, cause }),
1932 });
2033
2134 yield* refreshAgentAwarenessRegistration();
apps/mobile/src/features/agent-awareness/notificationPermissions.ts+26-3
......@@ -1,5 +1,6 @@
11import * as Notifications from "expo-notifications";
22import * as Effect from "effect/Effect";
3import * as Schema from "effect/Schema";
34import { Platform } from "react-native";
45
56export type NotificationPermissionResult =
......@@ -7,9 +8,31 @@ export type NotificationPermissionResult =
78 | { readonly type: "granted" }
89 | { readonly type: "denied"; readonly canAskAgain: boolean };
910
11export class NotificationPermissionReadError extends Schema.TaggedErrorClass<NotificationPermissionReadError>()(
12 "NotificationPermissionReadError",
13 {
14 cause: Schema.Defect(),
15 },
16) {
17 override get message(): string {
18 return "Failed to read notification permissions on iOS.";
19 }
20}
21
22export class NotificationPermissionRequestError extends Schema.TaggedErrorClass<NotificationPermissionRequestError>()(
23 "NotificationPermissionRequestError",
24 {
25 cause: Schema.Defect(),
26 },
27) {
28 override get message(): string {
29 return "Failed to request notification permissions on iOS.";
30 }
31}
32
1033export const requestAgentNotificationPermission: Effect.Effect<
1134 NotificationPermissionResult,
12 unknown
35 NotificationPermissionReadError | NotificationPermissionRequestError
1336> = Effect.gen(function* () {
1437 if (Platform.OS !== "ios") {
1538 return { type: "unsupported" };
......@@ -17,7 +40,7 @@ export const requestAgentNotificationPermission: Effect.Effect<
1740
1841 const existing = yield* Effect.tryPromise({
1942 try: () => Notifications.getPermissionsAsync(),
20 catch: (error) => error,
43 catch: (cause) => new NotificationPermissionReadError({ cause }),
2144 });
2245 if (existing.granted) {
2346 return { type: "granted" };
......@@ -36,7 +59,7 @@ export const requestAgentNotificationPermission: Effect.Effect<
3659 allowSound: true,
3760 },
3861 }),
39 catch: (error) => error,
62 catch: (cause) => new NotificationPermissionRequestError({ cause }),
4063 });
4164 return requested.granted
4265 ? { type: "granted" }