From 1ee2947afd5b31a8d1f51e42e733b0452b7bac18 Mon Sep 17 00:00:00 2001 From: ArtOfCode- <hello@artofcode.co.uk> Date: Mon, 3 Aug 2020 23:52:38 +0100 Subject: [PATCH] Add read/unread buttons to notifications --- app/assets/javascripts/notifications.js | 63 ++++++++++++++------- app/controllers/notifications_controller.rb | 4 +- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/notifications.js b/app/assets/javascripts/notifications.js index 7b5036abd..9137b9cd7 100644 --- a/app/assets/javascripts/notifications.js +++ b/app/assets/javascripts/notifications.js @@ -1,4 +1,22 @@ $(() => { + const makeNotification = notification => { + const template = `<div class="js-notification widget h-m-0 h-m-b-2 ${notification.is_read ? 'read' : 'is-teal'}"> + <div class="widget--body h-p-2"> + <div class="h-c-tertiary-600 h-fs-caption"> + ${notification.community_name} · + ${notification.is_read ? 'read' : `<strong>unread</strong>`} · + <span data-livestamp="${notification.created_at}">${notification.created_at}</span> + </div> + <p><a href="${notification.link}" data-id="${notification.id}" class="h-fw-bold is-not-underlined">${notification.content}</a></p> + <p class="has-font-size-caption"><a href="javascript:void(0)" data-notif-id="${notification.id}" class="js-notification-toggle"> + <i class="fas fa-${notification.is_read ? 'envelope' : 'envelope-open'}"></i> + mark ${notification.is_read ? 'unread' : 'read'} + </a></p> + </div> + </div>`; + return template; + }; + $('.inbox-toggle').on('click', async evt => { evt.preventDefault(); const $inbox = $('.inbox'); @@ -15,29 +33,13 @@ $(() => { const read = data.filter(n => n.is_read); unread.forEach(notification => { - const item = $(`<div class="widget is-teal h-m-0 h-m-b-2"> - <div class="widget--body h-p-2"> - <div class="h-c-tertiary-600 h-fs-caption"> - ${notification.community_name} · <strong>unread</strong> · - <span data-livestamp="${notification.created_at}">${notification.created_at}</span> - </div> - <a href="${notification.link}" data-id="${notification.id}" class="h-fw-bold is-not-underlined">${notification.content}</a> - </div> - </div>`); + const item = $(makeNotification(notification)); $inboxContainer.append(item); }); $inboxContainer.append(`<div role="separator" class="header-slide--separator"></div>`); read.forEach(notification => { - const item = $(`<div class="widget h-m-0 h-m-b-2"> - <div class="widget--body h-p-2"> - <div class="h-c-tertiary-600 h-fs-caption"> - ${notification.community_name} · read · - <span data-livestamp="${notification.created_at}">${notification.created_at}</span> - </div> - <a href="${notification.link}" data-id="${notification.id}" class="h-fw-bold is-not-underlined">${notification.content}</a> - </div> - </div>"`); + const item = $(makeNotification(notification)); $inboxContainer.append(item); }); @@ -53,7 +55,7 @@ $(() => { } }); - $(document).on('click', '.inbox a:not(.no-unread):not(.read)', async evt => { + $(document).on('click', '.inbox a:not(.no-unread):not(.read):not(.js-notification-toggle)', async evt => { const $tgt = $(evt.target); const id = $tgt.data('id'); await fetch(`/notifications/${id}/read`, { @@ -65,4 +67,27 @@ $(() => { const currentCount = parseInt($inboxCount.text(), 10); $inboxCount.text(currentCount - 1); }); + + $(document).on('click', '.js-notification-toggle', async ev => { + ev.stopPropagation(); + + const $tgt = $(ev.target).is('a') ? $(ev.target) : $(ev.target).parents('a'); + const id = $tgt.attr('data-notif-id'); + const resp = await fetch(`/notifications/${id}/read`, { + method: 'POST', + credentials: 'include', + headers: { 'Accept': 'application/json', 'X-CSRF-Token': QPixel.csrfToken() } + }); + const data = await resp.json(); + if (data.status !== 'success') { + console.error('Failed to toggle notification read state. Wat?'); + return; + } + + $tgt.parents('.js-notification')[0].outerHTML = makeNotification(data.notification); + const $inboxCount = $('.inbox-count'); + const currentCount = parseInt($inboxCount.text(), 10); + const newCount = data.notification.is_read ? currentCount - 1 : currentCount + 1; + $inboxCount.text(newCount); + }); }); \ No newline at end of file diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 4811ac2bc..112260c8f 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -22,14 +22,14 @@ class NotificationsController < ApplicationController return end - @notification.is_read = true + @notification.is_read = !@notification.is_read if @notification.save respond_to do |format| format.html do flash[:notice] = 'Marked as read.' render :index end - format.json { render json: { status: 'success' } } + format.json { render json: { status: 'success', notification: @notification }, methods: :community_name } end else respond_to do |format| -- GitLab