Add a notification module
This commit is contained in:
parent
a53deebbcf
commit
481715d8a2
9
frontend/js/actions/notifications.js
Normal file
9
frontend/js/actions/notifications.js
Normal file
@ -0,0 +1,9 @@
|
||||
export const sendNotification = (data) => ({
|
||||
type: "ADD_NOTIFICATION",
|
||||
payload: data,
|
||||
})
|
||||
|
||||
export const removeNotification = (id) => ({
|
||||
type: "REMOVE_NOTIFICATION",
|
||||
payload: { id },
|
||||
})
|
@ -26,6 +26,7 @@ import store, { history } from "./store"
|
||||
|
||||
// Components
|
||||
import { AdminPanel } from "./components/admins/panel"
|
||||
import { Notifications } from "./components/notifications/notifications"
|
||||
import Alert from "./components/alerts/alert"
|
||||
import MovieList from "./components/movies/list"
|
||||
import MoviesRoute from "./components/movies/route"
|
||||
@ -48,6 +49,7 @@ const App = () => (
|
||||
<WsHandler />
|
||||
<NavBar />
|
||||
<Alert />
|
||||
<Notifications />
|
||||
<Container fluid>
|
||||
<Switch>
|
||||
<AdminRoute path="/admin" exact component={AdminPanel} />
|
||||
|
70
frontend/js/components/notifications/notification.js
Normal file
70
frontend/js/components/notifications/notification.js
Normal file
@ -0,0 +1,70 @@
|
||||
import React, { useState } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { connect } from "react-redux"
|
||||
|
||||
import { Toast } from "react-bootstrap"
|
||||
|
||||
import { removeNotification } from "../../actions/notifications"
|
||||
|
||||
const NotificationConnected = ({
|
||||
id,
|
||||
icon,
|
||||
title,
|
||||
message,
|
||||
imageUrl,
|
||||
autohide,
|
||||
delay,
|
||||
removeNotification,
|
||||
}) => {
|
||||
const [show, setShow] = useState(true)
|
||||
|
||||
const hide = () => {
|
||||
setShow(false);
|
||||
setTimeout(() => removeNotification(id), 200);
|
||||
}
|
||||
|
||||
return (
|
||||
<Toast
|
||||
show={show}
|
||||
onClose={hide}
|
||||
autohide={autohide}
|
||||
delay={delay}
|
||||
>
|
||||
<Toast.Header>
|
||||
{icon !== "" &&
|
||||
<i className={`fa fa-${icon} mr-2`} />
|
||||
}
|
||||
<strong className="mr-auto">{title}</strong>
|
||||
</Toast.Header>
|
||||
<Toast.Body>
|
||||
{message !== "" &&
|
||||
<span>{message}</span>
|
||||
}
|
||||
{imageUrl !== "" &&
|
||||
<img src={imageUrl} className="img-fluid mt-2 mr-auto" />
|
||||
}
|
||||
</Toast.Body>
|
||||
</Toast>
|
||||
)
|
||||
}
|
||||
NotificationConnected.propTypes = {
|
||||
id: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
message: PropTypes.string,
|
||||
imageUrl: PropTypes.string,
|
||||
autohide: PropTypes.bool,
|
||||
delay: PropTypes.number,
|
||||
removeNotification: PropTypes.func,
|
||||
};
|
||||
|
||||
NotificationConnected.defaultProps = {
|
||||
autohide: false,
|
||||
delay: 5000,
|
||||
icon: "",
|
||||
imageUrl: "",
|
||||
title: "Info",
|
||||
message: "",
|
||||
};
|
||||
|
||||
export const Notification = connect(null, {removeNotification})(NotificationConnected);
|
34
frontend/js/components/notifications/notifications.js
Normal file
34
frontend/js/components/notifications/notifications.js
Normal file
@ -0,0 +1,34 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { List } from "immutable"
|
||||
import { connect } from "react-redux"
|
||||
|
||||
import { Notification } from "./notification"
|
||||
|
||||
const NotificationsConnected = ({ notifications }) => {
|
||||
return (
|
||||
<div className="notifications">
|
||||
{notifications.map((el) => (
|
||||
<Notification
|
||||
key={el.get("id")}
|
||||
id={el.get("id")}
|
||||
icon={el.get("icon", "video-camera")}
|
||||
title={el.get("title", "Notification")}
|
||||
message={el.get("message")}
|
||||
autohide={el.get("autohide", true)}
|
||||
delay={el.get("delay", 10000)}
|
||||
imageUrl={el.get("imageUrl")}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
NotificationsConnected.propTypes = {
|
||||
notifications: PropTypes.instanceOf(List),
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
notifications: state.notifications,
|
||||
});
|
||||
|
||||
export const Notifications = connect(mapStateToProps)(NotificationsConnected);
|
@ -8,6 +8,7 @@ import alerts from "./alerts"
|
||||
import torrentStore from "./torrents"
|
||||
import adminStore from "./admins"
|
||||
import polochon from "./polochon"
|
||||
import notifications from "./notifications"
|
||||
|
||||
export default combineReducers({
|
||||
movieStore,
|
||||
@ -18,4 +19,5 @@ export default combineReducers({
|
||||
torrentStore,
|
||||
adminStore,
|
||||
polochon,
|
||||
notifications,
|
||||
});
|
||||
|
15
frontend/js/reducers/notifications.js
Normal file
15
frontend/js/reducers/notifications.js
Normal file
@ -0,0 +1,15 @@
|
||||
import { List, fromJS } from "immutable"
|
||||
|
||||
const defaultState = List();
|
||||
|
||||
const handlers = {
|
||||
"ADD_NOTIFICATION": (state, action) => state.push(fromJS({
|
||||
id: Math.random().toString(36).substring(7),
|
||||
...action.payload
|
||||
})),
|
||||
"REMOVE_NOTIFICATION": (state, action) =>
|
||||
state.filter((e) => (e.get("id") !== action.payload.id)),
|
||||
}
|
||||
|
||||
export default (state = defaultState, action) =>
|
||||
handlers[action.type] ? handlers[action.type](state, action) : state;
|
@ -77,7 +77,7 @@ div.show.dropdown.nav-item > div {
|
||||
.list-details {
|
||||
position: sticky;
|
||||
top: $body-padding-top;
|
||||
z-index: 1000;
|
||||
z-index: $zindex-sticky;
|
||||
height: calc(100vh - #{$body-padding-top});
|
||||
}
|
||||
|
||||
@ -130,3 +130,25 @@ div.sweet-alert > h2 {
|
||||
.wishlist-button:hover > i {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
position: fixed;
|
||||
top: $body-padding-top;
|
||||
z-index: $zindex-fixed;
|
||||
max-height: calc(100vh - #{$body-padding-top});
|
||||
right: 1rem;
|
||||
width: 18rem;
|
||||
}
|
||||
|
||||
.toast-header {
|
||||
background-color: $card-cap-bg;
|
||||
color: $gray-100;
|
||||
|
||||
> button > span {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.toast {
|
||||
background-color: $card-bg;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user