1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-18 09:12:55 +00:00
seahub/frontend/src/components/toast/toastManager.js

136 lines
3.2 KiB
JavaScript
Raw Normal View History

2018-12-07 04:59:25 +00:00
import React from 'react';
import PropTypes from 'prop-types';
import Toast from './toast';
const hasCustomId = settings => Object.hasOwnProperty.call(settings, 'id');
export default class ToastManager extends React.PureComponent {
static propTypes = {
/**
* Function called with the `this.notify` function.
*/
2018-12-07 04:59:25 +00:00
bindNotify: PropTypes.func.isRequired,
/**
* Function called with the `this.getToasts` function.
*/
2018-12-07 04:59:25 +00:00
bindGetToasts: PropTypes.func.isRequired,
/**
* Function called with the `this.closeAll` function.
*/
2018-12-07 04:59:25 +00:00
bindCloseAll: PropTypes.func.isRequired
};
2018-12-07 04:59:25 +00:00
static idCounter = 0;
constructor(props, context) {
super(props, context);
props.bindNotify(this.notify);
props.bindGetToasts(this.getToasts);
props.bindCloseAll(this.closeAll);
this.state = {
toasts: []
};
}
getToasts = () => {
return this.state.toasts;
};
2018-12-07 04:59:25 +00:00
closeAll = () => {
this.getToasts().forEach(toast => toast.close());
};
2018-12-07 04:59:25 +00:00
notify = (title, settings) => {
// If there's a custom toast ID passed, close existing toasts with the same custom ID
2018-12-07 04:59:25 +00:00
if (hasCustomId(settings)) {
for (const toast of this.state.toasts) {
// Since unique ID is still appended to a custom ID, skip the unique ID and check only prefix
2018-12-07 04:59:25 +00:00
if (String(toast.id).startsWith(settings.id)) {
this.closeToast(toast.id);
}
}
}
const instance = this.createToastInstance(title, settings);
this.setState(previousState => {
return {
toasts: [instance, ...previousState.toasts]
};
});
return instance;
};
2018-12-07 04:59:25 +00:00
createToastInstance = (title, settings) => {
const uniqueId = ++ToastManager.idCounter;
const id = hasCustomId(settings) ? `${settings.id}-${uniqueId}` : uniqueId;
let hasCloseButton = settings.hasCloseButton || true;
let duration = settings.duration || 2;
if (settings.hasCloseButton !== undefined) {
hasCloseButton = settings.hasCloseButton;
}
if (settings.duration !== undefined) {
duration = settings.duration;
}
2018-12-07 04:59:25 +00:00
return {
id,
title,
description: settings.description,
hasCloseButton: hasCloseButton,
duration: duration,
2018-12-07 04:59:25 +00:00
close: () => this.closeToast(id),
intent: settings.intent
};
};
2018-12-07 04:59:25 +00:00
/**
* This will set isShown on the Toast which will close the toast.
* It won't remove the toast until onExited triggers onRemove.
*/
2018-12-07 04:59:25 +00:00
closeToast = id => {
this.setState(previousState => {
return {
toasts: previousState.toasts.map(toast => {
if (toast.id === id) {
return {
...toast,
isShown: false
};
}
return toast;
})
};
});
};
2018-12-07 04:59:25 +00:00
removeToast = id => {
this.setState(previousState => {
return {
toasts: previousState.toasts.filter(toast => toast.id !== id)
};
});
};
2018-12-07 04:59:25 +00:00
render() {
return (
<div className="seahub-toast-manager">
2018-12-07 04:59:25 +00:00
{this.state.toasts.map(({ id, description, ...props }) => {
return (
<Toast key={id} onRemove={() => this.removeToast(id)} {...props}>
{description}
</Toast>
);
})}
</div>
2018-12-07 04:59:25 +00:00
);
}
}