Rework on Notification API + some sytem packages
All checks were successful
gitea-sync/antos/pipeline/head This commit looks good

- 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
parent f48cfdd95d
commit 11aed2642b
28 changed files with 917 additions and 171 deletions

View File

@ -43,7 +43,8 @@ tags = dist/core/tags/tag.js \
dist/core/tags/DesktopTag.js \
dist/core/tags/StackMenuTag.js \
dist/core/tags/StackPanelTag.js \
dist/core/tags/InputTag.js
dist/core/tags/InputTag.js \
dist/core/tags/NotificationTag.js
javascripts= dist/core/core.js \
dist/core/settings.js \
@ -63,7 +64,7 @@ javascripts= dist/core/core.js \
antfx = $(tags) \
dist/core/Announcerment.js
packages = Syslog Files MarketPlace Setting NotePad
packages = SystemServices SystemReport Files MarketPlace Setting NotePad
main: initd build_javascripts build_themes libs build_packages languages
- cp src/index.html $(BUILDDIR)/

225
d.ts/antos.d.ts vendored
View File

@ -953,6 +953,46 @@ declare namespace OS {
* - System dialogs definition
*/
namespace GUI {
/**
* Enum definition of different UI locattion
*
* @export
* @enum {string }
*/
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
*
@ -1084,6 +1124,46 @@ declare namespace OS {
* to each dialog definition for the format of the callback data
*/
function openDialog(d: string | BaseDialog, data: GenericObject<any>): Promise<any>;
/**
* Toast notification configuration options
*
*
* @export
* @interface ToastOptions
*/
interface ToastOptions {
/**
* Where the Toast is displayed?
*
* @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
*
* @export
* @param
* @returns
*/
function toast(data: any, opts?: ToastOptions, app?: application.BaseApplication): void;
/**
* Find a list of applications that support a specific mime
* type in the system packages meta-data
@ -2443,6 +2523,12 @@ declare namespace OS {
* @memberof BaseApplication
*/
title(): string | FormattedString;
/**
* Getter to access the application window instance
*
* @memberof BaseApplication
*/
get window(): GUI.tag.WindowTag;
/**
* Function called when the application exit.
* If the input exit event is prevented, the application
@ -2489,6 +2575,15 @@ declare namespace OS {
* @memberof BaseApplication
*/
protected menu(): GUI.BasicItemType[];
/**
* 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;
/**
* The cleanup function that is called by [[onexit]] function.
* Application need to override this function to perform some
@ -3926,6 +4021,12 @@ declare namespace OS {
* stored in the `customElements` registry of the browser
*/
namespace tag {
/**
* Alias to all classes that extends [[AFXTag]]
*/
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.
@ -7974,7 +8075,7 @@ declare namespace OS {
*/
reset(): void;
/**
* Mount the tab bar and bind some basic events
* Mount the menu and bind some basic events
*
* @protected
* @memberof StackMenuTag
@ -8059,7 +8160,7 @@ declare namespace OS {
*/
show(e?: JQuery.MouseEventBase): void;
/**
* TabBar layout definition
* Tag layout definition
*
* @protected
* @returns {TagLayoutType[]}
@ -8362,7 +8463,7 @@ declare namespace OS {
*/
navigateBack(): void;
/**
* Navigate to a custom tab
* Navigate to a custom panel
*
* @memberof StackPanelTag
*/
@ -8454,6 +8555,118 @@ declare namespace OS {
}
}
}
declare namespace OS {
namespace GUI {
namespace tag {
/**
* Toast notification tag
*
* @export
* @class ToastNotificationTag
* @extends {AFXTag}
*/
class ToastNotificationTag extends AFXTag {
/**
*Creates an instance of ToastNotificationTag.
* @memberof ToastNotificationTag
*/
constructor();
/**
* Mount the tag
*
* @protected
* @memberof ToastNotificationTag
*/
protected mount(): void;
/**
* 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[];
}
/**
* This tag manage all notification UI on the desktop
*
* @export
* @class NotificationTag
* @extends {AFXTag}
*/
class NotificationTag extends AFXTag {
/**
*Creates an instance of NotificationTag.
* @memberof NotificationTag
*/
constructor();
/**
* Mount the tag
*
* @protected
* @memberof NotificationTag
*/
protected mount(): void;
/**
* Init the tag before mounting
*
* @protected
* @memberof NotificationTag
*/
protected init(): void;
/**
* Push anotification to a specific location
*
* @memberof NotificationTag
*/
push(tag: AFXTag, loc?: ANCHOR): void;
/**
* 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[];
}
}
}
}
declare namespace OS {
namespace GUI {
namespace tag {
@ -9066,6 +9279,12 @@ declare namespace OS {
*/
set apptitle(v: string | FormattedString);
get apptitle(): string | FormattedString;
/**
* Get the notification tag
*
* @memberof WindowTag
*/
get notification(): NotificationTag;
/**
* Resize all the children of the window based on its width and height
*

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.

View File

@ -154,7 +154,7 @@ namespace OS {
}
const path = `${d.file.path}/${d.name}`;
await API.VFS.mkar(file.path, path);
this.notify(__("Archive file created: {0}",path ));
this.toast(__("Archive file created: {0}",path ));
} catch (error) {
this.error(__("Unable to compress file, folder"), error);
}
@ -638,7 +638,7 @@ namespace OS {
cut: true,
files: this.view.selectedFiles.map(x => x.path.asFileHandle()),
};
return this.notify(__("{0} files cut", this.clipboard.files.length));
return this.toast(__("{0} files cut", this.clipboard.files.length));
case `${this.name}-copy`:
if (!file) {
@ -648,7 +648,7 @@ namespace OS {
cut: false,
files: this.view.selectedFiles.map(x => x.path.asFileHandle()),
};
return this.notify(
return this.toast(
__("{0} files copied", this.clipboard.files.length)
);
@ -747,8 +747,7 @@ namespace OS {
.publish()
.then((r) => {
return this.notify(
__("Shared url: {0}", r.result)
);
__("Shared url: {0}", r.result));
})
.catch((e) => {
return this.error(

View File

@ -126,10 +126,10 @@ namespace OS {
try {
if (this.btinstall.data.dirty) {
await this.updatePackage();
return this.notify(__("Package updated"));
return this.toast(__("Package updated"));
}
const n = await this.remoteInstall();
return this.notify(__("Package installed: {0}", n));
return this.toast(__("Package installed: {0}", n));
} catch (error) {
return this.error(error.toString(), error);
}
@ -138,7 +138,7 @@ namespace OS {
this.btremove.onbtclick = async () => {
try {
await this.uninstall();
return this.notify(__("Packaged uninstalled"));
return this.toast(__("Packaged uninstalled"));
} catch (e) {
return this.error(e.toString(), e);
}
@ -401,8 +401,8 @@ namespace OS {
);
})
.catch((_e) => {
this.notify(
__("Unable to read package description")
this.error(
__("Unable to read package description"), _e
);
return $(this.appdesc).empty();
});
@ -487,7 +487,7 @@ namespace OS {
case "install":
this.localInstall()
.then((n) => {
return this.notify(
return this.toast(
__("Package installed: {0}", n)
);
})
@ -734,7 +734,7 @@ namespace OS {
if (r.error) {
throw __("Cannot uninstall package: {0}", r.error).__();
}
this.notify(__("Package uninstalled"));
this.toast(__("Package uninstalled"));
// stop all the services if any
if (app.services) {
for (let srv of Array.from(app.services)) {
@ -787,7 +787,7 @@ namespace OS {
}
this.bulkUninstall([...dep.uninstall])
.then((_b) => {
this.notify(__("Uninstall successfully"));
this.toast(__("Uninstall successfully"));
})
.catch((err) => {
this.error(__("Unable to uninstall package(s): {0}", err.toString()), err);

View File

@ -1,6 +0,0 @@
# Syslog: System notification management and service
Provide system wise notification service (Push Notification)
## Change logs
-v0.1.2-b: add README

View File

@ -1,20 +0,0 @@
{
"app": "Syslog",
"pkgname": "Syslog",
"services": [
"Calendar",
"PushNotification"
],
"name": "System log",
"description": "Core services and system log",
"info": {
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com",
"credit": "dedicated to some one here",
"licences": "GPLv3"
},
"version": "0.1.2-b",
"category": "System",
"iconclass": "fa fa-bug",
"mimes": []
}

View File

@ -1,4 +1,4 @@
module_files = Calendar.js PushNotification.js Syslog.js
module_files = SystemReport.js
libfiles =
@ -7,5 +7,5 @@ cssfiles = main.css
copyfiles = package.json scheme.html README.md
PKG_NAME=Syslog
PKG_NAME=SystemReport
include ../pkg.mk

View File

@ -0,0 +1,7 @@
# SystemReport: System notification management and service
Provide system wise notification service (Push Notification)
## Change logs
-v0.1.3-b: Rename from Syslog to SystemReport, move all services to SystemServices package
-v0.1.2-b: add README

View File

@ -110,33 +110,33 @@ detail:
*
*
* @export
* @class Syslog
* @class SystemReport
* @extends {BaseApplication}
*/
export class Syslog extends BaseApplication {
export class SystemReport extends BaseApplication {
private loglist: TAG.ListViewTag;
private logdetail: HTMLElement;
private srv: PushNotification;
constructor(args: AppArgumentsType[]) {
super("Syslog", args);
super("SystemReport", args);
}
/**
*
*
* @memberof Syslog
* @memberof SystemReport
*/
/**
*
*
* @memberof Syslog
* @memberof SystemReport
*/
main(): void {
this.loglist = this.find("loglist") as TAG.ListViewTag;
this.logdetail = this.find("logdetail");
this._gui
.pushService("Syslog/PushNotification")
.pushService("SystemServices/PushNotification")
.then((srv) => {
this.srv = srv as PushNotification;
@ -231,7 +231,7 @@ detail:
*
*
* @param {GenericObject<any>} log
* @memberof Syslog
* @memberof SystemReport
*/
addLog(log: GenericObject<any>): void {
this.loglist.push(log);
@ -241,7 +241,7 @@ detail:
*
*
* @returns {void}
* @memberof Syslog
* @memberof SystemReport
*/
cleanup(): void {
if (this.srv) {
@ -250,6 +250,6 @@ detail:
}
}
Syslog.singleton = true;
SystemReport.singleton = true;
}
}

View File

@ -0,0 +1,35 @@
afx-app-window[data-id ='Syslog'] div[data-id ='container']{
overflow: auto;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error {
display: block;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error i::before {
color: chocolate;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time{
display: block;
padding-left: 10px;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time i.label-text{
font-size: 10px;
font-style: italic;
}
afx-app-window[data-id ='Syslog'] afx-bug-list-item li.selected {
background-color: #116cd6;
color: white;
}
afx-app-window[data-id ='Syslog'] pre {
padding: 10px;
margin:0;
user-select: text;
cursor: text;
}
afx-app-window[data-id ='Syslog'] input{
height: 100%;
}

View File

@ -0,0 +1,15 @@
{
"app": "SystemReport",
"pkgname": "SystemReport",
"name": "System report",
"description": "System reports",
"info": {
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com",
"licences": "GPLv3"
},
"version": "0.1.3-b",
"category": "System",
"iconclass": "fa fa-bug",
"mimes": []
}

View File

@ -1,4 +1,4 @@
<afx-app-window data-id="Syslog" width='600' height='450' apptitle = "__(System error log)" >
<afx-app-window data-id="SystemReport" width='600' height='450' apptitle = "__(System error log)" >
<afx-hbox>
<afx-list-view data-id = "loglist" data-width="200"> </afx-list-view>
<afx-resizer data-width = "2" ></afx-resizer>

View File

@ -0,0 +1,11 @@
module_files = Calendar.js PushNotification.js
libfiles =
cssfiles = main.css
copyfiles = package.json README.md
PKG_NAME=SystemServices
include ../pkg.mk

View File

@ -31,12 +31,10 @@ namespace OS {
private cb: (e: JQuery.ClickEvent) => void;
private view: boolean;
private mlist: TAG.ListViewTag;
private mfeed: TAG.ListViewTag;
private nzone: TAG.OverlayTag;
private fzone: TAG.OverlayTag;
logs: GenericObject<any>[];
logmon: Syslog;
logmon: SystemReport;
/**
*Creates an instance of PushNotification.
@ -70,9 +68,7 @@ namespace OS {
*/
main(): void {
this.mlist = this.find("notifylist") as TAG.ListViewTag;
this.mfeed = this.find("notifeed") as TAG.ListViewTag;
this.nzone = this.find("notifyzone") as TAG.OverlayTag;
this.fzone = this.find("feedzone") as TAG.OverlayTag;
(this.find("btclear") as TAG.ButtonTag).onbtclick = (e) =>
(this.mlist.data = []);
(this.find("bterrlog") as TAG.ButtonTag).onbtclick = (e) =>
@ -83,18 +79,12 @@ namespace OS {
this.subscribe("info", (o) => this.pushout("INFO", o));
this.nzone.height = "100%";
this.fzone.height = "100%";
$(this.nzone)
.css("right", 0)
.css("top", "0")
.css("bottom", "0")
.hide();
$(this.fzone)
//.css("z-index", 99999)
.css("bottom", "0")
.css("bottom", "0")
.hide();
}
/**
@ -105,7 +95,7 @@ namespace OS {
* @memberof PushNotification
*/
private showLogReport(): void {
this._gui.launch("Syslog", []);
this._gui.launch("SystemReport", []);
}
/**
@ -167,16 +157,7 @@ namespace OS {
* @memberof PushNotification
*/
private notifeed(d: GenericObject<any>): void {
let timer: number;
this.mfeed.unshift(d);
$(this.fzone).show();
timer = window.setTimeout(() => {
this.mfeed.delete(d.domel);
if (this.mfeed.data.length === 0) {
$(this.fzone).hide();
}
return clearTimeout(timer);
}, 3000);
GUI.toast(d,{timeout: 3, location: GUI.ANCHOR.NORTH});
}
/**
@ -230,10 +211,6 @@ namespace OS {
</afx-hbox>
<afx-list-view data-id="notifylist"></afx-list-view>
</afx-overlay>
<afx-overlay data-id = "feedzone" width = "250">
<afx-list-view data-id = "notifeed">
</afx-list-view>
</afx-overlay>
</div>\
`;
}

View File

View File

@ -1,86 +1,50 @@
afx-overlay[data-id = "notifyzone"]{
/*opacity: 0.85;*/
overflow-y: auto;
overflow-x: hidden;
padding:3px;
margin: 0;
}
afx-overlay[data-id = "notifyzone"] afx-button button{
width: 100%;
border-radius: 0;
}
afx-list-view[data-id = "notifylist"]
{
padding:0;
}
afx-list-view[data-id = "notifylist"] > div.list-container > ul li{
border:1px solid #464646;
border-radius: 3px;
margin-bottom: 5px;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
padding-top: 5px;
padding-bottom: 5px;
}
afx-overlay[data-id = "feedzone"]{
overflow: hidden;
background-color:transparent;
right:5px;
margin: 0;
padding:0;
top:0;
}
afx-list-view[data-id = "notifeed"]
{
padding:0;
margin:0;
}
afx-list-view[data-id = "notifeed"] li{
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border:1px solid #262626;
border-radius: 6px;
margin-bottom: 2px;
z-index: 99999;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
}
afx-app-window[data-id ='Syslog'] div[data-id ='container']{
overflow: auto;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error {
display: block;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-error i::before {
color: chocolate;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time{
display: block;
padding-left: 10px;
}
afx-app-window[data-id ='Syslog'] .afx-bug-list-item-time i.label-text{
font-size: 10px;
font-style: italic;
}
afx-app-window[data-id ='Syslog'] afx-bug-list-item li.selected {
background-color: #116cd6;
color: white;
}
afx-app-window[data-id ='Syslog'] pre {
padding: 10px;
margin:0;
user-select: text;
cursor: text;
}
afx-app-window[data-id ='Syslog'] input{
height: 100%;
afx-overlay[data-id = "notifyzone"]{
/*opacity: 0.85;*/
overflow-y: auto;
overflow-x: hidden;
padding:3px;
margin: 0;
}
afx-overlay[data-id = "notifyzone"] afx-button button{
width: 100%;
border-radius: 0;
}
afx-list-view[data-id = "notifylist"]
{
padding:0;
}
afx-list-view[data-id = "notifylist"] > div.list-container > ul li{
border:1px solid #464646;
border-radius: 3px;
margin-bottom: 5px;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
padding-top: 5px;
padding-bottom: 5px;
}
afx-overlay[data-id = "feedzone"]{
overflow: hidden;
background-color:transparent;
right:5px;
margin: 0;
padding:0;
top:0;
}
afx-list-view[data-id = "notifeed"]
{
padding:0;
margin:0;
}
afx-list-view[data-id = "notifeed"] li{
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border:1px solid #262626;
border-radius: 6px;
margin-bottom: 2px;
z-index: 99999;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
}

View File

@ -0,0 +1,15 @@
{
"pkgname": "SystemServices",
"services": ["PushNotification", "Calendar"],
"name": "System services",
"description": "System services",
"info": {
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com",
"licences": "GPLv3"
},
"version": "0.1.0-a",
"category": "System",
"iconclass": "fa fa-cog",
"mimes": []
}

View File

@ -0,0 +1,19 @@
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]::before
{
font-family: "bootstrap-icons";
content: "\F62A";
font-size: 20px;
}
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]:hover
{
color: orangered;
}
afx-toast-notification div[data-id="toast_container"]
{
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border:1px solid #262626;
background-color:#3b3b3b;
border-radius: 6px;
}

View File

@ -0,0 +1,19 @@
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]::before
{
font-family: "bootstrap-icons";
content: "\F62A";
font-size: 20px;
}
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]:hover
{
color: orangered;
}
afx-toast-notification div[data-id="toast_container"]
{
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border: 1px solid #a6a6a6;
background-color: #f6F6F6;
border-radius: 6px;
}

View File

@ -0,0 +1,117 @@
afx-notification {
display: contents;
}
afx-notification div[data-id="north"] {
position: absolute;
top: 5px;
left: 50%;
transform: translate(-50%, 0);
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: center;
}
afx-notification div[data-id="south"] {
position: absolute;
bottom: 5px;
left: 50%;
transform: translate(-50%, 0);
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: center;
}
afx-notification div[data-id="north_west"] {
position: absolute;
left: 5px;
top: 5px;
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: flex-start;
}
afx-notification div[data-id="south_west"] {
position: absolute;
left: 5px;
bottom: 5px;
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: flex-start;
}
afx-notification div[data-id="north_est"] {
position: absolute;
right: 5px;
top: 5px;
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: flex-end;
}
afx-notification div[data-id="south_est"] {
position: absolute;
right: 5px;
bottom: 5px;
/*max-width: 30%;*/
max-height: 100%;
width: fit-content;
height: fit-content;
z-index: 1000000;
display: flex;
flex-direction: column;
align-items: flex-end;
}
afx-toast-notification {
display: contents;
}
afx-toast-notification div[data-id="toast_container"]
{
display: block;
width: fit-content;
height: fit-content;
position: relative;
max-width: 300px;
}
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_header"]
{
position: absolute;
width: 20px;
height: 20px;
right: 5px;
}
afx-toast-notification div[data-id="toast_container"] div[data-id="toast_content"]
{
padding: 20px 15px;
}