Created
February 16, 2020 17:02
-
-
Save dufia/09d76a2cdfe1e0abeae934a8dfd7dd29 to your computer and use it in GitHub Desktop.
Toaster saga
This file contains hidden or 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
import { HIDE_TOAST, SHOW_TOAST, updateToasts } from '../actions'; | |
import { all, delay, fork, put, take, takeEvery } from 'redux-saga/effects'; | |
function* toasterSaga() { | |
const MaxToasts = 3; | |
const ToastDisplayTime = 5000; | |
const ToastAnimationTime = 500; | |
const toastTimers: number[] = []; // keep track of when toasts are added | |
const pendingToasts: any[] = []; | |
let activeToasts: any[] = []; | |
function* displayToast(toast) { | |
// get the latest timer | |
const latestTimer = toastTimers.pop() || Date.now(); | |
// create a latest timer from previous latest timer and add 300ms | |
toastTimers.push(latestTimer + 300); | |
// wait enough time so there is a delay between two slides showing | |
yield delay(latestTimer - Date.now()); | |
activeToasts.push(toast); | |
yield put(updateToasts([...activeToasts])); | |
yield delay(ToastDisplayTime); | |
toast.open = false; | |
yield put(updateToasts([...activeToasts])); | |
yield delay(ToastAnimationTime); | |
activeToasts = activeToasts.filter(t => t.id !== toast.id); | |
yield put(updateToasts([...activeToasts])); | |
yield fork(toastScheduler); | |
} | |
function* toastWatcher() { | |
while (true) { | |
const { payload: toast } = yield take(SHOW_TOAST); | |
pendingToasts.push(toast); | |
yield fork(toastScheduler); | |
} | |
} | |
yield takeEvery(HIDE_TOAST, removeToast); | |
function* removeToast(action) { | |
const toast = activeToasts.find(t => t.id === action.payload); | |
if (toast) { | |
toast.open = false; | |
yield put(updateToasts([...activeToasts])); | |
yield delay(ToastAnimationTime); | |
activeToasts = activeToasts.filter(t => t.id !== toast.id); | |
yield put(updateToasts([...activeToasts])); | |
yield fork(toastScheduler); | |
} | |
} | |
function* toastScheduler() { | |
const canDisplayToast = activeToasts.length < MaxToasts && pendingToasts.length > 0; | |
if (canDisplayToast) { | |
const toast = pendingToasts.shift(); | |
yield fork(displayToast, toast); | |
} | |
} | |
yield toastWatcher(); | |
} | |
export default function* rootSaga() { | |
yield all([toasterSaga()]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment