Skip to content

Instantly share code, notes, and snippets.

@jberndsen
Created March 14, 2016 09:34
Show Gist options
  • Save jberndsen/fc8f1627278d406fc0d2 to your computer and use it in GitHub Desktop.
Save jberndsen/fc8f1627278d406fc0d2 to your computer and use it in GitHub Desktop.
Angular2-Redux-Immutable-Toastr
import {Injectable} from 'angular2/core';
import {guid} from '../../../helpers';
export const ADD_TOAST = 'ADD_TOAST';
export const REMOVE_TOAST = 'REMOVE_TOAST';
export const FADE_TOAST = 'FADE_TOAST';
@Injectable()
export class ToastrActionCreator {
constructor() {
}
displayToast(message: string, kind: string, sticky: boolean = false) {
return dispatch => {
var toastId = guid();
dispatch(this.showToast(message, kind, sticky, toastId));
if (!sticky) {
setTimeout(() => {
dispatch(this.dismissToast(toastId, true));
}, 5000);
}
};
}
dismissToast(id: string, fadeOut: boolean = false) {
return dispatch => {
if (!fadeOut) {
dispatch(this.removeToast(id));
} else {
dispatch(this.fadeToast(id));
setTimeout(() => {
dispatch(this.removeToast(id));
}, 1000);
}
};
}
private showToast(message: string, kind: string, sticky: boolean, id: string) {
return {
type: ADD_TOAST,
message: message,
kind: kind,
sticky: sticky,
id: id
};
}
private removeToast(id: string) {
return {
type: REMOVE_TOAST,
id: id
};
}
private fadeToast(id: string) {
return {
type: FADE_TOAST,
id: id
};
}
}
import {Component, Input, OnDestroy} from 'angular2/core';
import {NgSwitch, NgSwitchWhen} from 'angular2/common';
import {EcarisStore} from '../../store/ecarisStore';
import {ToastrActionCreator} from '../../store/actions/toastr.actions';
@Component({
selector: 'toastr',
template: require('./toastr.html'),
styles: [require('./toastr.scss')],
directives: [NgSwitch, NgSwitchWhen]
})
export class Toastr implements OnDestroy {
state = [];
private unsubscribe;
constructor(private store: EcarisStore, private actionCreator: ToastrActionCreator) {
this.unsubscribe = store.subscribe(newState => {
this.state = newState.toastr.toJS();
});
// EXAMPLE TOASTS:
//store.dispatch(actionCreator.displayToast('dit is een foutmelding', 'error', true));
//store.dispatch(actionCreator.displayToast('dit een waarschuwing', 'warning'));
//store.dispatch(actionCreator.displayToast('great success!', 'success', true));
//store.dispatch(actionCreator.displayToast('gewoon een berichtje', 'notice'));
}
ngOnDestroy() {
this.unsubscribe();
}
dismissToast(id) {
var action = this.actionCreator.dismissToast(id);
this.store.dispatch(action);
}
}
<div class="toastr">
<div *ngFor="#toast of state" class="toastr__toast toastr__toast--{{toast.kind}}"
[ngClass]="{fadeout: toast.fadeout}">
{{toast.message}}
<span (click)="dismissToast(toast.id)" class="toastr__toast__close"><i class="fa fa-close"></i></span>
</div>
</div>
import Immutable = require('immutable');
import { ADD_TOAST, REMOVE_TOAST, FADE_TOAST } from '../actions/toastr.actions';
const initialState = Immutable.fromJS([]);
export const toastrReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TOAST:
return addToast(state, action);
case REMOVE_TOAST:
return removeToast(state, action);
case FADE_TOAST:
return fadeToast(state, action);
default:
return state;
}
};
function addToast(state, action) {
const newToast = Immutable.fromJS({ message: action.message, kind: action.kind, sticky: action.sticky, id: action.id });
return state.push(newToast);
}
function removeToast(state, action) {
return state.filter(t => t.get('id') !== action.id);
}
function fadeToast(state, action) {
const index = state.findIndex(t => t.get('id') === action.id);
return state.update(index, t => t.set('fadeout', true));
}
@import "../../../styles/style.scss";
.toastr {
position: fixed;
bottom: 25px;
right: 25px;
width: 25%;
z-index: 500;
&__toast {
border-radius: 2px;
padding: 15px;
margin-bottom: 10px;
&__close {
float: right;
cursor: pointer;
}
&--error {
background-color: $color-accent-red;
color: white;
}
&--warning {
background-color: $color-virorange;
}
&--success {
background-color: $color-accent-green;
color: white;
}
&--notice {
background-color: $color-virblue-light;
}
}
}
.fadeout {
animation-name: fadeout;
animation-duration: 1.2s;
}
@keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment