@use-voltra/android 2.3.2 → 2.4.0
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/build/commonjs/index.js +25 -0
- package/build/commonjs/index.js.map +1 -1
- package/build/commonjs/jsx/primitives.js +36 -0
- package/build/commonjs/jsx/primitives.js.map +1 -1
- package/build/commonjs/modifiers/createAndroidModifier.js +20 -0
- package/build/commonjs/modifiers/createAndroidModifier.js.map +1 -0
- package/build/commonjs/modifiers/index.js +188 -0
- package/build/commonjs/modifiers/index.js.map +1 -0
- package/build/commonjs/ongoing-notification/components.js +7 -1
- package/build/commonjs/ongoing-notification/components.js.map +1 -1
- package/build/commonjs/ongoing-notification/renderer.js +354 -18
- package/build/commonjs/ongoing-notification/renderer.js.map +1 -1
- package/build/commonjs/ongoing-notification/types.js +56 -0
- package/build/commonjs/ongoing-notification/types.js.map +1 -1
- package/build/commonjs/server.js.map +1 -1
- package/build/module/index.js +3 -1
- package/build/module/index.js.map +1 -1
- package/build/module/jsx/primitives.js +1 -0
- package/build/module/jsx/primitives.js.map +1 -1
- package/build/module/modifiers/createAndroidModifier.js +15 -0
- package/build/module/modifiers/createAndroidModifier.js.map +1 -0
- package/build/module/modifiers/index.js +169 -0
- package/build/module/modifiers/index.js.map +1 -0
- package/build/module/ongoing-notification/components.js +6 -0
- package/build/module/ongoing-notification/components.js.map +1 -1
- package/build/module/ongoing-notification/renderer.js +354 -18
- package/build/module/ongoing-notification/renderer.js.map +1 -1
- package/build/module/ongoing-notification/types.js +55 -1
- package/build/module/ongoing-notification/types.js.map +1 -1
- package/build/module/server.js.map +1 -1
- package/build/typescript/commonjs/index.d.ts +4 -3
- package/build/typescript/commonjs/index.d.ts.map +1 -1
- package/build/typescript/commonjs/jsx/baseProps.d.ts +8 -0
- package/build/typescript/commonjs/jsx/baseProps.d.ts.map +1 -1
- package/build/typescript/commonjs/jsx/primitives.d.ts +1 -0
- package/build/typescript/commonjs/jsx/primitives.d.ts.map +1 -1
- package/build/typescript/commonjs/modifiers/createAndroidModifier.d.ts +13 -0
- package/build/typescript/commonjs/modifiers/createAndroidModifier.d.ts.map +1 -0
- package/build/typescript/commonjs/modifiers/index.d.ts +171 -0
- package/build/typescript/commonjs/modifiers/index.d.ts.map +1 -0
- package/build/typescript/commonjs/ongoing-notification/components.d.ts +8 -2
- package/build/typescript/commonjs/ongoing-notification/components.d.ts.map +1 -1
- package/build/typescript/commonjs/ongoing-notification/renderer.d.ts.map +1 -1
- package/build/typescript/commonjs/ongoing-notification/types.d.ts +281 -3
- package/build/typescript/commonjs/ongoing-notification/types.d.ts.map +1 -1
- package/build/typescript/commonjs/server.d.ts +1 -1
- package/build/typescript/commonjs/server.d.ts.map +1 -1
- package/build/typescript/module/index.d.ts +4 -3
- package/build/typescript/module/index.d.ts.map +1 -1
- package/build/typescript/module/jsx/baseProps.d.ts +8 -0
- package/build/typescript/module/jsx/baseProps.d.ts.map +1 -1
- package/build/typescript/module/jsx/primitives.d.ts +1 -0
- package/build/typescript/module/jsx/primitives.d.ts.map +1 -1
- package/build/typescript/module/modifiers/createAndroidModifier.d.ts +13 -0
- package/build/typescript/module/modifiers/createAndroidModifier.d.ts.map +1 -0
- package/build/typescript/module/modifiers/index.d.ts +171 -0
- package/build/typescript/module/modifiers/index.d.ts.map +1 -0
- package/build/typescript/module/ongoing-notification/components.d.ts +8 -2
- package/build/typescript/module/ongoing-notification/components.d.ts.map +1 -1
- package/build/typescript/module/ongoing-notification/renderer.d.ts.map +1 -1
- package/build/typescript/module/ongoing-notification/types.d.ts +281 -3
- package/build/typescript/module/ongoing-notification/types.d.ts.map +1 -1
- package/build/typescript/module/server.d.ts +1 -1
- package/build/typescript/module/server.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +36 -2
- package/src/jsx/baseProps.tsx +8 -0
- package/src/jsx/primitives.ts +1 -0
- package/src/modifiers/createAndroidModifier.ts +21 -0
- package/src/modifiers/index.ts +166 -0
- package/src/ongoing-notification/components.tsx +22 -1
- package/src/ongoing-notification/renderer.ts +451 -18
- package/src/ongoing-notification/types.ts +298 -4
- package/src/server.ts +15 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { createAndroidModifier } from './createAndroidModifier.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A static color string. Resolves to `never` for an `AndroidDynamicColors` token, so passing one
|
|
7
|
+
* where Glance needs a concrete color is a compile-time error.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** At least one of the two keys is required. */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Adds padding in dp, mirrored in right-to-left layouts. The most specific edge wins (`start` over
|
|
14
|
+
* `horizontal` over `all`). Glance adds repeated padding together, including `style.padding`.
|
|
15
|
+
*
|
|
16
|
+
* @since Android 7.0
|
|
17
|
+
*/
|
|
18
|
+
export const padding = values => {
|
|
19
|
+
if (typeof values === 'number') {
|
|
20
|
+
return createAndroidModifier('padding', {
|
|
21
|
+
all: values
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Copy only the known edges so extra keys on a caller's object never reach the device.
|
|
25
|
+
const {
|
|
26
|
+
all,
|
|
27
|
+
horizontal,
|
|
28
|
+
vertical,
|
|
29
|
+
start,
|
|
30
|
+
top,
|
|
31
|
+
end,
|
|
32
|
+
bottom
|
|
33
|
+
} = values;
|
|
34
|
+
return createAndroidModifier('padding', {
|
|
35
|
+
all,
|
|
36
|
+
horizontal,
|
|
37
|
+
vertical,
|
|
38
|
+
start,
|
|
39
|
+
top,
|
|
40
|
+
end,
|
|
41
|
+
bottom
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Adds padding in dp that ignores the layout direction. Adds up with `padding` and `style.padding`.
|
|
47
|
+
*
|
|
48
|
+
* @since Android 7.0
|
|
49
|
+
*/
|
|
50
|
+
export const absolutePadding = values => {
|
|
51
|
+
if (typeof values === 'number') {
|
|
52
|
+
return createAndroidModifier('absolutePadding', {
|
|
53
|
+
all: values
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const {
|
|
57
|
+
all,
|
|
58
|
+
horizontal,
|
|
59
|
+
vertical,
|
|
60
|
+
left,
|
|
61
|
+
top,
|
|
62
|
+
right,
|
|
63
|
+
bottom
|
|
64
|
+
} = values;
|
|
65
|
+
return createAndroidModifier('absolutePadding', {
|
|
66
|
+
all,
|
|
67
|
+
horizontal,
|
|
68
|
+
vertical,
|
|
69
|
+
left,
|
|
70
|
+
top,
|
|
71
|
+
right,
|
|
72
|
+
bottom
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Sets a fixed width in dp.
|
|
78
|
+
*
|
|
79
|
+
* @since Android 7.0
|
|
80
|
+
*/
|
|
81
|
+
export const width = dp => createAndroidModifier('width', {
|
|
82
|
+
width: dp
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Sets a fixed height in dp.
|
|
87
|
+
*
|
|
88
|
+
* @since Android 7.0
|
|
89
|
+
*/
|
|
90
|
+
export const height = dp => createAndroidModifier('height', {
|
|
91
|
+
height: dp
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Sets a fixed size in dp. A single number sets both dimensions.
|
|
96
|
+
*
|
|
97
|
+
* @since Android 7.0
|
|
98
|
+
*/
|
|
99
|
+
export const size = value => createAndroidModifier('size', typeof value === 'number' ? {
|
|
100
|
+
width: value,
|
|
101
|
+
height: value
|
|
102
|
+
} : {
|
|
103
|
+
width: value.width,
|
|
104
|
+
height: value.height
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/** @since Android 7.0 */
|
|
108
|
+
export const fillMaxWidth = () => createAndroidModifier('fillMaxWidth');
|
|
109
|
+
/** @since Android 7.0 */
|
|
110
|
+
export const fillMaxHeight = () => createAndroidModifier('fillMaxHeight');
|
|
111
|
+
/** @since Android 7.0 */
|
|
112
|
+
export const fillMaxSize = () => createAndroidModifier('fillMaxSize');
|
|
113
|
+
/** @since Android 7.0 */
|
|
114
|
+
export const wrapContentWidth = () => createAndroidModifier('wrapContentWidth');
|
|
115
|
+
/** @since Android 7.0 */
|
|
116
|
+
export const wrapContentHeight = () => createAndroidModifier('wrapContentHeight');
|
|
117
|
+
/** @since Android 7.0 */
|
|
118
|
+
export const wrapContentSize = () => createAndroidModifier('wrapContentSize');
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Fills the background with a color: a static color, an `AndroidDynamicColors` token, or a pair of
|
|
122
|
+
* static colors for light and dark mode.
|
|
123
|
+
*
|
|
124
|
+
* @since Android 7.0
|
|
125
|
+
*/
|
|
126
|
+
export const background = color => createAndroidModifier('background', typeof color === 'string' ? {
|
|
127
|
+
color
|
|
128
|
+
} : {
|
|
129
|
+
day: color.day,
|
|
130
|
+
night: color.night
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Rounds the corners in dp. Glance ignores it below Android 12 (API 31).
|
|
135
|
+
*
|
|
136
|
+
* @since Android 12
|
|
137
|
+
*/
|
|
138
|
+
export const cornerRadius = radius => createAndroidModifier('cornerRadius', {
|
|
139
|
+
radius
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Shows, hides (keeping its space), or removes the component from layout.
|
|
144
|
+
*
|
|
145
|
+
* @since Android 7.0
|
|
146
|
+
*/
|
|
147
|
+
export const visibility = value => createAndroidModifier('visibility', {
|
|
148
|
+
visibility: value
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Sets accessibility and test metadata.
|
|
153
|
+
*
|
|
154
|
+
* @since Android 7.0
|
|
155
|
+
*/
|
|
156
|
+
export const semantics = values => createAndroidModifier('semantics', {
|
|
157
|
+
contentDescription: values.contentDescription,
|
|
158
|
+
testTag: values.testTag
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Marks the widget's background view so the launcher can animate it when the widget opens the app.
|
|
163
|
+
* Use it once per widget, on the outermost component. Only one component keeps it: the first that
|
|
164
|
+
* appears once in the widget, and none inside a widget with a `Scaffold`, which marks its own.
|
|
165
|
+
*
|
|
166
|
+
* @since Android 12
|
|
167
|
+
*/
|
|
168
|
+
export const appWidgetBackground = () => createAndroidModifier('appWidgetBackground');
|
|
169
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAndroidModifier","padding","values","all","horizontal","vertical","start","top","end","bottom","absolutePadding","left","right","width","dp","height","size","value","fillMaxWidth","fillMaxHeight","fillMaxSize","wrapContentWidth","wrapContentHeight","wrapContentSize","background","color","day","night","cornerRadius","radius","visibility","semantics","contentDescription","testTag","appWidgetBackground"],"sourceRoot":"../../../src","sources":["modifiers/index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,10 +9,16 @@ const createAndroidOngoingNotificationComponent = (displayName, kind) => {
|
|
|
9
9
|
};
|
|
10
10
|
export const Progress = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.Progress', 'progress');
|
|
11
11
|
export const BigText = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.BigText', 'bigText');
|
|
12
|
+
export const BigPicture = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.BigPicture', 'bigPicture');
|
|
13
|
+
export const Inbox = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.Inbox', 'inbox');
|
|
14
|
+
export const Metric = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.Metric', 'metric');
|
|
12
15
|
export const Action = createAndroidOngoingNotificationComponent('AndroidOngoingNotification.Action', 'action');
|
|
13
16
|
export const AndroidOngoingNotification = {
|
|
14
17
|
Progress,
|
|
15
18
|
BigText,
|
|
19
|
+
BigPicture,
|
|
20
|
+
Inbox,
|
|
21
|
+
Metric,
|
|
16
22
|
Action
|
|
17
23
|
};
|
|
18
24
|
//# sourceMappingURL=components.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ANDROID_ONGOING_NOTIFICATION_COMPONENT_TAG","Symbol","for","createAndroidOngoingNotificationComponent","displayName","kind","Component","_props","Progress","BigText","Action","AndroidOngoingNotification"],"sourceRoot":"../../../src","sources":["ongoing-notification/components.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"names":["ANDROID_ONGOING_NOTIFICATION_COMPONENT_TAG","Symbol","for","createAndroidOngoingNotificationComponent","displayName","kind","Component","_props","Progress","BigText","BigPicture","Inbox","Metric","Action","AndroidOngoingNotification"],"sourceRoot":"../../../src","sources":["ongoing-notification/components.tsx"],"mappings":";;AAWA,OAAO,MAAMA,0CAA0C,GAAGC,MAAM,CAACC,GAAG,CAAC,+CAA+C,CAAC;AASrH,MAAMC,yCAAyC,GAAGA,CAChDC,WAAmB,EACnBC,IAA6C,KACG;EAChD,MAAMC,SAAS,GAAIC,MAAc,IAAK,IAAI;EAE1CD,SAAS,CAACF,WAAW,GAAGA,WAAW;EACjCE,SAAS,CAAiDN,0CAA0C,CAAC,GAAGK,IAAI;EAE9G,OAAOC,SAAS;AAClB,CAAC;AAED,OAAO,MAAME,QAAQ,GAAGL,yCAAyC,CAC/D,qCAAqC,EACrC,UACF,CAAC;AAED,OAAO,MAAMM,OAAO,GAAGN,yCAAyC,CAC9D,oCAAoC,EACpC,SACF,CAAC;AAED,OAAO,MAAMO,UAAU,GAAGP,yCAAyC,CACjE,uCAAuC,EACvC,YACF,CAAC;AAED,OAAO,MAAMQ,KAAK,GAAGR,yCAAyC,CAC5D,kCAAkC,EAClC,OACF,CAAC;AAED,OAAO,MAAMS,MAAM,GAAGT,yCAAyC,CAC7D,mCAAmC,EACnC,QACF,CAAC;AAED,OAAO,MAAMU,MAAM,GAAGV,yCAAyC,CAC7D,mCAAmC,EACnC,QACF,CAAC;AAED,OAAO,MAAMW,0BAA0B,GAAG;EACxCN,QAAQ;EACRC,OAAO;EACPC,UAAU;EACVC,KAAK;EACLC,MAAM;EACNC;AACF,CAAU","ignoreList":[]}
|
|
@@ -5,6 +5,24 @@ import { getAndroidComponentId } from '../payload/component-ids.js';
|
|
|
5
5
|
import { ANDROID_ONGOING_NOTIFICATION_COMPONENT_TAG } from './components.js';
|
|
6
6
|
void getAndroidComponentId;
|
|
7
7
|
const PAYLOAD_VERSION = 1;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* InboxStyle only renders six lines, so more than that is rejected at render time instead of being
|
|
11
|
+
* silently truncated. Kept in sync with MAX_INBOX_LINES in the Android client.
|
|
12
|
+
*/
|
|
13
|
+
const MAX_INBOX_LINES = 6;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Size of an inline picture that is still reasonable to hand to a native post. Push providers cap
|
|
17
|
+
* data payloads at a few kilobytes (FCM allows 4096 bytes), so no inline picture travels through a
|
|
18
|
+
* push message. Warns instead of failing: local starts and self-hosted transports can legitimately
|
|
19
|
+
* carry more. Compared against the decoded size, because a base64 string is four characters per
|
|
20
|
+
* three bytes and its length flatters the image.
|
|
21
|
+
*/
|
|
22
|
+
const MAX_INLINE_PICTURE_BYTES = 256 * 1024;
|
|
23
|
+
|
|
24
|
+
/** Bytes a base64 string holds once decoded. Padding leaves this at most two bytes high. */
|
|
25
|
+
const decodedBase64Bytes = base64 => Math.ceil(base64.length * 3 / 4);
|
|
8
26
|
const flattenChildren = node => {
|
|
9
27
|
if (node === null || node === undefined || typeof node === 'boolean') {
|
|
10
28
|
return [];
|
|
@@ -77,6 +95,13 @@ const assertOptionalImageSource = (value, propName) => {
|
|
|
77
95
|
}
|
|
78
96
|
return value;
|
|
79
97
|
};
|
|
98
|
+
const assertRequiredImageSource = (value, propName) => {
|
|
99
|
+
const source = assertOptionalImageSource(value, propName);
|
|
100
|
+
if (source === undefined) {
|
|
101
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}" is required.`);
|
|
102
|
+
}
|
|
103
|
+
return source;
|
|
104
|
+
};
|
|
80
105
|
const assertBoolean = (value, propName) => {
|
|
81
106
|
if (value === undefined) {
|
|
82
107
|
return undefined;
|
|
@@ -143,21 +168,91 @@ const normalizeProgressPoints = value => {
|
|
|
143
168
|
};
|
|
144
169
|
});
|
|
145
170
|
};
|
|
146
|
-
const
|
|
147
|
-
if (value
|
|
148
|
-
|
|
171
|
+
const normalizeInboxLines = value => {
|
|
172
|
+
if (!Array.isArray(value)) {
|
|
173
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "lines" must be an array of non-empty strings.');
|
|
174
|
+
}
|
|
175
|
+
if (value.length === 0) {
|
|
176
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "lines" must contain at least one line.');
|
|
149
177
|
}
|
|
178
|
+
if (value.length > MAX_INBOX_LINES) {
|
|
179
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "lines" must contain at most ${MAX_INBOX_LINES} lines, got ${value.length}.`);
|
|
180
|
+
}
|
|
181
|
+
return value.map((line, index) => assertString(line, `lines[${index}]`));
|
|
182
|
+
};
|
|
183
|
+
const warnInlinePicture = picture => {
|
|
184
|
+
const base64 = 'base64' in picture ? picture.base64 : undefined;
|
|
185
|
+
if (base64 === undefined) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const pictureBytes = decodedBase64Bytes(base64);
|
|
189
|
+
if (pictureBytes > MAX_INLINE_PICTURE_BYTES) {
|
|
190
|
+
console.warn(`[Voltra] [Android] Ongoing notification prop "picture" carries a ${pictureBytes}-byte image, which exceeds ${MAX_INLINE_PICTURE_BYTES} bytes. Inline pictures cannot travel through push messages: preload the image and reference it with assetName instead.`);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const normalizeEpoch = (value, propName) => {
|
|
150
194
|
if (value instanceof Date) {
|
|
151
195
|
const timestamp = value.getTime();
|
|
152
196
|
if (!Number.isFinite(timestamp)) {
|
|
153
|
-
throw new Error(
|
|
197
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}" must be a valid Date or timestamp.`);
|
|
154
198
|
}
|
|
155
199
|
return timestamp;
|
|
156
200
|
}
|
|
157
201
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
158
202
|
return value;
|
|
159
203
|
}
|
|
160
|
-
throw new Error(
|
|
204
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}" must be a valid Date or timestamp.`);
|
|
205
|
+
};
|
|
206
|
+
const normalizeWhen = value => {
|
|
207
|
+
if (value === undefined) {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
return normalizeEpoch(value, 'when');
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// `true` keeps meaning "count up" for payloads and props written before the
|
|
214
|
+
// chip gained a direction; only 'countDown' sets chronometerCountDown, and a
|
|
215
|
+
// countdown without `when` has nothing to count down to.
|
|
216
|
+
const normalizeChronometer = (value, when) => {
|
|
217
|
+
if (value === undefined) {
|
|
218
|
+
return {};
|
|
219
|
+
}
|
|
220
|
+
if (typeof value === 'boolean') {
|
|
221
|
+
return {
|
|
222
|
+
chronometer: value
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (value === 'countUp') {
|
|
226
|
+
return {
|
|
227
|
+
chronometer: true
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (value === 'countDown') {
|
|
231
|
+
if (when === undefined) {
|
|
232
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "chronometer" set to "countDown" requires the "when" prop.');
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
chronometer: true,
|
|
236
|
+
chronometerCountDown: true
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "chronometer" must be a boolean, "countUp" or "countDown".');
|
|
240
|
+
};
|
|
241
|
+
const normalizePublicVersion = value => {
|
|
242
|
+
if (value === undefined) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
246
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "publicVersion" must be an object with a title.');
|
|
247
|
+
}
|
|
248
|
+
const {
|
|
249
|
+
title,
|
|
250
|
+
text
|
|
251
|
+
} = value;
|
|
252
|
+
return {
|
|
253
|
+
title: assertString(title, 'publicVersion.title'),
|
|
254
|
+
text: assertOptionalString(text, 'publicVersion.text')
|
|
255
|
+
};
|
|
161
256
|
};
|
|
162
257
|
const getElementKind = element => {
|
|
163
258
|
const elementType = element.type;
|
|
@@ -170,6 +265,19 @@ const normalizeActionPayload = props => {
|
|
|
170
265
|
icon: assertOptionalImageSource(props.icon, 'icon')
|
|
171
266
|
};
|
|
172
267
|
};
|
|
268
|
+
const normalizeCommonDisplayFields = props => {
|
|
269
|
+
const when = normalizeWhen(props.when);
|
|
270
|
+
return {
|
|
271
|
+
title: assertOptionalNonEmptyString(props.title, 'title'),
|
|
272
|
+
subText: assertOptionalString(props.subText, 'subText'),
|
|
273
|
+
shortCriticalText: assertOptionalString(props.shortCriticalText, 'shortCriticalText'),
|
|
274
|
+
when,
|
|
275
|
+
...normalizeChronometer(props.chronometer, when),
|
|
276
|
+
showWhen: assertBoolean(props.showWhen, 'showWhen'),
|
|
277
|
+
largeIcon: assertOptionalImageSource(props.largeIcon, 'largeIcon'),
|
|
278
|
+
publicVersion: normalizePublicVersion(props.publicVersion)
|
|
279
|
+
};
|
|
280
|
+
};
|
|
173
281
|
const normalizeActions = value => {
|
|
174
282
|
const actions = [];
|
|
175
283
|
Children.forEach(value, child => {
|
|
@@ -202,16 +310,11 @@ const normalizeProgressPayload = props => {
|
|
|
202
310
|
return {
|
|
203
311
|
v: PAYLOAD_VERSION,
|
|
204
312
|
kind: 'progress',
|
|
205
|
-
|
|
206
|
-
subText: assertOptionalString(props.subText, 'subText'),
|
|
313
|
+
...normalizeCommonDisplayFields(props),
|
|
207
314
|
text: assertOptionalString(props.text, 'text'),
|
|
208
315
|
value,
|
|
209
316
|
max,
|
|
210
317
|
indeterminate: assertBoolean(props.indeterminate, 'indeterminate'),
|
|
211
|
-
shortCriticalText: assertOptionalString(props.shortCriticalText, 'shortCriticalText'),
|
|
212
|
-
when: normalizeWhen(props.when),
|
|
213
|
-
chronometer: assertBoolean(props.chronometer, 'chronometer'),
|
|
214
|
-
largeIcon: assertOptionalImageSource(props.largeIcon, 'largeIcon'),
|
|
215
318
|
progressTrackerIcon: assertOptionalImageSource(props.progressTrackerIcon, 'progressTrackerIcon'),
|
|
216
319
|
progressStartIcon: assertOptionalImageSource(props.progressStartIcon, 'progressStartIcon'),
|
|
217
320
|
progressEndIcon: assertOptionalImageSource(props.progressEndIcon, 'progressEndIcon'),
|
|
@@ -225,14 +328,238 @@ const normalizeBigTextPayload = props => {
|
|
|
225
328
|
return {
|
|
226
329
|
v: PAYLOAD_VERSION,
|
|
227
330
|
kind: 'bigText',
|
|
228
|
-
|
|
229
|
-
subText: assertOptionalString(props.subText, 'subText'),
|
|
331
|
+
...normalizeCommonDisplayFields(props),
|
|
230
332
|
text,
|
|
231
333
|
bigText: assertOptionalString(props.bigText, 'bigText') ?? text,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
334
|
+
actions: normalizeActions(props.children)
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
const METRIC_TIME_PATTERN = /^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/;
|
|
338
|
+
const METRIC_SEMANTIC_STYLES = ['unspecified', 'info', 'safe', 'caution', 'danger'];
|
|
339
|
+
const METRIC_TIME_FORMATS = ['adaptive', 'chronometer'];
|
|
340
|
+
const assertMetricNonEmptyString = (value, propName) => {
|
|
341
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
342
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}" must be a non-empty string.`);
|
|
343
|
+
}
|
|
344
|
+
return value;
|
|
345
|
+
};
|
|
346
|
+
const normalizeMetricTimeFormat = (value, propName) => {
|
|
347
|
+
if (value === undefined) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
if (!METRIC_TIME_FORMATS.includes(value)) {
|
|
351
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}" must be "adaptive" or "chronometer".`);
|
|
352
|
+
}
|
|
353
|
+
return value;
|
|
354
|
+
};
|
|
355
|
+
const normalizeMetricValue = (value, unit, propName) => {
|
|
356
|
+
const topLevelUnit = assertOptionalString(unit, `${propName}.unit`);
|
|
357
|
+
const rejectTopLevelUnit = () => {
|
|
358
|
+
if (topLevelUnit !== undefined) {
|
|
359
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.unit" only applies to "int", "float" and "text" values.`);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Shorthands: an integer reads as int, any other number as float, a string as text.
|
|
364
|
+
if (typeof value === 'number') {
|
|
365
|
+
if (!Number.isFinite(value)) {
|
|
366
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.value" must be a finite number.`);
|
|
367
|
+
}
|
|
368
|
+
return Number.isInteger(value) ? {
|
|
369
|
+
type: 'int',
|
|
370
|
+
value,
|
|
371
|
+
unit: topLevelUnit
|
|
372
|
+
} : {
|
|
373
|
+
type: 'float',
|
|
374
|
+
value,
|
|
375
|
+
unit: topLevelUnit
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
if (typeof value === 'string') {
|
|
379
|
+
return {
|
|
380
|
+
type: 'text',
|
|
381
|
+
value: assertMetricNonEmptyString(value, `${propName}.value`),
|
|
382
|
+
unit: topLevelUnit
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
386
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.value" must be a number, a string, or a metric value object.`);
|
|
387
|
+
}
|
|
388
|
+
const source = value;
|
|
389
|
+
const type = source.type;
|
|
390
|
+
switch (type) {
|
|
391
|
+
case 'int':
|
|
392
|
+
{
|
|
393
|
+
const numberValue = assertFiniteNumber(source.value, `${propName}.value`);
|
|
394
|
+
if (!Number.isInteger(numberValue)) {
|
|
395
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.value" must be an integer.`);
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
type: 'int',
|
|
399
|
+
value: numberValue,
|
|
400
|
+
unit: assertOptionalString(source.unit, `${propName}.unit`) ?? topLevelUnit
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
case 'float':
|
|
404
|
+
{
|
|
405
|
+
const numberValue = assertFiniteNumber(source.value, `${propName}.value`);
|
|
406
|
+
const min = source.min === undefined ? undefined : assertFiniteNumber(source.min, `${propName}.min`);
|
|
407
|
+
const max = source.max === undefined ? undefined : assertFiniteNumber(source.max, `${propName}.max`);
|
|
408
|
+
if (min !== undefined && min < 0) {
|
|
409
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.min" must be greater than or equal to 0.`);
|
|
410
|
+
}
|
|
411
|
+
if (max !== undefined && max < 0) {
|
|
412
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.max" must be greater than or equal to 0.`);
|
|
413
|
+
}
|
|
414
|
+
if (min !== undefined && max !== undefined && min > max) {
|
|
415
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.min" must not exceed "${propName}.max".`);
|
|
416
|
+
}
|
|
417
|
+
let fractionDigits;
|
|
418
|
+
if (source.fractionDigits !== undefined) {
|
|
419
|
+
fractionDigits = assertFiniteNumber(source.fractionDigits, `${propName}.fractionDigits`);
|
|
420
|
+
if (!Number.isInteger(fractionDigits) || fractionDigits < 0) {
|
|
421
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.fractionDigits" must be an integer greater than or equal to 0.`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return {
|
|
425
|
+
type: 'float',
|
|
426
|
+
value: numberValue,
|
|
427
|
+
unit: assertOptionalString(source.unit, `${propName}.unit`) ?? topLevelUnit,
|
|
428
|
+
min,
|
|
429
|
+
max,
|
|
430
|
+
fractionDigits
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
case 'text':
|
|
434
|
+
return {
|
|
435
|
+
type: 'text',
|
|
436
|
+
value: assertMetricNonEmptyString(source.value, `${propName}.value`),
|
|
437
|
+
unit: assertOptionalString(source.unit, `${propName}.unit`) ?? topLevelUnit
|
|
438
|
+
};
|
|
439
|
+
case 'time':
|
|
440
|
+
{
|
|
441
|
+
rejectTopLevelUnit();
|
|
442
|
+
const timeValue = assertMetricNonEmptyString(source.value, `${propName}.value`);
|
|
443
|
+
if (!METRIC_TIME_PATTERN.test(timeValue)) {
|
|
444
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.value" must be a time in "HH:mm" or "HH:mm:ss" form.`);
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
type: 'time',
|
|
448
|
+
value: timeValue
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
case 'timer':
|
|
452
|
+
rejectTopLevelUnit();
|
|
453
|
+
return {
|
|
454
|
+
type: 'timer',
|
|
455
|
+
endsAt: normalizeEpoch(source.endsAt, `${propName}.endsAt`),
|
|
456
|
+
format: normalizeMetricTimeFormat(source.format, `${propName}.format`)
|
|
457
|
+
};
|
|
458
|
+
case 'stopwatch':
|
|
459
|
+
rejectTopLevelUnit();
|
|
460
|
+
return {
|
|
461
|
+
type: 'stopwatch',
|
|
462
|
+
startedAt: normalizeEpoch(source.startedAt, `${propName}.startedAt`),
|
|
463
|
+
format: normalizeMetricTimeFormat(source.format, `${propName}.format`)
|
|
464
|
+
};
|
|
465
|
+
case 'pausedTimer':
|
|
466
|
+
{
|
|
467
|
+
rejectTopLevelUnit();
|
|
468
|
+
const remainingMillis = assertFiniteNumber(source.remainingMillis, `${propName}.remainingMillis`);
|
|
469
|
+
if (remainingMillis < 0) {
|
|
470
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.remainingMillis" must be greater than or equal to 0.`);
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
type: 'pausedTimer',
|
|
474
|
+
remainingMillis
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
case 'pausedStopwatch':
|
|
478
|
+
{
|
|
479
|
+
rejectTopLevelUnit();
|
|
480
|
+
const elapsedMillis = assertFiniteNumber(source.elapsedMillis, `${propName}.elapsedMillis`);
|
|
481
|
+
if (elapsedMillis < 0) {
|
|
482
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.elapsedMillis" must be greater than or equal to 0.`);
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
type: 'pausedStopwatch',
|
|
486
|
+
elapsedMillis
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
default:
|
|
490
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "${propName}.type" must be "int", "float", "text", "time", "timer", "stopwatch", "pausedTimer", or "pausedStopwatch".`);
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
const normalizeMetricPayload = props => {
|
|
494
|
+
if (!Array.isArray(props.metrics)) {
|
|
495
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "metrics" must be an array.');
|
|
496
|
+
}
|
|
497
|
+
if (props.metrics.length < 1 || props.metrics.length > 3) {
|
|
498
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "metrics" must contain between 1 and 3 metrics.');
|
|
499
|
+
}
|
|
500
|
+
const metrics = props.metrics.map((descriptor, index) => {
|
|
501
|
+
if (!descriptor || typeof descriptor !== 'object' || Array.isArray(descriptor)) {
|
|
502
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "metrics[${index}]" must be an object.`);
|
|
503
|
+
}
|
|
504
|
+
const label = assertMetricNonEmptyString(descriptor.label, `metrics[${index}].label`);
|
|
505
|
+
if (label.length > 10) {
|
|
506
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "metrics[${index}].label" must be at most 10 characters long.`);
|
|
507
|
+
}
|
|
508
|
+
return {
|
|
509
|
+
label,
|
|
510
|
+
value: normalizeMetricValue(descriptor.value, descriptor.unit, `metrics[${index}]`)
|
|
511
|
+
};
|
|
512
|
+
});
|
|
513
|
+
let criticalMetric;
|
|
514
|
+
if (props.criticalMetric !== undefined) {
|
|
515
|
+
criticalMetric = assertFiniteNumber(props.criticalMetric, 'criticalMetric');
|
|
516
|
+
if (!Number.isInteger(criticalMetric) || criticalMetric < 0 || criticalMetric >= metrics.length) {
|
|
517
|
+
throw new Error(`[Voltra] [Android] Ongoing notification prop "criticalMetric" must be an index between 0 and ${metrics.length - 1}.`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
let semanticStyle;
|
|
521
|
+
if (props.semanticStyle !== undefined) {
|
|
522
|
+
if (!METRIC_SEMANTIC_STYLES.includes(props.semanticStyle)) {
|
|
523
|
+
throw new Error('[Voltra] [Android] Ongoing notification prop "semanticStyle" must be "unspecified", "info", "safe", "caution", or "danger".');
|
|
524
|
+
}
|
|
525
|
+
semanticStyle = props.semanticStyle;
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
v: PAYLOAD_VERSION,
|
|
529
|
+
kind: 'metric',
|
|
530
|
+
...normalizeCommonDisplayFields(props),
|
|
531
|
+
metrics,
|
|
532
|
+
criticalMetric,
|
|
533
|
+
semanticStyle,
|
|
534
|
+
actions: normalizeActions(props.children)
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
const normalizeBigPicturePayload = props => {
|
|
538
|
+
const picture = assertRequiredImageSource(props.picture, 'picture');
|
|
539
|
+
warnInlinePicture(picture);
|
|
540
|
+
return {
|
|
541
|
+
v: PAYLOAD_VERSION,
|
|
542
|
+
kind: 'bigPicture',
|
|
543
|
+
...normalizeCommonDisplayFields(props),
|
|
544
|
+
text: assertOptionalString(props.text, 'text'),
|
|
545
|
+
picture,
|
|
546
|
+
summaryText: assertOptionalNonEmptyString(props.summaryText, 'summaryText'),
|
|
547
|
+
pictureContentDescription: assertOptionalNonEmptyString(props.pictureContentDescription, 'pictureContentDescription'),
|
|
548
|
+
showPictureWhenCollapsed: assertBoolean(props.showPictureWhenCollapsed, 'showPictureWhenCollapsed'),
|
|
549
|
+
bigLargeIcon: assertOptionalImageSource(props.bigLargeIcon, 'bigLargeIcon'),
|
|
550
|
+
hideLargeIconWhenExpanded: assertBoolean(props.hideLargeIconWhenExpanded, 'hideLargeIconWhenExpanded'),
|
|
551
|
+
actions: normalizeActions(props.children)
|
|
552
|
+
};
|
|
553
|
+
};
|
|
554
|
+
const normalizeInboxPayload = props => {
|
|
555
|
+
const lines = normalizeInboxLines(props.lines);
|
|
556
|
+
return {
|
|
557
|
+
v: PAYLOAD_VERSION,
|
|
558
|
+
kind: 'inbox',
|
|
559
|
+
...normalizeCommonDisplayFields(props),
|
|
560
|
+
text: props.text === undefined ? lines[0] : assertString(props.text, 'text'),
|
|
561
|
+
lines,
|
|
562
|
+
summaryText: assertOptionalNonEmptyString(props.summaryText, 'summaryText'),
|
|
236
563
|
actions: normalizeActions(props.children)
|
|
237
564
|
};
|
|
238
565
|
};
|
|
@@ -245,7 +572,16 @@ export const renderAndroidOngoingNotificationPayloadToJson = content => {
|
|
|
245
572
|
if (kind === 'bigText') {
|
|
246
573
|
return normalizeBigTextPayload(element.props);
|
|
247
574
|
}
|
|
248
|
-
|
|
575
|
+
if (kind === 'bigPicture') {
|
|
576
|
+
return normalizeBigPicturePayload(element.props);
|
|
577
|
+
}
|
|
578
|
+
if (kind === 'inbox') {
|
|
579
|
+
return normalizeInboxPayload(element.props);
|
|
580
|
+
}
|
|
581
|
+
if (kind === 'metric') {
|
|
582
|
+
return normalizeMetricPayload(element.props);
|
|
583
|
+
}
|
|
584
|
+
throw new Error('[Voltra] [Android] Ongoing notification content must use AndroidOngoingNotification.Progress, AndroidOngoingNotification.BigText, AndroidOngoingNotification.BigPicture, AndroidOngoingNotification.Inbox, or AndroidOngoingNotification.Metric.');
|
|
249
585
|
};
|
|
250
586
|
export const renderAndroidOngoingNotificationPayload = content => {
|
|
251
587
|
return JSON.stringify(renderAndroidOngoingNotificationPayloadToJson(content));
|