mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-29 12:50:59 +00:00
Add UI notify API and notification handling
This commit is contained in:
+2
-1
@@ -12,6 +12,7 @@ The UI API provides a comprehensive set of tools for creating rich user interfac
|
||||
|
||||
### Dialogs and Alerts
|
||||
- **[`puter.ui.alert()`](/UI/alert/)** - Show alert dialogs
|
||||
- **[`puter.ui.notify()`](/UI/notify/)** - Show desktop notifications
|
||||
- **[`puter.ui.prompt()`](/UI/prompt/)** - Show input prompts
|
||||
|
||||
### Window Management
|
||||
@@ -47,4 +48,4 @@ The UI API provides a comprehensive set of tools for creating rich user interfac
|
||||
- **[`puter.ui.showColorPicker()`](/UI/showColorPicker/)** - Show color picker
|
||||
- **[`puter.ui.showFontPicker()`](/UI/showFontPicker/)** - Show font picker
|
||||
- **[`puter.ui.showSpinner()`](/UI/showSpinner/)** - Show spinner
|
||||
- **[`puter.ui.socialShare()`](/UI/socialShare/)** - Share content socially
|
||||
- **[`puter.ui.socialShare()`](/UI/socialShare/)** - Share content socially
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: puter.ui.notify()
|
||||
description: Displays a desktop notification in Puter.
|
||||
platforms: [apps]
|
||||
---
|
||||
|
||||
Displays a desktop notification in Puter. Use this to surface app events without interrupting the user.
|
||||
|
||||
## Syntax
|
||||
```js
|
||||
puter.ui.notify(options)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
#### `options` (optional)
|
||||
An object that configures the notification.
|
||||
|
||||
- `title` (string): Title shown in the notification.
|
||||
- `text` (string): Body text shown under the title.
|
||||
- `icon` (string): Icon URL or Puter icon name (for example `bell.svg`).
|
||||
- `round_icon` (boolean): If `true`, renders the icon as a circle. `roundIcon` is accepted as an alias.
|
||||
- `uid` (string): Optional ID to associate with the notification.
|
||||
- `value` (any): Optional value stored on the notification element.
|
||||
|
||||
## Return value
|
||||
A `Promise` that resolves to the notification UID.
|
||||
|
||||
## Examples
|
||||
```html
|
||||
<script src="https://js.puter.com/v2/"></script>
|
||||
<script>
|
||||
puter.ui.notify({
|
||||
title: 'Build finished',
|
||||
text: 'Your export is ready.',
|
||||
icon: 'bell.svg',
|
||||
}).then((uid) => {
|
||||
console.log('Notification UID:', uid);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@@ -678,6 +678,14 @@ let sidebar = [
|
||||
source: '/UI/alert.md',
|
||||
path: '/UI/alert',
|
||||
},
|
||||
{
|
||||
title: '<code>notify()</code>',
|
||||
page_title: '<code>puter.ui.notify()</code>',
|
||||
title_tag: 'puter.ui.notify()',
|
||||
icon: '/assets/img/function.svg',
|
||||
source: '/UI/notify.md',
|
||||
path: '/UI/notify',
|
||||
},
|
||||
{
|
||||
title: '<code>contextMenu()</code>',
|
||||
page_title: '<code>puter.ui.contextMenu()</code>',
|
||||
|
||||
+41
-6
@@ -34,6 +34,7 @@ import UIWindowFontPicker from './UI/UIWindowFontPicker.js';
|
||||
import UIWindowRequestPermission from './UI/UIWindowRequestPermission.js';
|
||||
import UIWindowSaveAccount from './UI/UIWindowSaveAccount.js';
|
||||
import UIWindowSignup from './UI/UIWindowSignup.js';
|
||||
import UINotification from './UI/UINotification.js';
|
||||
|
||||
import { PROCESS_IPC_ATTACHED } from './definitions.js';
|
||||
import TeePromise from './util/TeePromise.js';
|
||||
@@ -253,6 +254,38 @@ const ipc_listener = async (event, handled) => {
|
||||
}, '*');
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// showNotification
|
||||
//--------------------------------------------------------
|
||||
else if ( event.data.msg === 'showNotification' ) {
|
||||
const options = event.data.options ?? {};
|
||||
const notification_uid = options.uid ?? `app-${app_uuid}-${msg_id}`;
|
||||
let icon = window.icons['bell.svg'];
|
||||
let round_icon = false;
|
||||
|
||||
if ( typeof options.icon === 'string' && options.icon.length > 0 ) {
|
||||
icon = window.icons[options.icon] ?? options.icon;
|
||||
}
|
||||
|
||||
if ( options.round_icon ) {
|
||||
round_icon = true;
|
||||
}
|
||||
|
||||
UINotification({
|
||||
title: options.title ?? app_name ?? 'Notification',
|
||||
text: options.text ?? '',
|
||||
icon,
|
||||
round_icon,
|
||||
uid: notification_uid,
|
||||
value: options.value,
|
||||
});
|
||||
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
msg: 'notificationShown',
|
||||
uid: notification_uid,
|
||||
}, '*');
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// getLanguage
|
||||
//--------------------------------------------------------
|
||||
else if ( event.data.msg === 'getLanguage' ) {
|
||||
@@ -1488,12 +1521,14 @@ const ipc_listener = async (event, handled) => {
|
||||
target_path, el_filedialog_window,
|
||||
file_to_upload, overwrite,
|
||||
}) => {
|
||||
const res = await puter.fs.write(target_path,
|
||||
file_to_upload,
|
||||
{
|
||||
dedupeName: false,
|
||||
overwrite: overwrite,
|
||||
});
|
||||
const res = await puter.fs.write(
|
||||
target_path,
|
||||
file_to_upload,
|
||||
{
|
||||
dedupeName: false,
|
||||
overwrite: overwrite,
|
||||
},
|
||||
);
|
||||
|
||||
await tell_caller_and_update_views({ res, el_filedialog_window, target_path });
|
||||
};
|
||||
|
||||
@@ -499,6 +499,9 @@ class UI extends EventListener {
|
||||
// execute callback
|
||||
this.#callbackFunctions[e.data.original_msg_id](e.data.response);
|
||||
}
|
||||
else if ( e.data.msg === 'notificationShown' ) {
|
||||
this.#callbackFunctions[e.data.original_msg_id](e.data.uid);
|
||||
}
|
||||
else if ( e.data.msg === 'languageReceived' ) {
|
||||
// execute callback
|
||||
this.#callbackFunctions[e.data.original_msg_id](e.data.language);
|
||||
@@ -722,6 +725,16 @@ class UI extends EventListener {
|
||||
});
|
||||
};
|
||||
|
||||
notify (options) {
|
||||
return new Promise((resolve) => {
|
||||
const normalized = { ...(options ?? {}) };
|
||||
if ( normalized.roundIcon !== undefined && normalized.round_icon === undefined ) {
|
||||
normalized.round_icon = normalized.roundIcon;
|
||||
}
|
||||
this.#postMessageWithCallback('showNotification', resolve, { options: normalized });
|
||||
});
|
||||
};
|
||||
|
||||
showDirectoryPicker (options, callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if ( ! globalThis.open ) {
|
||||
|
||||
Vendored
+11
@@ -74,6 +74,16 @@ export interface DirectoryPickerOptions {
|
||||
multiple?: boolean;
|
||||
}
|
||||
|
||||
export interface NotificationOptions {
|
||||
title?: string;
|
||||
text?: string;
|
||||
icon?: string;
|
||||
round_icon?: boolean;
|
||||
roundIcon?: boolean;
|
||||
uid?: string;
|
||||
value?: unknown;
|
||||
}
|
||||
|
||||
export interface AppConnectionCloseEvent {
|
||||
appInstanceID: string;
|
||||
statusCode?: number;
|
||||
@@ -113,6 +123,7 @@ export class AppConnection {
|
||||
export class UI {
|
||||
alert (message?: string, buttons?: AlertButton[]): Promise<string>;
|
||||
prompt (message?: string, placeholder?: string): Promise<string | null>;
|
||||
notify (options?: NotificationOptions): Promise<string>;
|
||||
authenticateWithPuter (): Promise<void>;
|
||||
contextMenu (options: ContextMenuOptions): void;
|
||||
createWindow (options?: WindowOptions): void;
|
||||
|
||||
Reference in New Issue
Block a user