@choochmeque/tauri-plugin-notifications-api 0.1.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/LICENSE +21 -0
- package/README.md +550 -0
- package/dist-js/index.cjs +319 -0
- package/dist-js/index.d.ts +456 -0
- package/dist-js/index.js +302 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 - Present Tauri Apps Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/@choochmeque/tauri-plugin-notifications-api)
|
|
2
|
+
[](https://crates.io/crates/tauri-plugin-notifications)
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
|
|
5
|
+
# Tauri Plugin Notifications
|
|
6
|
+
|
|
7
|
+
A Tauri v2 plugin for sending system notifications on desktop and mobile platforms. Send toast notifications (brief auto-expiring OS window elements) to your user with support for rich content, scheduling, actions, and channels.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Send simple and rich notifications
|
|
12
|
+
- Schedule notifications for specific dates or recurring intervals
|
|
13
|
+
- Interactive notifications with custom actions
|
|
14
|
+
- Notification channels (Android) for organized notifications
|
|
15
|
+
- Manage pending and active notifications
|
|
16
|
+
- Support for attachments, icons, and custom sounds
|
|
17
|
+
- Inbox and large text notification styles
|
|
18
|
+
- Group notifications with summary support
|
|
19
|
+
- Permission management
|
|
20
|
+
- Real-time notification events
|
|
21
|
+
|
|
22
|
+
## Platform Support
|
|
23
|
+
|
|
24
|
+
- **macOS**: Native notification center integration
|
|
25
|
+
- **Windows**: Windows notification system
|
|
26
|
+
- **Linux**: notify-rust with desktop notification support
|
|
27
|
+
- **iOS**: User Notifications framework
|
|
28
|
+
- **Android**: Android notification system with channels
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
Install the JavaScript package:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @choochmeque/tauri-plugin-notifications-api
|
|
36
|
+
# or
|
|
37
|
+
yarn add @choochmeque/tauri-plugin-notifications-api
|
|
38
|
+
# or
|
|
39
|
+
pnpm add @choochmeque/tauri-plugin-notifications-api
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Add the plugin to your Tauri project's `Cargo.toml`:
|
|
43
|
+
|
|
44
|
+
```toml
|
|
45
|
+
[dependencies]
|
|
46
|
+
tauri-plugin-notifications = "0.1"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Configure the plugin permissions in your `capabilities/default.json`:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"permissions": [
|
|
54
|
+
"notifications:default"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Register the plugin in your Tauri app:
|
|
60
|
+
|
|
61
|
+
```rust
|
|
62
|
+
fn main() {
|
|
63
|
+
tauri::Builder::default()
|
|
64
|
+
.plugin(tauri_plugin_notifications::init())
|
|
65
|
+
.run(tauri::generate_context!())
|
|
66
|
+
.expect("error while running tauri application");
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
### JavaScript/TypeScript
|
|
73
|
+
|
|
74
|
+
#### Basic Notifications
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import {
|
|
78
|
+
isPermissionGranted,
|
|
79
|
+
requestPermission,
|
|
80
|
+
sendNotification
|
|
81
|
+
} from '@choochmeque/tauri-plugin-notifications-api';
|
|
82
|
+
|
|
83
|
+
// Check and request permission
|
|
84
|
+
let permissionGranted = await isPermissionGranted();
|
|
85
|
+
if (!permissionGranted) {
|
|
86
|
+
const permission = await requestPermission();
|
|
87
|
+
permissionGranted = permission === 'granted';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Send simple notification
|
|
91
|
+
if (permissionGranted) {
|
|
92
|
+
sendNotification('Hello from Tauri!');
|
|
93
|
+
|
|
94
|
+
// Or with more details
|
|
95
|
+
sendNotification({
|
|
96
|
+
title: 'TAURI',
|
|
97
|
+
body: 'Tauri is awesome!'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Rich Notifications
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { sendNotification } from '@choochmeque/tauri-plugin-notifications-api';
|
|
106
|
+
|
|
107
|
+
// Notification with icon and sound
|
|
108
|
+
await sendNotification({
|
|
109
|
+
id: 1,
|
|
110
|
+
title: 'New Message',
|
|
111
|
+
body: 'You have a new message from John',
|
|
112
|
+
icon: 'message_icon',
|
|
113
|
+
sound: 'notification_sound',
|
|
114
|
+
autoCancel: true
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Large text notification
|
|
118
|
+
await sendNotification({
|
|
119
|
+
id: 2,
|
|
120
|
+
title: 'Article',
|
|
121
|
+
body: 'New article available',
|
|
122
|
+
largeBody: 'This is a much longer text that will be displayed when the user expands the notification...',
|
|
123
|
+
summary: 'Read more'
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Inbox style notification
|
|
127
|
+
await sendNotification({
|
|
128
|
+
id: 3,
|
|
129
|
+
title: 'Email',
|
|
130
|
+
body: '3 new emails',
|
|
131
|
+
inboxLines: [
|
|
132
|
+
'Alice: Meeting at 3pm',
|
|
133
|
+
'Bob: Project update',
|
|
134
|
+
'Charlie: Lunch tomorrow?'
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Scheduled Notifications
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { sendNotification, Schedule } from '@choochmeque/tauri-plugin-notifications-api';
|
|
143
|
+
|
|
144
|
+
// Schedule notification for specific date
|
|
145
|
+
await sendNotification({
|
|
146
|
+
title: 'Reminder',
|
|
147
|
+
body: 'Time for your meeting!',
|
|
148
|
+
schedule: Schedule.at(new Date(2024, 0, 15, 14, 30))
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Repeating notification
|
|
152
|
+
await sendNotification({
|
|
153
|
+
title: 'Daily Reminder',
|
|
154
|
+
body: 'Don\'t forget to exercise!',
|
|
155
|
+
schedule: Schedule.at(new Date(2024, 0, 15, 9, 0), true)
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Schedule with interval
|
|
159
|
+
await sendNotification({
|
|
160
|
+
title: 'Break Time',
|
|
161
|
+
body: 'Time to take a break!',
|
|
162
|
+
schedule: Schedule.interval({
|
|
163
|
+
hour: 1
|
|
164
|
+
})
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Schedule every X units
|
|
168
|
+
import { ScheduleEvery } from '@choochmeque/tauri-plugin-notifications-api';
|
|
169
|
+
|
|
170
|
+
await sendNotification({
|
|
171
|
+
title: 'Hourly Update',
|
|
172
|
+
body: 'Checking in every hour',
|
|
173
|
+
schedule: Schedule.every(ScheduleEvery.Hour, 1)
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Interactive Notifications with Actions
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import {
|
|
181
|
+
sendNotification,
|
|
182
|
+
registerActionTypes,
|
|
183
|
+
onAction
|
|
184
|
+
} from '@choochmeque/tauri-plugin-notifications-api';
|
|
185
|
+
|
|
186
|
+
// Register action types
|
|
187
|
+
await registerActionTypes([{
|
|
188
|
+
id: 'message-actions',
|
|
189
|
+
actions: [
|
|
190
|
+
{
|
|
191
|
+
id: 'reply',
|
|
192
|
+
title: 'Reply',
|
|
193
|
+
input: true,
|
|
194
|
+
inputPlaceholder: 'Type your reply...',
|
|
195
|
+
inputButtonTitle: 'Send'
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'mark-read',
|
|
199
|
+
title: 'Mark as Read'
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: 'delete',
|
|
203
|
+
title: 'Delete',
|
|
204
|
+
destructive: true
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}]);
|
|
208
|
+
|
|
209
|
+
// Send notification with actions
|
|
210
|
+
await sendNotification({
|
|
211
|
+
title: 'New Message',
|
|
212
|
+
body: 'You have a new message',
|
|
213
|
+
actionTypeId: 'message-actions'
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Listen for action events
|
|
217
|
+
const unlisten = await onAction((notification) => {
|
|
218
|
+
console.log('Action performed on notification:', notification);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Stop listening
|
|
222
|
+
unlisten();
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Notification Channels (Android)
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import {
|
|
229
|
+
createChannel,
|
|
230
|
+
channels,
|
|
231
|
+
removeChannel,
|
|
232
|
+
Importance,
|
|
233
|
+
Visibility
|
|
234
|
+
} from '@choochmeque/tauri-plugin-notifications-api';
|
|
235
|
+
|
|
236
|
+
// Create a notification channel
|
|
237
|
+
await createChannel({
|
|
238
|
+
id: 'messages',
|
|
239
|
+
name: 'Messages',
|
|
240
|
+
description: 'Notifications for new messages',
|
|
241
|
+
importance: Importance.High,
|
|
242
|
+
visibility: Visibility.Private,
|
|
243
|
+
sound: 'message_sound',
|
|
244
|
+
vibration: true,
|
|
245
|
+
lights: true,
|
|
246
|
+
lightColor: '#FF0000'
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Send notification to specific channel
|
|
250
|
+
await sendNotification({
|
|
251
|
+
channelId: 'messages',
|
|
252
|
+
title: 'New Message',
|
|
253
|
+
body: 'You have a new message'
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// List all channels
|
|
257
|
+
const channelList = await channels();
|
|
258
|
+
|
|
259
|
+
// Remove a channel
|
|
260
|
+
await removeChannel('messages');
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### Managing Notifications
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import {
|
|
267
|
+
pending,
|
|
268
|
+
active,
|
|
269
|
+
cancel,
|
|
270
|
+
cancelAll,
|
|
271
|
+
removeActive,
|
|
272
|
+
removeAllActive
|
|
273
|
+
} from '@choochmeque/tauri-plugin-notifications-api';
|
|
274
|
+
|
|
275
|
+
// Get pending notifications
|
|
276
|
+
const pendingNotifications = await pending();
|
|
277
|
+
|
|
278
|
+
// Cancel specific pending notifications
|
|
279
|
+
await cancel([1, 2, 3]);
|
|
280
|
+
|
|
281
|
+
// Cancel all pending notifications
|
|
282
|
+
await cancelAll();
|
|
283
|
+
|
|
284
|
+
// Get active notifications
|
|
285
|
+
const activeNotifications = await active();
|
|
286
|
+
|
|
287
|
+
// Remove specific active notifications
|
|
288
|
+
await removeActive([
|
|
289
|
+
{ id: 1 },
|
|
290
|
+
{ id: 2, tag: 'message' }
|
|
291
|
+
]);
|
|
292
|
+
|
|
293
|
+
// Remove all active notifications
|
|
294
|
+
await removeAllActive();
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### Notification Events
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
import { onNotificationReceived } from '@choochmeque/tauri-plugin-notifications-api';
|
|
301
|
+
|
|
302
|
+
// Listen for notifications received
|
|
303
|
+
const unlisten = await onNotificationReceived((notification) => {
|
|
304
|
+
console.log('Notification received:', notification);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Stop listening
|
|
308
|
+
unlisten();
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Rust
|
|
312
|
+
|
|
313
|
+
```rust
|
|
314
|
+
use tauri_plugin_notifications::{NotificationExt, Schedule, ScheduleEvery};
|
|
315
|
+
|
|
316
|
+
// Send simple notification
|
|
317
|
+
app.notification()
|
|
318
|
+
.builder()
|
|
319
|
+
.title("Hello")
|
|
320
|
+
.body("This is a notification from Rust!")
|
|
321
|
+
.show()?;
|
|
322
|
+
|
|
323
|
+
// Send rich notification
|
|
324
|
+
app.notification()
|
|
325
|
+
.builder()
|
|
326
|
+
.id(1)
|
|
327
|
+
.title("New Message")
|
|
328
|
+
.body("You have a new message")
|
|
329
|
+
.icon("message_icon")
|
|
330
|
+
.sound("notification_sound")
|
|
331
|
+
.auto_cancel()
|
|
332
|
+
.show()?;
|
|
333
|
+
|
|
334
|
+
// Scheduled notification
|
|
335
|
+
app.notification()
|
|
336
|
+
.builder()
|
|
337
|
+
.title("Reminder")
|
|
338
|
+
.body("Time for your meeting!")
|
|
339
|
+
.schedule(Schedule::at(date_time, false, false))
|
|
340
|
+
.show()?;
|
|
341
|
+
|
|
342
|
+
// Notification with attachments
|
|
343
|
+
use tauri_plugin_notifications::Attachment;
|
|
344
|
+
|
|
345
|
+
app.notification()
|
|
346
|
+
.builder()
|
|
347
|
+
.title("Photo Shared")
|
|
348
|
+
.body("Check out this image!")
|
|
349
|
+
.attachment(Attachment {
|
|
350
|
+
id: "image1".to_string(),
|
|
351
|
+
url: "file:///path/to/image.jpg".to_string(),
|
|
352
|
+
})
|
|
353
|
+
.show()?;
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## API Reference
|
|
357
|
+
|
|
358
|
+
### `isPermissionGranted()`
|
|
359
|
+
Checks if the permission to send notifications is granted.
|
|
360
|
+
|
|
361
|
+
**Returns:** `Promise<boolean>`
|
|
362
|
+
|
|
363
|
+
### `requestPermission()`
|
|
364
|
+
Requests the permission to send notifications.
|
|
365
|
+
|
|
366
|
+
**Returns:** `Promise<'granted' | 'denied' | 'default'>`
|
|
367
|
+
|
|
368
|
+
### `sendNotification(options: Options | string)`
|
|
369
|
+
Sends a notification to the user. Can be called with a simple string for the title or with a detailed options object.
|
|
370
|
+
|
|
371
|
+
**Parameters:**
|
|
372
|
+
- `options`: Notification options or title string
|
|
373
|
+
- `id`: Notification identifier (32-bit integer)
|
|
374
|
+
- `channelId`: Channel identifier (Android)
|
|
375
|
+
- `title`: Notification title
|
|
376
|
+
- `body`: Notification body
|
|
377
|
+
- `schedule`: Schedule for delayed or recurring notifications
|
|
378
|
+
- `largeBody`: Multiline text content
|
|
379
|
+
- `summary`: Detail text for large notifications
|
|
380
|
+
- `actionTypeId`: Action type identifier
|
|
381
|
+
- `group`: Group identifier
|
|
382
|
+
- `groupSummary`: Mark as group summary (Android)
|
|
383
|
+
- `sound`: Sound resource name
|
|
384
|
+
- `inboxLines`: Array of lines for inbox style (max 5)
|
|
385
|
+
- `icon`: Notification icon
|
|
386
|
+
- `largeIcon`: Large icon (Android)
|
|
387
|
+
- `iconColor`: Icon color (Android)
|
|
388
|
+
- `attachments`: Array of attachments
|
|
389
|
+
- `extra`: Extra payload data
|
|
390
|
+
- `ongoing`: Non-dismissible notification (Android)
|
|
391
|
+
- `autoCancel`: Auto-cancel on click
|
|
392
|
+
- `silent`: Silent notification (iOS)
|
|
393
|
+
- `visibility`: Notification visibility
|
|
394
|
+
- `number`: Number of items (Android)
|
|
395
|
+
|
|
396
|
+
### `registerActionTypes(types: ActionType[])`
|
|
397
|
+
Register actions that are performed when the user clicks on the notification.
|
|
398
|
+
|
|
399
|
+
**Parameters:**
|
|
400
|
+
- `types`: Array of action type objects with:
|
|
401
|
+
- `id`: Action type identifier
|
|
402
|
+
- `actions`: Array of action objects
|
|
403
|
+
- `id`: Action identifier
|
|
404
|
+
- `title`: Action title
|
|
405
|
+
- `requiresAuthentication`: Requires device unlock
|
|
406
|
+
- `foreground`: Opens app in foreground
|
|
407
|
+
- `destructive`: Destructive action style
|
|
408
|
+
- `input`: Enable text input
|
|
409
|
+
- `inputButtonTitle`: Input button label
|
|
410
|
+
- `inputPlaceholder`: Input placeholder text
|
|
411
|
+
|
|
412
|
+
### `pending()`
|
|
413
|
+
Retrieves the list of pending notifications.
|
|
414
|
+
|
|
415
|
+
**Returns:** `Promise<PendingNotification[]>`
|
|
416
|
+
|
|
417
|
+
### `cancel(notifications: number[])`
|
|
418
|
+
Cancels the pending notifications with the given list of identifiers.
|
|
419
|
+
|
|
420
|
+
### `cancelAll()`
|
|
421
|
+
Cancels all pending notifications.
|
|
422
|
+
|
|
423
|
+
### `active()`
|
|
424
|
+
Retrieves the list of active notifications.
|
|
425
|
+
|
|
426
|
+
**Returns:** `Promise<ActiveNotification[]>`
|
|
427
|
+
|
|
428
|
+
### `removeActive(notifications: Array<{ id: number; tag?: string }>)`
|
|
429
|
+
Removes the active notifications with the given list of identifiers.
|
|
430
|
+
|
|
431
|
+
### `removeAllActive()`
|
|
432
|
+
Removes all active notifications.
|
|
433
|
+
|
|
434
|
+
### `createChannel(channel: Channel)`
|
|
435
|
+
Creates a notification channel (Android).
|
|
436
|
+
|
|
437
|
+
**Parameters:**
|
|
438
|
+
- `channel`: Channel configuration
|
|
439
|
+
- `id`: Channel identifier
|
|
440
|
+
- `name`: Channel name
|
|
441
|
+
- `description`: Channel description
|
|
442
|
+
- `sound`: Sound resource name
|
|
443
|
+
- `lights`: Enable notification light
|
|
444
|
+
- `lightColor`: Light color
|
|
445
|
+
- `vibration`: Enable vibration
|
|
446
|
+
- `importance`: Importance level (None, Min, Low, Default, High)
|
|
447
|
+
- `visibility`: Visibility level (Secret, Private, Public)
|
|
448
|
+
|
|
449
|
+
### `removeChannel(id: string)`
|
|
450
|
+
Removes the channel with the given identifier.
|
|
451
|
+
|
|
452
|
+
### `channels()`
|
|
453
|
+
Retrieves the list of notification channels.
|
|
454
|
+
|
|
455
|
+
**Returns:** `Promise<Channel[]>`
|
|
456
|
+
|
|
457
|
+
### `onNotificationReceived(callback: (notification: Options) => void)`
|
|
458
|
+
Listens for notification received events.
|
|
459
|
+
|
|
460
|
+
**Returns:** `Promise<PluginListener>` with `unlisten()` method
|
|
461
|
+
|
|
462
|
+
### `onAction(callback: (notification: Options) => void)`
|
|
463
|
+
Listens for notification action performed events.
|
|
464
|
+
|
|
465
|
+
**Returns:** `Promise<PluginListener>` with `unlisten()` method
|
|
466
|
+
|
|
467
|
+
## Platform Differences
|
|
468
|
+
|
|
469
|
+
### Desktop (macOS, Windows, Linux)
|
|
470
|
+
- Uses native notification systems
|
|
471
|
+
- Actions support varies by platform
|
|
472
|
+
- Limited scheduling capabilities on some platforms
|
|
473
|
+
- Channels not applicable (Android-specific)
|
|
474
|
+
|
|
475
|
+
### iOS
|
|
476
|
+
- Requires permission request
|
|
477
|
+
- Rich notifications with attachments
|
|
478
|
+
- Action support with input options
|
|
479
|
+
- Silent notifications available
|
|
480
|
+
- Group notifications (thread identifiers)
|
|
481
|
+
|
|
482
|
+
### Android
|
|
483
|
+
- Notification channels required for Android 8.0+
|
|
484
|
+
- Full scheduling support
|
|
485
|
+
- Rich notification styles (inbox, large text)
|
|
486
|
+
- Ongoing notifications for background tasks
|
|
487
|
+
- Detailed importance and visibility controls
|
|
488
|
+
- Custom sounds, vibration, and lights
|
|
489
|
+
|
|
490
|
+
## Platform Setup
|
|
491
|
+
|
|
492
|
+
### iOS Setup
|
|
493
|
+
|
|
494
|
+
1. The plugin automatically configures notification capabilities
|
|
495
|
+
2. Add notification sounds to your Xcode project if needed:
|
|
496
|
+
- Add sound files to your iOS project
|
|
497
|
+
- Place in app bundle
|
|
498
|
+
- Reference by filename (without extension)
|
|
499
|
+
|
|
500
|
+
### Android Setup
|
|
501
|
+
|
|
502
|
+
1. The plugin automatically includes required permissions
|
|
503
|
+
2. For custom sounds:
|
|
504
|
+
- Place sound files in `res/raw/` folder
|
|
505
|
+
- Reference by filename (without extension)
|
|
506
|
+
3. For custom icons:
|
|
507
|
+
- Place icons in `res/drawable/` folder
|
|
508
|
+
- Reference by filename (without extension)
|
|
509
|
+
|
|
510
|
+
## Testing
|
|
511
|
+
|
|
512
|
+
### Desktop
|
|
513
|
+
- Notifications appear in the system notification center
|
|
514
|
+
- Test different notification types and interactions
|
|
515
|
+
- Verify notification persistence and dismissal
|
|
516
|
+
|
|
517
|
+
### iOS
|
|
518
|
+
- Test on physical devices (simulator support is limited)
|
|
519
|
+
- Request permissions before sending notifications
|
|
520
|
+
- Test scheduled notifications with different intervals
|
|
521
|
+
- Verify action handling and notification grouping
|
|
522
|
+
|
|
523
|
+
### Android
|
|
524
|
+
- Create and test notification channels
|
|
525
|
+
- Test different importance levels and visibility settings
|
|
526
|
+
- Verify scheduled notifications work with device sleep
|
|
527
|
+
- Test ongoing notifications for background tasks
|
|
528
|
+
- Verify notification styles (inbox, large text, etc.)
|
|
529
|
+
|
|
530
|
+
## Troubleshooting
|
|
531
|
+
|
|
532
|
+
### Notifications not appearing
|
|
533
|
+
- Verify permissions are granted
|
|
534
|
+
- On Android, ensure notification channel exists
|
|
535
|
+
- Check system notification settings
|
|
536
|
+
- Verify notification ID is unique
|
|
537
|
+
|
|
538
|
+
### Scheduled notifications not firing
|
|
539
|
+
- Check device power settings (battery optimization)
|
|
540
|
+
- On Android, use `allowWhileIdle` for critical notifications
|
|
541
|
+
- Verify schedule time is in the future
|
|
542
|
+
|
|
543
|
+
### Actions not working
|
|
544
|
+
- Ensure action types are registered before sending notification
|
|
545
|
+
- Verify action IDs match between registration and handling
|
|
546
|
+
- Check platform-specific action support
|
|
547
|
+
|
|
548
|
+
## License
|
|
549
|
+
|
|
550
|
+
[MIT](LICENSE)
|