From ddf58b54f265a92f678de013e12ce99c1f5a1cef Mon Sep 17 00:00:00 2001 From: James Wang Date: Tue, 22 Jan 2019 23:48:28 -0600 Subject: [PATCH 1/3] Automatically close notifications for answered questions --- src/redux/questionNotificationMiddleware.js | 46 ++++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/redux/questionNotificationMiddleware.js b/src/redux/questionNotificationMiddleware.js index a47b753d..6bdee0ba 100644 --- a/src/redux/questionNotificationMiddleware.js +++ b/src/redux/questionNotificationMiddleware.js @@ -1,8 +1,14 @@ /* eslint-env browser */ -import { CREATE_QUESTION, UPDATE_QUESTION } from '../constants/ActionTypes' +import { + CREATE_QUESTION, + DELETE_QUESTION, + UPDATE_QUESTION, +} from '../constants/ActionTypes' import { baseUrl } from '../util' -function sendNotificationIfEnabled(title, options) { +const notifications = {} + +function sendNotificationIfEnabled(title, options, queueId, questionId) { if ( typeof window !== 'undefined' && window.localStorage && @@ -13,11 +19,27 @@ function sendNotificationIfEnabled(title, options) { n.onclick = () => { window.focus() n.close() + delete notifications[queueId][questionId] + } + if (!(queueId in notifications)) { + notifications[queueId] = {} } + notifications[queueId][questionId] = n } } } +function closeNotification(queueId, questionId) { + if (!(queueId in notifications)) { + return + } + if (!(questionId in notifications[queueId])) { + return + } + notifications[queueId][questionId].close() + delete notifications[queueId][questionId] +} + function isOnDutyStaff(activeStaff, user) { return Object.keys(activeStaff).some( key => activeStaff[key].userId === user.id @@ -34,7 +56,7 @@ export default store => next => action => { // On duty staff cannot ask questions, so no need to filter by askedById if (isOnDutyStaff(activeStaff, user)) { const title = 'New question' - const { name, location, queueId } = action.question + const { id, name, location, queueId } = action.question const queue = state.queues.queues[queueId] let body = '' @@ -47,25 +69,37 @@ export default store => next => action => { const options = { body, icon: `${baseUrl}/static/notif_icon.png`, + tag: `queue-${queueId}/question-${id}`, } - sendNotificationIfEnabled(title, options) + sendNotificationIfEnabled(title, options, queueId, id) } // Notification for question being answered by staff to student // Note: Only UPDATE_QUESTION action will happen on student's side, but not UPDATE_QUESTION_ANSWERING } else if (action.type === UPDATE_QUESTION.SUCCESS) { const { question } = action + const { activeStaff } = state.activeStaff // If question is marked as being answered and it is the student who ask this question const markedBeingAnswered = !state.questions.questions[question.id].beingAnswered && question.beingAnswered - if (markedBeingAnswered && user.id === question.askedById) { + if (isOnDutyStaff(activeStaff, user)) { + closeNotification(question.queueId, question.id) + } else if (markedBeingAnswered && user.id === question.askedById) { + const { id, queueId } = question const name = question.answeredBy.name || question.answeredBy.netid const title = `${name} is answering your question` const options = { icon: `${baseUrl}/static/notif_icon.png`, + tag: `queue-${queueId}/question-${id}`, } - sendNotificationIfEnabled(title, options) + sendNotificationIfEnabled(title, options, queueId, id) + } + } else if (action.type === DELETE_QUESTION.SUCCESS) { + const { activeStaff } = state.activeStaff + const { questionId, queueId } = action + if (isOnDutyStaff(activeStaff, user)) { + closeNotification(queueId, questionId) } } return next(action) From aec9107d51c04718d6d234d6fc3a1a70f90e203a Mon Sep 17 00:00:00 2001 From: James Wang Date: Sat, 26 Jan 2019 18:51:02 -0600 Subject: [PATCH 2/3] Close student notifications when a question is finished/cancelled --- src/redux/questionNotificationMiddleware.js | 33 ++++++++++++--------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/redux/questionNotificationMiddleware.js b/src/redux/questionNotificationMiddleware.js index 6bdee0ba..63265ce6 100644 --- a/src/redux/questionNotificationMiddleware.js +++ b/src/redux/questionNotificationMiddleware.js @@ -78,29 +78,34 @@ export default store => next => action => { } else if (action.type === UPDATE_QUESTION.SUCCESS) { const { question } = action const { activeStaff } = state.activeStaff - // If question is marked as being answered and it is the student who ask this question + if (isOnDutyStaff(activeStaff, user)) { + // Close question creation notification + closeNotification(question.queueId, question.id) + } + const markedBeingAnswered = !state.questions.questions[question.id].beingAnswered && question.beingAnswered - if (isOnDutyStaff(activeStaff, user)) { - closeNotification(question.queueId, question.id) - } else if (markedBeingAnswered && user.id === question.askedById) { + if (user.id === question.askedById) { const { id, queueId } = question - const name = question.answeredBy.name || question.answeredBy.netid - const title = `${name} is answering your question` - const options = { - icon: `${baseUrl}/static/notif_icon.png`, - tag: `queue-${queueId}/question-${id}`, + // If question is marked as being answered and it is the user who asked this question + if (markedBeingAnswered) { + const name = question.answeredBy.name || question.answeredBy.netid + const title = `${name} is answering your question` + + const options = { + icon: `${baseUrl}/static/notif_icon.png`, + tag: `queue-${queueId}/question-${id}`, + } + sendNotificationIfEnabled(title, options, queueId, id) + } else { + closeNotification(queueId, id) } - sendNotificationIfEnabled(title, options, queueId, id) } } else if (action.type === DELETE_QUESTION.SUCCESS) { - const { activeStaff } = state.activeStaff const { questionId, queueId } = action - if (isOnDutyStaff(activeStaff, user)) { - closeNotification(queueId, questionId) - } + closeNotification(queueId, questionId) } return next(action) } From e88f72fc0f4eff1e5de6e2bb089fa7308af75dd3 Mon Sep 17 00:00:00 2001 From: James Wang Date: Sat, 26 Jan 2019 18:53:10 -0600 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf0ff487..9f8e3ad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ with the current date and the next changes should go under a **[Next]** header. * Use enter key to submit new question, new course, or new queue. ([@rohinb2](https://github.com/rohinb2) in [#161](https://github.com/illinois/queue/pull/161)) * Specify which queue is being deleted. ([@james9909](https://github.com/james9909) in [#179](https://github.com/illinois/queue/pull/179)) * Switch to maintaining our own user sessions outside of Shibboleth. ([@nwalters512](https://github.com/nwalters512) in [#182](https://github.com/illinois/queue/pull/182)) +* Automatically close resolved notifications. ([@james9909](https://github.com/james9909) in [#183](https://github.com/illinois/queue/pull/183)) ## 17 January 2019