-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(notification): add simple Notification module
support the basic notification display panel, add, and remove methods re #18
- Loading branch information
Showing
15 changed files
with
384 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import * as React from 'react'; | ||
import * as ReactDOM from 'react-dom'; | ||
import { connect, IStatusBarItem } from 'mo'; | ||
import { Controller } from 'mo/react/controller'; | ||
import { notificationService, statusBarService } from 'mo/services'; | ||
import { singleton } from 'tsyringe'; | ||
import { Notification } from 'mo/workbench/statusBar/notification'; | ||
import { NotificationPanel } from 'mo/workbench/statusBar/notification/notificationPanel'; | ||
|
||
import { IActionBarItem } from 'mo/components/actionBar'; | ||
import { | ||
INotificationItem, | ||
NOTIFICATION_CLEAR_ALL, | ||
NOTIFICATION_HIDE, | ||
} from 'mo/model/notification'; | ||
import { select } from 'mo/common/dom'; | ||
import { ID_APP } from 'mo/common/id'; | ||
|
||
export interface INotificationController { | ||
onCloseNotification(item: INotificationItem): void; | ||
onClick?: (e: React.MouseEvent, item: IStatusBarItem) => void; | ||
onActionBarClick?( | ||
event: React.MouseEvent<Element, MouseEvent>, | ||
item: IActionBarItem<any> | ||
): void; | ||
} | ||
|
||
@singleton() | ||
export class NotificationController | ||
extends Controller | ||
implements INotificationController { | ||
constructor() { | ||
super(); | ||
this.init(); | ||
} | ||
|
||
public onCloseNotification(item: INotificationItem<any>): void { | ||
if (typeof item.id === 'number') { | ||
notificationService.removeNotification(item.id); | ||
} | ||
} | ||
|
||
private _notificationPanel: HTMLDivElement | undefined = undefined; | ||
|
||
private showHideNotifications() { | ||
if (!this._notificationPanel) { | ||
this.renderNotificationPanel(); | ||
} | ||
notificationService.showHideNotifications(); | ||
} | ||
|
||
public onClick = (e: React.MouseEvent, item: IStatusBarItem) => { | ||
this.showHideNotifications(); | ||
}; | ||
|
||
public onActionBarClick = ( | ||
event: React.MouseEvent<Element, MouseEvent>, | ||
item: IActionBarItem<any> | ||
) => { | ||
const action = item.id; | ||
if (action === NOTIFICATION_CLEAR_ALL.id) { | ||
notificationService.showHideNotifications(); | ||
} else if (action === NOTIFICATION_HIDE.id) { | ||
this.showHideNotifications(); | ||
} | ||
}; | ||
|
||
private init() { | ||
const notificationItem = notificationService.getState(); | ||
const NotificationView = connect(notificationService, Notification); | ||
notificationService.setState({ | ||
...notificationItem, | ||
render: () => <NotificationView onClick={this.onClick} />, | ||
}); | ||
statusBarService.appendRightItem(notificationItem); | ||
} | ||
|
||
public renderNotificationPanel() { | ||
const NotificationPanelView = connect( | ||
notificationService, | ||
NotificationPanel | ||
); | ||
const root = select('#' + ID_APP); | ||
const container = document.createElement('div'); | ||
root?.appendChild(container); | ||
ReactDOM.render( | ||
<NotificationPanelView | ||
onActionBarClick={this.onActionBarClick} | ||
onCloseNotification={this.onCloseNotification} | ||
/>, | ||
container | ||
); | ||
this._notificationPanel = container; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,69 @@ | ||
import { IActionBarItem } from 'mo/components/actionBar'; | ||
import { Icon } from 'mo/components/icon'; | ||
import * as React from 'react'; | ||
import { injectable } from 'tsyringe'; | ||
import { IStatusBarItem } from './workbench/statusBar'; | ||
|
||
export type NotificationStatusType = 'message' | 'normal'; | ||
export enum NotificationStatus { | ||
Read = 1, | ||
WaitRead = 2, | ||
} | ||
|
||
export interface INotificationItem<T = any> { | ||
id?: number; | ||
value: T; | ||
status?: NotificationStatus; | ||
} | ||
|
||
export interface INotification<T = any> extends IStatusBarItem { | ||
data: T[]; | ||
status: NotificationStatusType; | ||
data?: INotificationItem<T>[]; | ||
showNotifications?: boolean; | ||
actionBar?: IActionBarItem[]; | ||
} | ||
|
||
export const NOTIFICATION_CLEAR_ALL: IActionBarItem = { | ||
id: 'ClearAll', | ||
title: 'Clear All Notifications', | ||
iconName: 'codicon-clear-all', | ||
}; | ||
|
||
export const NOTIFICATION_HIDE: IActionBarItem = { | ||
id: 'HideNotifications', | ||
title: 'Hide Notifications', | ||
iconName: 'codicon-chevron-down', | ||
}; | ||
|
||
@injectable() | ||
export class NotificationModel<T> implements INotification<T> { | ||
|
||
static readonly ID = 'MO_NOTIFICATION'; | ||
static readonly NAME = 'Notification'; | ||
|
||
public id: string; | ||
public name: string; | ||
public data: T[]; | ||
public data: INotificationItem<T>[]; | ||
public sortIndex: number; | ||
public render: () => ReactNode; | ||
public status: NotificationStatusType; | ||
public showNotifications: boolean; | ||
public actionBar: IActionBarItem[]; | ||
|
||
constructor( | ||
id: string = NotificationModel.ID, | ||
name: string = NotificationModel.NAME, | ||
data: T[] = [], | ||
data: INotificationItem<T>[] = [], | ||
sortIndex: number = 1, | ||
render: () => ReactNode = () => <Icon type="bell" />, | ||
status: NotificationStatusType = 'normal' | ||
showNotifications: boolean = false, | ||
actionBar: IActionBarItem[] = [ | ||
NOTIFICATION_CLEAR_ALL, | ||
NOTIFICATION_HIDE, | ||
], | ||
render: () => ReactNode = () => <Icon type="bell" /> | ||
) { | ||
this.id = id; | ||
this.name = name; | ||
this.sortIndex = sortIndex; | ||
this.render = render; | ||
this.status = status; | ||
this.showNotifications = showNotifications; | ||
this.data = data; | ||
this.actionBar = actionBar; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,87 @@ | ||
// TODO notificationService | ||
import { | ||
INotification, | ||
INotificationItem, | ||
NotificationModel, | ||
NotificationStatus, | ||
} from 'mo/model/notification'; | ||
import { Component } from 'mo/react'; | ||
import { singleton, container } from 'tsyringe'; | ||
import { searchById } from './helper'; | ||
|
||
export interface INotificationService extends Component<INotification> { | ||
addNotification<T>(item: INotificationItem<T>): null | INotificationItem<T>; | ||
removeNotification(id: number): void; | ||
updateNotification<T>( | ||
item: INotificationItem<T> | ||
): null | INotificationItem<T>; | ||
showHideNotifications(): void; | ||
} | ||
|
||
@singleton() | ||
export class NotificationService | ||
extends Component<INotification> | ||
implements INotificationService { | ||
protected state: INotification; | ||
|
||
constructor() { | ||
super(); | ||
this.state = container.resolve(NotificationModel); | ||
} | ||
|
||
public showHideNotifications(): void { | ||
this.setState({ | ||
...this.state, | ||
showNotifications: !this.state.showNotifications, | ||
}); | ||
} | ||
|
||
public updateNotification<T>( | ||
item: INotificationItem<T> | ||
): INotificationItem<T> | null { | ||
const { data = [] } = this.state; | ||
if (data.length > -1) { | ||
const index = data.findIndex(searchById(item.id)); | ||
if (index > -1) { | ||
const original = data[index]; | ||
data[index] = Object.assign(original, item); | ||
this.setState({ | ||
...this.state, | ||
data: [...data], | ||
}); | ||
return data[index]; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public removeNotification(id: number): void { | ||
const { data = [] } = this.state; | ||
if (data.length > -1) { | ||
const index = data.findIndex(searchById(id)); | ||
if (index > -1) { | ||
data.splice(index, 1); | ||
this.setState({ | ||
...this.state, | ||
data: [...data], | ||
}); | ||
} | ||
} | ||
} | ||
|
||
public addNotification<T>( | ||
item: INotificationItem<T> | ||
): null | INotificationItem<T> { | ||
const { data = [] } = this.state; | ||
if (item) { | ||
if (item.id === undefined) item.id = data.length; | ||
item.status = NotificationStatus.WaitRead; | ||
const arr = [...data, item]; | ||
this.setState({ | ||
...this.state, | ||
data: arr, | ||
}); | ||
return item; | ||
} | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.