Rework on Notification API + some sytem packages

- Rename Syslog to SystemReport
- All services previously on SystemReport now moved to the dedicated SystemServices Packages
- Rework on a more versatile notification GUI and API
- Applications now can display a local toast message instead of pushing a global notification message
This commit is contained in:
DanyLE
2023-01-06 18:44:11 +01:00
committed by Dany LE
parent c52e4b649e
commit 242df06a28
28 changed files with 917 additions and 171 deletions

View File

@ -380,7 +380,17 @@ namespace OS {
title(): string | FormattedString {
return (this.scheme as GUI.tag.WindowTag).apptitle;
}
/**
* Getter to access the application window instance
*
* @memberof BaseApplication
*/
get window(): GUI.tag.WindowTag
{
return this.scheme as GUI.tag.WindowTag;
}
/**
* Function called when the application exit.
* If the input exit event is prevented, the application
@ -455,6 +465,35 @@ namespace OS {
return [];
}
/**
* Show local toast notification
*
* @param {any} data to send
* @param {GUI.ToastOptions} notification options see [[GUI.ToastOptions]]
* @returns {void}
* @memberof BaseApplication
*/
toast(data: any, opts?: GUI.ToastOptions): void {
let options: GUI.ToastOptions = {
location: GUI.ANCHOR.SOUTH_EST,
timeout: 3,
tag: "afx-label"
};
if(opts)
{
for(const k in opts)
{
options[k] = opts[k];
}
}
let d = data;
if(typeof data == "string" || data instanceof FormattedString)
{
d = {text: data};
}
this._gui.toast(d,options, this);
}
/**
* The cleanup function that is called by [[onexit]] function.
* Application need to override this function to perform some

View File

@ -26,6 +26,48 @@ namespace OS {
* - System dialogs definition
*/
export namespace GUI {
/**
* Enum definition of different UI locattion
*
* @export
* @enum {string }
*/
export enum ANCHOR {
/**
* Center top
*/
NORTH = "NORTH",
/**
* Center bottom
*/
SOUTH = "SOUTH",
/**
* Center left
*/
WEST = "WEST",
/**
* Center right
*/
EST = "EST",
/**
* Top left
*/
NORTH_WEST = "NORTH_WEST",
/**
* Bottom left
*/
SOUTH_WEST = "SOUTH_WEST",
/**
* Top right
*/
NORTH_EST = "NORTH_EST",
/**
* Bottom right
*/
SOUTH_EST = "SOUTH_EST",
}
/**
* AntOS keyboard shortcut type definition
*
@ -242,6 +284,87 @@ namespace OS {
return dialog.init();
});
}
/**
* Toast notification configuration options
*
*
* @export
* @interface ToastOptions
*/
export interface ToastOptions {
/**
* Where the Toast is displayed? see [[ANCHOR]]
*
* @type {ANCHOR}
* @memberof ToastOptions
*/
location?: ANCHOR;
/**
* Timeout (in seconds) before the Toast disappear
* Set this value to 0 to prevent the Toast to disappear,
* in this case, use need to explicitly close the notification
*
* @type {number}
* @memberof ToastOptions
*/
timeout?: number;
/**
* AFXTag that is used to render the data
*
* @type {number}
* @memberof ToastOptions
*/
tag?: string;
}
/**
* Toast notification API
* Show a toad message on different posisition on screen, see [[ToastOptions]]
*
* @export
* @param
* @returns
*/
export function toast(data: any, opts?: ToastOptions, app: application.BaseApplication = undefined): void
{
let notification_el = undefined;
if(app)
{
notification_el = app.window.notification;
}
else
{
notification_el = $("#sys_notification")[0] as tag.NotificationTag;
}
let options: ToastOptions = {
location: ANCHOR.NORTH,
timeout: 3,
tag: "afx-label"
};
if(opts)
{
for(const k in opts)
{
options[k] = opts[k];
}
}
const toast_el = $(`<afx-toast-notification>`)[0] as tag.ToastNotificationTag;
const content_el = $(`<${options.tag}>`)[0] as AFXTag;
$(toast_el).append(content_el);
toast_el.uify(undefined);
notification_el.push(toast_el, options.location);
content_el.set(data);
if(options.timeout && options.timeout != 0)
{
setTimeout(function(){
$(toast_el).remove();
clearTimeout(this);
}, options.timeout*1000);
}
}
/**
* Find a list of applications that support a specific mime
@ -951,6 +1074,8 @@ namespace OS {
);
});
// mount it
const nottification = $("#sys_notification")[0] as tag.NotificationTag;
nottification.uify(undefined);
desktop().uify(undefined);
}
@ -1104,6 +1229,7 @@ namespace OS {
<afx-sys-panel id = "syspanel"></afx-sys-panel>
<div id = "workspace">
<afx-desktop id = "desktop" dir="vertical" ></afx-desktop>
<afx-notification id="sys_notification" ></afx-notification>
</div>
<afx-stack-menu id="contextmenu" data-id="contextmenu" context="true" style="display:none;"></afx-stack-menu>
<afx-label id="systooltip" data-id="systooltip" style="display:none;position:absolute;"></afx-label>

View File

@ -0,0 +1,189 @@
namespace OS {
export namespace GUI {
export namespace tag {
/**
* Toast notification tag
*
* @export
* @class ToastNotificationTag
* @extends {AFXTag}
*/
export class ToastNotificationTag extends AFXTag {
/**
*Creates an instance of ToastNotificationTag.
* @memberof ToastNotificationTag
*/
constructor() {
super();
}
/**
* Mount the tag
*
* @protected
* @memberof ToastNotificationTag
*/
protected mount() {
$(this.refs.header).on('click',(e) => {
$(this).remove();
})
}
/**
* Init the tag before mounting
*
* @protected
* @memberof ToastNotificationTag
*/
protected init(): void {
};
/**
* Re-calibrate tag
*
* @protected
* @memberof ToastNotificationTag
*/
protected calibrate(): void {}
/**
* Update the current tag, do nothing in this tag
*
* @param {*} [d]
* @memberof ToastNotificationTag
*/
reload(d?: any): void {}
/**
* Tag layout definition
*
* @protected
* @returns {TagLayoutType[]}
* @memberof ToastNotificationTag
*/
protected layout(): TagLayoutType[] {
return [
{
el: "div", id: "toast_container", ref: "container",
children:[
{
el: "div",
ref: "header",
id: "toast_header",
},
{
el: "div",
ref: "yield",
id:"toast_content",
}
]
}
];
}
}
/**
* This tag manage all notification UI on the desktop
*
* @export
* @class NotificationTag
* @extends {AFXTag}
*/
export class NotificationTag extends AFXTag {
/**
*Creates an instance of NotificationTag.
* @memberof NotificationTag
*/
constructor() {
super();
}
/**
* Mount the tag
*
* @protected
* @memberof NotificationTag
*/
protected mount() {
}
/**
* Init the tag before mounting
*
* @protected
* @memberof NotificationTag
*/
protected init(): void {
};
/**
* Push anotification to a specific location
*
* @memberof NotificationTag
*/
push(tag: AFXTag, loc: ANCHOR = ANCHOR.NORTH): void
{
if(!this.refs[loc])
{
return;
}
switch(loc)
{
case ANCHOR.NORTH:
case ANCHOR.NORTH_EST:
case ANCHOR.NORTH_WEST:
$(this.refs[loc]).prepend(tag);
break;
case ANCHOR.SOUTH:
case ANCHOR.SOUTH_EST:
case ANCHOR.SOUTH_WEST:
$(this.refs[loc]).append(tag);
break;
default: break;
}
this.calibrate();
}
/**
* Re-calibrate tag
*
* @protected
* @memberof NotificationTag
*/
protected calibrate(): void {}
/**
* Update the current tag, do nothing in this tag
*
* @param {*} [d]
* @memberof NotificationTag
*/
reload(d?: any): void {}
/**
* Tag layout definition
*
* @protected
* @returns {TagLayoutType[]}
* @memberof NotificationTag
*/
protected layout(): TagLayoutType[] {
return [
{ el: "div", id: "north", ref: "NORTH" },
{ el: "div", id: "south", ref: "SOUTH" },
{ el: "div", id: "north_west", ref: "NORTH_WEST" },
{ el: "div", id: "south_west", ref: "SOUTH_WEST" },
{ el: "div", id: "north_est", ref: "NORTH_EST" },
{ el: "div", id: "south_est", ref: "SOUTH_EST" }
];
}
}
define("afx-notification", NotificationTag);
define("afx-toast-notification", ToastNotificationTag);
}
}
}

