@buoy-gg/notifications 7.0.41 → 7.0.42

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.
Files changed (71) hide show
  1. package/lib/commonjs/components/LocalNotificationTest.js +1 -185
  2. package/lib/commonjs/components/NotificationTestView.js +1 -329
  3. package/lib/commonjs/components/NotificationToolView.js +1 -673
  4. package/lib/commonjs/components/notificationStyles.js +1 -292
  5. package/lib/commonjs/expo.js +1 -247
  6. package/lib/commonjs/index.js +1 -148
  7. package/lib/commonjs/json.js +1 -58
  8. package/lib/commonjs/payload.js +1 -68
  9. package/lib/commonjs/preset.js +1 -56
  10. package/lib/commonjs/preview.js +1 -18
  11. package/lib/commonjs/recorder.js +1 -339
  12. package/lib/commonjs/runtime.js +1 -110
  13. package/lib/commonjs/storage.js +1 -61
  14. package/lib/commonjs/types.js +0 -1
  15. package/lib/module/components/LocalNotificationTest.js +1 -180
  16. package/lib/module/components/NotificationTestView.js +1 -324
  17. package/lib/module/components/NotificationToolView.js +1 -668
  18. package/lib/module/components/notificationStyles.js +1 -288
  19. package/lib/module/expo.js +1 -241
  20. package/lib/module/index.js +1 -13
  21. package/lib/module/json.js +1 -51
  22. package/lib/module/payload.js +1 -63
  23. package/lib/module/preset.js +1 -50
  24. package/lib/module/preview.js +1 -14
  25. package/lib/module/recorder.js +1 -332
  26. package/lib/module/runtime.js +1 -103
  27. package/lib/module/storage.js +1 -56
  28. package/lib/module/types.js +0 -1
  29. package/package.json +2 -2
  30. package/lib/commonjs/components/LocalNotificationTest.js.map +0 -1
  31. package/lib/commonjs/components/NotificationTestView.js.map +0 -1
  32. package/lib/commonjs/components/NotificationToolView.js.map +0 -1
  33. package/lib/commonjs/components/notificationStyles.js.map +0 -1
  34. package/lib/commonjs/expo.js.map +0 -1
  35. package/lib/commonjs/index.js.map +0 -1
  36. package/lib/commonjs/json.js.map +0 -1
  37. package/lib/commonjs/payload.js.map +0 -1
  38. package/lib/commonjs/preset.js.map +0 -1
  39. package/lib/commonjs/preview.js.map +0 -1
  40. package/lib/commonjs/recorder.js.map +0 -1
  41. package/lib/commonjs/runtime.js.map +0 -1
  42. package/lib/commonjs/storage.js.map +0 -1
  43. package/lib/commonjs/types.js.map +0 -1
  44. package/lib/module/components/LocalNotificationTest.js.map +0 -1
  45. package/lib/module/components/NotificationTestView.js.map +0 -1
  46. package/lib/module/components/NotificationToolView.js.map +0 -1
  47. package/lib/module/components/notificationStyles.js.map +0 -1
  48. package/lib/module/expo.js.map +0 -1
  49. package/lib/module/index.js.map +0 -1
  50. package/lib/module/json.js.map +0 -1
  51. package/lib/module/payload.js.map +0 -1
  52. package/lib/module/preset.js.map +0 -1
  53. package/lib/module/preview.js.map +0 -1
  54. package/lib/module/recorder.js.map +0 -1
  55. package/lib/module/runtime.js.map +0 -1
  56. package/lib/module/storage.js.map +0 -1
  57. package/lib/module/types.js.map +0 -1
  58. package/lib/typescript/components/LocalNotificationTest.d.ts.map +0 -1
  59. package/lib/typescript/components/NotificationTestView.d.ts.map +0 -1
  60. package/lib/typescript/components/NotificationToolView.d.ts.map +0 -1
  61. package/lib/typescript/components/notificationStyles.d.ts.map +0 -1
  62. package/lib/typescript/expo.d.ts.map +0 -1
  63. package/lib/typescript/index.d.ts.map +0 -1
  64. package/lib/typescript/json.d.ts.map +0 -1
  65. package/lib/typescript/payload.d.ts.map +0 -1
  66. package/lib/typescript/preset.d.ts.map +0 -1
  67. package/lib/typescript/preview.d.ts.map +0 -1
  68. package/lib/typescript/recorder.d.ts.map +0 -1
  69. package/lib/typescript/runtime.d.ts.map +0 -1
  70. package/lib/typescript/storage.d.ts.map +0 -1
  71. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,180 +1 @@