View File

@ -325,7 +325,7 @@ namespace OS {
}
/**
* Mount the tab bar and bind some basic events
* Mount the menu and bind some basic events
*
* @protected
* @memberof StackMenuTag
@ -546,7 +546,7 @@ namespace OS {
}
/**
* TabBar layout definition
* Tag layout definition
*
* @protected
* @returns {TagLayoutType[]}

View File

@ -61,7 +61,7 @@ namespace OS {
this.navigate()
}
/**
* Navigate to a custom tab
* Navigate to a custom panel
*
* @memberof StackPanelTag
*/

View File

@ -272,6 +272,15 @@ namespace OS {
return $(this).attr("apptitle");
}
/**
* Get the notification tag
*
* @memberof WindowTag
*/
get notification(): NotificationTag
{
return this.refs.notification as NotificationTag;
}
/**
* Resize all the children of the window based on its width and height
*
@ -703,6 +712,10 @@ namespace OS {
{
el: "afx-stack-menu",
ref: "stackmenu"
},
{
el: "afx-notification",
ref: "notification"
}
],
},

View File

@ -595,6 +595,7 @@ namespace OS {
return element.hasAttribute(v);
}
}
HTMLElement.prototype.update = function (d): void {
$(this)
@ -632,6 +633,12 @@ namespace OS {
* stored in the `customElements` registry of the browser
*/
export namespace tag {
/**
* Alias to all classes that extends [[AFXTag]]
*/
export type AFXTagTypeClass = {
new <T extends AFXTag>(): T;
};
/**
* Define an AFX tag as a custom element and add it to the
* global `customElements` registry. If the tag is redefined, i.e.