1
- "use strict";
2
-
3
- import React, { useRef, useState } from "react";
4
- import { StyleSheet, Text, TextInput, View } from "react-native";
5
- import { NightSegmented, night } from "@buoy-gg/shared-ui";
6
- import { NotificationTestView } from "./NotificationTestView";
7
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
- export function LocalNotificationTest({
9
- snapshot,
10
- onAction,
11
- onViewActivity
12
- }) {
13
- const [title, setTitle] = useState("Test notification");
14
- const [message, setMessage] = useState("Tap to open the app.");
15
- const [data, setData] = useState("{}");
16
- const [seconds, setSeconds] = useState("1");
17
- const [busy, setBusy] = useState(false);
18
- const lock = useRef(false);
19
- const [error, setError] = useState(null);
20
- const [latest, setLatest] = useState(null);
21
- let custom = {};
22
- let validation = null;
23
- try {
24
- custom = JSON.parse(data);
25
- if (!custom || typeof custom !== "object" || Array.isArray(custom)) throw new Error();
26
- } catch {
27
- validation = "Custom data must be a JSON object. Open Options to edit it.";
28
- }
29
- async function send() {
30
- if (lock.current || validation) return;
31
- lock.current = true;
32
- setBusy(true);
33
- setLatest(null);
34
- setError(null);
35
- const test = {
36
- testId: `buoy-local-${Date.now()}-${Math.random().toString(36).slice(2)}`,
37
- startedAt: Date.now(),
38
- appId: snapshot?.appId ?? null
39
- };
40
- try {
41
- await onAction("setCaptureSession", {
42
- runId: test.testId,
43
- durationMs: 1800000
44
- });
45
- await onAction("scheduleLocal", {
46
- title,
47
- body: message,
48
- data: {
49
- ...custom,
50
- __buoyTestId: test.testId
51
- },
52
- seconds: Number(seconds)
53
- });
54
- setLatest(test);
55
- } catch (error) {
56
- setError(error instanceof Error ? error.message : String(error));
57
- } finally {
58
- lock.current = false;
59
- setBusy(false);
60
- }
61
- }
62
- const events = latest && latest.appId === snapshot?.appId ? snapshot.events.filter(event => event.testId === latest.testId && event.capturedAt >= latest.startedAt) : [];
63
- const received = events.some(event => event.kind === "received");
64
- const tapped = events.some(event => event.kind === "response" || event.kind === "startup-response");
65
- const outcome = events.some(event => event.kind === "app-outcome");
66
- const supported = !!snapshot?.capabilities.includes("local-scheduling");
67
- return /*#__PURE__*/_jsx(NotificationTestView, {
68
- title: title,
69
- message: message,
70
- onTitleChange: setTitle,
71
- onMessageChange: setMessage,
72
- appName: "This app",
73
- appearance: snapshot?.preview,
74
- destination: /*#__PURE__*/_jsxs(View, {
75
- style: s.destination,
76
- children: [/*#__PURE__*/_jsxs(View, {
77
- style: s.field,
78
- children: [/*#__PURE__*/_jsx(Text, {
79
- style: s.label,
80
- children: "Device"
81
- }), /*#__PURE__*/_jsx(Text, {
82
- style: s.value,
83
- children: "This device"
84
- })]
85
- }), /*#__PURE__*/_jsxs(View, {
86
- style: s.field,
87
- children: [/*#__PURE__*/_jsx(Text, {
88
- style: s.label,
89
- children: "Delivery"
90
- }), /*#__PURE__*/_jsx(Text, {
91
- style: s.value,
92
- children: "Local notification"
93
- })]
94
- })]
95
- }),
96
- options: /*#__PURE__*/_jsxs(View, {
97
- style: s.options,
98
- children: [/*#__PURE__*/_jsx(Text, {
99
- style: s.label,
100
- children: "Send after"
101
- }), /*#__PURE__*/_jsx(NightSegmented, {
102
- tabs: [{
103
- key: "1",
104
- label: "1 second"
105
- }, {
106
- key: "10",
107
- label: "10 seconds"
108
- }],
109
- activeKey: seconds,
110
- onChange: setSeconds,
111
- size: "sm",
112
- glass: true
113
- }), /*#__PURE__*/_jsx(Text, {
114
- style: s.label,
115
- children: "Custom data"
116
- }), /*#__PURE__*/_jsx(TextInput, {
117
- accessibilityLabel: "Notification custom data",
118
- value: data,
119
- onChangeText: setData,
120
- multiline: true,
121
- autoCapitalize: "none",
122
- autoCorrect: false,
123
- style: s.json
124
- }), /*#__PURE__*/_jsx(Text, {
125
- style: s.label,
126
- children: "Use the delay to leave the app before delivery. Simulator push and raw APNs payloads are available on desktop."
127
- })]
128
- }),
129
- result: latest ? {
130
- title: outcome ? "App reported an outcome" : tapped ? "Notification tapped" : received ? "Received by app" : "Notification scheduled",
131
- message: tapped ? "Open Activity to inspect the app’s response." : "Tap the notification to test what opens."
132
- } : null,
133
- onViewActivity: onViewActivity,
134
- onSend: () => {
135
- void send();
136
- },
137
- busy: busy,
138
- disabled: !supported || !!validation,
139
- error: error ?? validation,
140
- hint: !supported ? "Connect Expo notification capture to send a local test." : seconds === "10" ? "You have 10 seconds to leave the app." : "Sends locally on this device after one second."
141
- });
142
- }
143
- const s = StyleSheet.create({
144
- destination: {
145
- flexDirection: "row",
146
- gap: 12
147
- },
148
- field: {
149
- flex: 1,
150
- gap: 7
151
- },
152
- label: {
153
- color: night.color.textSecondary,
154
- fontSize: 12,
155
- lineHeight: 18
156
- },
157
- value: {
158
- color: night.color.text,
159
- fontSize: 13,
160
- borderWidth: 1,
161
- borderColor: night.color.glassBorder,
162
- backgroundColor: night.color.glass,
163
- borderRadius: 10,
164
- padding: 11
165
- },
166
- options: {
167
- gap: 12
168
- },
169
- json: {
170
- color: night.color.text,
171
- fontSize: 12,
172
- minHeight: 100,
173
- textAlignVertical: "top",
174
- padding: 12,
175
- borderWidth: 1,
176
- borderColor: night.color.glassBorder,
177
- borderRadius: 10
178
- }
179
- });
180
- //# sourceMappingURL=LocalNotificationTest.js.map
1
+ "use strict";import J,{useRef as E,useState as s}from"react";import{StyleSheet as M,Text as a,TextInput as V,View as d}from"react-native";import{NightSegmented as _,night as i}from"@buoy-gg/shared-ui";import{NotificationTestView as B}from"./NotificationTestView";import{jsx as o,jsxs as p}from"react/jsx-runtime";export function LocalNotificationTest({snapshot:n,onAction:m,onViewActivity:I}){const[b,N]=s("Test notification");const[g,k]=s("Tap to open the app.");const[v,A]=s("{}");const[u,j]=s("1");const[D,S]=s(false);const f=E(false);const[z,x]=s(null);const[l,w]=s(null);let r={};let c=null;try{r=JSON.parse(v);if(!r||typeof r!=="object"||Array.isArray(r))throw new Error}catch{c="Custom data must be a JSON object. Open Options to edit it."}async function L(){if(f.current||c)return;f.current=true;S(true);w(null);x(null);const e={testId:`buoy-local-${Date.now()}-${Math.random().toString(36).slice(2)}`,startedAt:Date.now(),appId:n?.appId??null};try{await m("setCaptureSession",{runId:e.testId,durationMs:18e5});await m("scheduleLocal",{title:b,body:g,data:{...r,__buoyTestId:e.testId},seconds:Number(u)});w(e)}catch(h){x(h instanceof Error?h.message:String(h))}finally{f.current=false;S(false)}}const y=l&&l.appId===n?.appId?n.events.filter(e=>e.testId===l.testId&&e.capturedAt>=l.startedAt):[];const O=y.some(e=>e.kind==="received");const C=y.some(e=>e.kind==="response"||e.kind==="startup-response");const R=y.some(e=>e.kind==="app-outcome");const T=!!n?.capabilities.includes("local-scheduling");return o(B,{title:b,message:g,onTitleChange:N,onMessageChange:k,appName:"This app",appearance:n?.preview,destination:p(d,{style:t.destination,children:[p(d,{style:t.field,children:[o(a,{style:t.label,children:"Device"}),o(a,{style:t.value,children:"This device"})]}),p(d,{style:t.field,children:[o(a,{style:t.label,children:"Delivery"}),o(a,{style:t.value,children:"Local notification"})]})]}),options:p(d,{style:t.options,children:[o(a,{style:t.label,children:"Send after"}),o(_,{tabs:[{key:"1",label:"1 second"},{key:"10",label:"10 seconds"}],activeKey:u,onChange:j,size:"sm",glass:true}),o(a,{style:t.label,children:"Custom data"}),o(V,{accessibilityLabel:"Notification custom data",value:v,onChangeText:A,multiline:true,autoCapitalize:"none",autoCorrect:false,style:t.json}),o(a,{style:t.label,children:"Use the delay to leave the app before delivery. Simulator push and raw APNs payloads are available on desktop."})]}),result:l?{title:R?"App reported an outcome":C?"Notification tapped":O?"Received by app":"Notification scheduled",message:C?"Open Activity to inspect the app\u2019s response.":"Tap the notification to test what opens."}:null,onViewActivity:I,onSend:()=>{void L()},busy:D,disabled:!T||!!c,error:z??c,hint:!T?"Connect Expo notification capture to send a local test.":u==="10"?"You have 10 seconds to leave the app.":"Sends locally on this device after one second."})}const t=M.create({destination:{flexDirection:"row",gap:12},field:{flex:1,gap:7},label:{color:i.color.textSecondary,fontSize:12,lineHeight:18},value:{color:i.color.text,fontSize:13,borderWidth:1,borderColor:i.color.glassBorder,backgroundColor:i.color.glass,borderRadius:10,padding:11},options:{gap:12},json:{color:i.color.text,fontSize:12,minHeight:100,textAlignVertical:"top",padding:12,borderWidth:1,borderColor:i.color.glassBorder,borderRadius:10}});
@@ -1,324 +1 @@
1
- "use strict";
2
-
3
- import React, { useEffect, useState } from "react";
4
- import { Image, Pressable, ScrollView, StyleSheet, Text, TextInput, View } from "react-native";
5
- import { CheckCircle, ChevronDown, ChevronRight, NotificationsIcon, XCircle, night, useSafeAreaInsets } from "@buoy-gg/shared-ui";
6
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
- export function NotificationTestView(props) {
8
- const [iconFailed, setIconFailed] = useState(false);
9
- useEffect(() => setIconFailed(false), [props.appearance?.iconUri]);
10
- const ink = props.appearance?.textColor ? {
11
- color: props.appearance.textColor
12
- } : undefined;
13
- const [optionsOpen, setOptionsOpen] = useState(false);
14
- const insets = useSafeAreaInsets({
15
- minBottom: 12
16
- });
17
- return /*#__PURE__*/_jsxs(View, {
18
- style: s.root,
19
- children: [/*#__PURE__*/_jsx(ScrollView, {
20
- testID: "notification-test-scroll",
21
- style: s.root,
22
- contentContainerStyle: s.scroll,
23
- keyboardShouldPersistTaps: "handled",
24
- children: /*#__PURE__*/_jsxs(View, {
25
- style: s.content,
26
- children: [/*#__PURE__*/_jsxs(View, {
27
- style: s.intro,
28
- children: [/*#__PURE__*/_jsx(Text, {
29
- accessibilityRole: "header",
30
- style: s.heading,
31
- children: "Test a notification"
32
- }), /*#__PURE__*/_jsx(Text, {
33
- style: s.caption,
34
- children: "Send a test notification to your app."
35
- })]
36
- }), props.destination, props.previewNote ? /*#__PURE__*/_jsx(Text, {
37
- style: s.caption,
38
- children: props.previewNote
39
- }) : /*#__PURE__*/_jsxs(View, {
40
- style: [s.preview, props.appearance?.backgroundColor ? {
41
- backgroundColor: props.appearance.backgroundColor,
42
- borderColor: props.appearance.backgroundColor
43
- } : undefined],
44
- accessibilityLabel: "Notification preview",
45
- children: [/*#__PURE__*/_jsxs(View, {
46
- style: s.row,
47
- children: [props.appearance?.iconUri && !iconFailed ? /*#__PURE__*/_jsx(Image, {
48
- testID: "buoy-internal-notification-preview",
49
- source: {
50
- uri: props.appearance.iconUri
51
- },
52
- accessibilityLabel: `${props.appearance.appName ?? props.appName} icon`,
53
- style: s.appIcon,
54
- onError: () => setIconFailed(true)
55
- }) : /*#__PURE__*/_jsx(View, {
56
- style: s.iconFallback,
57
- children: /*#__PURE__*/_jsx(NotificationsIcon, {
58
- size: 22,
59
- color: night.color.accent
60
- })
61
- }), /*#__PURE__*/_jsx(Text, {
62
- numberOfLines: 1,
63
- style: [s.caption, s.appName, ink],
64
- children: props.appearance?.appName ?? props.appName
65
- }), /*#__PURE__*/_jsx(Text, {
66
- style: [s.caption, ink],
67
- children: "now"
68
- })]
69
- }), /*#__PURE__*/_jsx(TextInput, {
70
- accessibilityLabel: "Notification title",
71
- placeholder: "Title",
72
- placeholderTextColor: night.color.placeholder,
73
- value: props.title,
74
- onChangeText: props.onTitleChange,
75
- style: [s.input, s.title, ink],
76
- editable: !props.busy
77
- }), /*#__PURE__*/_jsx(TextInput, {
78
- accessibilityLabel: "Notification message",
79
- placeholder: "Message",
80
- placeholderTextColor: night.color.placeholder,
81
- value: props.message,
82
- onChangeText: props.onMessageChange,
83
- style: [s.input, ink],
84
- editable: !props.busy
85
- })]
86
- }), props.result && /*#__PURE__*/_jsxs(View, {
87
- accessibilityRole: "summary",
88
- accessibilityLiveRegion: "polite",
89
- testID: "notification-test-result",
90
- style: s.result,
91
- children: [/*#__PURE__*/_jsxs(View, {
92
- style: s.row,
93
- children: [props.result.failed ? /*#__PURE__*/_jsx(XCircle, {
94
- size: 16,
95
- color: night.color.danger
96
- }) : /*#__PURE__*/_jsx(CheckCircle, {
97
- size: 16,
98
- color: night.color.accent
99
- }), /*#__PURE__*/_jsx(Text, {
100
- style: s.resultTitle,
101
- children: props.result.title
102
- })]
103
- }), /*#__PURE__*/_jsx(Text, {
104
- style: s.caption,
105
- children: props.result.message
106
- }), /*#__PURE__*/_jsx(Pressable, {
107
- accessibilityRole: "button",
108
- accessibilityLabel: "View activity",
109
- onPress: props.onViewActivity,
110
- style: s.secondary,
111
- children: /*#__PURE__*/_jsx(Text, {
112
- style: s.secondaryText,
113
- children: "View activity"
114
- })
115
- })]
116
- }), /*#__PURE__*/_jsxs(View, {
117
- children: [/*#__PURE__*/_jsxs(Pressable, {
118
- accessibilityRole: "button",
119
- accessibilityLabel: "Notification options",
120
- accessibilityState: {
121
- expanded: optionsOpen
122
- },
123
- onPress: () => setOptionsOpen(!optionsOpen),
124
- style: s.options,
125
- children: [optionsOpen ? /*#__PURE__*/_jsx(ChevronDown, {
126
- size: 12,
127
- color: night.color.textSecondary
128
- }) : /*#__PURE__*/_jsx(ChevronRight, {
129
- size: 12,
130
- color: night.color.textSecondary
131
- }), /*#__PURE__*/_jsx(Text, {
132
- style: s.caption,
133
- children: "Options"
134
- })]
135
- }), optionsOpen && props.options]
136
- })]
137
- })
138
- }), /*#__PURE__*/_jsxs(View, {
139
- style: [s.footer, {
140
- paddingBottom: insets.bottom
141
- }],
142
- children: [!!props.error && /*#__PURE__*/_jsx(Text, {
143
- accessibilityRole: "alert",
144
- style: s.error,
145
- children: props.error
146
- }), !!props.notice && /*#__PURE__*/_jsx(Text, {
147
- accessibilityLiveRegion: "polite",
148
- style: s.caption,
149
- children: props.notice
150
- }), /*#__PURE__*/_jsxs(View, {
151
- style: s.footerRow,
152
- children: [/*#__PURE__*/_jsx(Text, {
153
- style: [s.caption, s.hint],
154
- children: props.hint
155
- }), /*#__PURE__*/_jsxs(Pressable, {
156
- accessibilityRole: "button",
157
- accessibilityLabel: props.busy ? "Sending…" : "Send notification",
158
- accessibilityState: {
159
- disabled: props.disabled || props.busy
160
- },
161
- disabled: props.disabled || props.busy,
162
- onPress: props.onSend,
163
- style: ({
164
- pressed
165
- }) => [s.send, (props.disabled || props.busy) && s.disabled, pressed && s.pressed],
166
- children: [/*#__PURE__*/_jsx(NotificationsIcon, {
167
- size: 15,
168
- color: night.color.onAccent
169
- }), /*#__PURE__*/_jsx(Text, {
170
- style: s.sendText,
171
- children: props.busy ? "Sending…" : "Send notification"
172
- })]
173
- })]
174
- })]
175
- })]
176
- });
177
- }
178
- const s = StyleSheet.create({
179
- root: {
180
- flex: 1,
181
- minHeight: 0,
182
- minWidth: 0
183
- },
184
- scroll: {
185
- padding: 16,
186
- flexGrow: 1
187
- },
188
- content: {
189
- width: "100%",
190
- maxWidth: 620,
191
- alignSelf: "center",
192
- gap: 20
193
- },
194
- intro: {
195
- gap: 8,
196
- paddingTop: 8
197
- },
198
- heading: {
199
- color: night.color.text,
200
- fontSize: 22,
201
- fontWeight: "600",
202
- letterSpacing: -0.5
203
- },
204
- caption: {
205
- color: night.color.textSecondary,
206
- fontSize: 12,
207
- lineHeight: 18
208
- },
209
- row: {
210
- flexDirection: "row",
211
- alignItems: "center",
212
- gap: 8
213
- },
214
- appName: {
215
- flex: 1,
216
- fontWeight: "600"
217
- },
218
- appIcon: {
219
- width: 36,
220
- height: 36,
221
- borderRadius: 8
222
- },
223
- iconFallback: {
224
- width: 36,
225
- height: 36,
226
- alignItems: "center",
227
- justifyContent: "center",
228
- borderRadius: 8,
229
- backgroundColor: night.color.fillSecondary
230
- },
231
- preview: {
232
- padding: 16,
233
- gap: 8,
234
- borderWidth: 1,
235
- borderColor: night.color.glassBorder,
236
- borderRadius: 20,
237
- backgroundColor: night.color.glass
238
- },
239
- input: {
240
- color: night.color.text,
241
- fontSize: 14,
242
- padding: 6,
243
- minHeight: 36
244
- },
245
- title: {
246
- fontSize: 16,
247
- fontWeight: "600"
248
- },
249
- result: {
250
- gap: 10,
251
- padding: 16,
252
- borderWidth: 1,
253
- borderColor: night.color.glassBorder,
254
- borderRadius: 14
255
- },
256
- resultTitle: {
257
- color: night.color.text,
258
- fontWeight: "500",
259
- fontSize: 13,
260
- flexShrink: 1
261
- },
262
- secondary: {
263
- alignSelf: "flex-start",
264
- paddingHorizontal: 14,
265
- paddingVertical: 8,
266
- borderRadius: 24,
267
- backgroundColor: night.color.fillSecondary
268
- },
269
- secondaryText: {
270
- color: night.color.accent,
271
- fontSize: 13
272
- },
273
- options: {
274
- flexDirection: "row",
275
- alignItems: "center",
276
- gap: 6,
277
- paddingVertical: 12
278
- },
279
- footer: {
280
- padding: 14,
281
- gap: 8,
282
- borderTopWidth: 1,
283
- borderTopColor: night.color.separator
284
- },
285
- footerRow: {
286
- flexDirection: "row",
287
- flexWrap: "wrap",
288
- alignItems: "center",
289
- justifyContent: "space-between",
290
- gap: 12
291
- },
292
- hint: {
293
- flexGrow: 1,
294
- flexShrink: 1,
295
- flexBasis: 200
296
- },
297
- send: {
298
- flexDirection: "row",
299
- alignItems: "center",
300
- justifyContent: "center",
301
- gap: 8,
302
- borderRadius: 24,
303
- paddingHorizontal: 18,
304
- paddingVertical: 12,
305
- backgroundColor: night.color.accent
306
- },
307
- sendText: {
308
- color: night.color.onAccent,
309
- fontSize: 13,
310
- fontWeight: "600"
311
- },
312
- disabled: {
313
- opacity: 0.4
314
- },
315
- pressed: {
316
- opacity: 0.8
317
- },
318
- error: {
319
- color: night.color.danger,
320
- fontSize: 12,
321
- lineHeight: 18
322
- }
323
- });
324
- //# sourceMappingURL=NotificationTestView.js.map
1
+ "use strict";import I,{useEffect as m,useState as y}from"react";import{Image as p,Pressable as s,ScrollView as S,StyleSheet as w,Text as n,TextInput as h,View as a}from"react-native";import{CheckCircle as C,ChevronDown as T,ChevronRight as R,NotificationsIcon as b,XCircle as z,night as o,useSafeAreaInsets as k}from"@buoy-gg/shared-ui";import{jsx as i,jsxs as l}from"react/jsx-runtime";export function NotificationTestView(e){const[g,d]=y(false);m(()=>d(false),[e.appearance?.iconUri]);const c=e.appearance?.textColor?{color:e.appearance.textColor}:void 0;const[r,f]=y(false);const u=k({minBottom:12});return l(a,{style:t.root,children:[i(S,{testID:"notification-test-scroll",style:t.root,contentContainerStyle:t.scroll,keyboardShouldPersistTaps:"handled",children:l(a,{style:t.content,children:[l(a,{style:t.intro,children:[i(n,{accessibilityRole:"header",style:t.heading,children:"Test a notification"}),i(n,{style:t.caption,children:"Send a test notification to your app."})]}),e.destination,e.previewNote?i(n,{style:t.caption,children:e.previewNote}):l(a,{style:[t.preview,e.appearance?.backgroundColor?{backgroundColor:e.appearance.backgroundColor,borderColor:e.appearance.backgroundColor}:void 0],accessibilityLabel:"Notification preview",children:[l(a,{style:t.row,children:[e.appearance?.iconUri&&!g?i(p,{testID:"buoy-internal-notification-preview",source:{uri:e.appearance.iconUri},accessibilityLabel:`${e.appearance.appName??e.appName} icon`,style:t.appIcon,onError:()=>d(true)}):i(a,{style:t.iconFallback,children:i(b,{size:22,color:o.color.accent})}),i(n,{numberOfLines:1,style:[t.caption,t.appName,c],children:e.appearance?.appName??e.appName}),i(n,{style:[t.caption,c],children:"now"})]}),i(h,{accessibilityLabel:"Notification title",placeholder:"Title",placeholderTextColor:o.color.placeholder,value:e.title,onChangeText:e.onTitleChange,style:[t.input,t.title,c],editable:!e.busy}),i(h,{accessibilityLabel:"Notification message",placeholder:"Message",placeholderTextColor:o.color.placeholder,value:e.message,onChangeText:e.onMessageChange,style:[t.input,c],editable:!e.busy})]}),e.result&&l(a,{accessibilityRole:"summary",accessibilityLiveRegion:"polite",testID:"notification-test-result",style:t.result,children:[l(a,{style:t.row,children:[e.result.failed?i(z,{size:16,color:o.color.danger}):i(C,{size:16,color:o.color.accent}),i(n,{style:t.resultTitle,children:e.result.title})]}),i(n,{style:t.caption,children:e.result.message}),i(s,{accessibilityRole:"button",accessibilityLabel:"View activity",onPress:e.onViewActivity,style:t.secondary,children:i(n,{style:t.secondaryText,children:"View activity"})})]}),l(a,{children:[l(s,{accessibilityRole:"button",accessibilityLabel:"Notification options",accessibilityState:{expanded:r},onPress:()=>f(!r),style:t.options,children:[r?i(T,{size:12,color:o.color.textSecondary}):i(R,{size:12,color:o.color.textSecondary}),i(n,{style:t.caption,children:"Options"})]}),r&&e.options]})]})}),l(a,{style:[t.footer,{paddingBottom:u.bottom}],children:[!!e.error&&i(n,{accessibilityRole:"alert",style:t.error,children:e.error}),!!e.notice&&i(n,{accessibilityLiveRegion:"polite",style:t.caption,children:e.notice}),l(a,{style:t.footerRow,children:[i(n,{style:[t.caption,t.hint],children:e.hint}),l(s,{accessibilityRole:"button",accessibilityLabel:e.busy?"Sending\u2026":"Send notification",accessibilityState:{disabled:e.disabled||e.busy},disabled:e.disabled||e.busy,onPress:e.onSend,style:({pressed:x})=>[t.send,(e.disabled||e.busy)&&t.disabled,x&&t.pressed],children:[i(b,{size:15,color:o.color.onAccent}),i(n,{style:t.sendText,children:e.busy?"Sending\u2026":"Send notification"})]})]})]})]})}const t=w.create({root:{flex:1,minHeight:0,minWidth:0},scroll:{padding:16,flexGrow:1},content:{width:"100%",maxWidth:620,alignSelf:"center",gap:20},intro:{gap:8,paddingTop:8},heading:{color:o.color.text,fontSize:22,fontWeight:"600",letterSpacing:-.5},caption:{color:o.color.textSecondary,fontSize:12,lineHeight:18},row:{flexDirection:"row",alignItems:"center",gap:8},appName:{flex:1,fontWeight:"600"},appIcon:{width:36,height:36,borderRadius:8},iconFallback:{width:36,height:36,alignItems:"center",justifyContent:"center",borderRadius:8,backgroundColor:o.color.fillSecondary},preview:{padding:16,gap:8,borderWidth:1,borderColor:o.color.glassBorder,borderRadius:20,backgroundColor:o.color.glass},input:{color:o.color.text,fontSize:14,padding:6,minHeight:36},title:{fontSize:16,fontWeight:"600"},result:{gap:10,padding:16,borderWidth:1,borderColor:o.color.glassBorder,borderRadius:14},resultTitle:{color:o.color.text,fontWeight:"500",fontSize:13,flexShrink:1},secondary:{alignSelf:"flex-start",paddingHorizontal:14,paddingVertical:8,borderRadius:24,backgroundColor:o.color.fillSecondary},secondaryText:{color:o.color.accent,fontSize:13},options:{flexDirection:"row",alignItems:"center",gap:6,paddingVertical:12},footer:{padding:14,gap:8,borderTopWidth:1,borderTopColor:o.color.separator},footerRow:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",justifyContent:"space-between",gap:12},hint:{flexGrow:1,flexShrink:1,flexBasis:200},send:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,borderRadius:24,paddingHorizontal:18,paddingVertical:12,backgroundColor:o.color.accent},sendText:{color:o.color.onAccent,fontSize:13,fontWeight:"600"},disabled:{opacity:.4},pressed:{opacity:.8},error:{color:o.color.danger,fontSize:12,lineHeight:18}});