diff --git a/app/assets/javascripts/notifications.js b/app/assets/javascripts/notifications.js new file mode 100644 index 000000000..c8c697bc8 --- /dev/null +++ b/app/assets/javascripts/notifications.js @@ -0,0 +1,19 @@ +$(document.body).ready(function () { + $('.btn-more-notifications') + .on("ajax:success", function (e, data) { + var list = $('.notifications-list'); + var moreBtn = $('.btn-more-notifications'); + if (data.html) { + // Remove button if all notifications are shown + if (data.results_number < data.per_page) { + moreBtn.remove(); + // Otherwise update reference + } else { + moreBtn.attr('href', data.more_notifications_url); + } + $(list).append(data.html); + } else if (data.results_number < 1) { + moreBtn.remove(); + } + }); +}); diff --git a/app/assets/stylesheets/notifications.scss b/app/assets/stylesheets/notifications.scss new file mode 100644 index 000000000..dc7594de2 --- /dev/null +++ b/app/assets/stylesheets/notifications.scss @@ -0,0 +1,81 @@ +@import "colors"; +@import "mixins"; + +.notifications-container { + margin-bottom: 20px; + margin-top: 20px; +} + +.notifications-header { + background-color: $color-concrete; + border-left: 1px solid $color-alto; + border-right: 1px solid $color-alto; + border-top: 1px solid $color-alto; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + color: $color-dove-gray; + font-weight: bold; + padding: 8px; +} + +.notifications-list { + background-color: $color-white; + border: 1px solid $color-alto; + list-style: none; + margin-bottom: 0; + padding: 0; + + .notification { + border-bottom: 1px solid $color-alto; + padding-bottom: 10px; + padding-top: 10px; + + &:hover { + background-color: $color-mystic; + } + } + + .unseen { + border-left: 4px solid $color-theme-primary; + } + + .text-center { + margin-left: 10px; + padding-top: 10px; + } + + .assignment { + background-color: $color-theme-primary; + border-radius: 50%; + color: $color-wild-sand; + font-size: 15px; + padding: 7px; + } + + .system-message { + background-color: $color-theme-secondary; + border-radius: 50%; + color: $color-wild-sand; + font-size: 13px; + padding: 7px 10px; + } +} + + +.notifications-footer { + + background-color: $color-mystic; + + .btn-more-notifications { + border-bottom: 1px solid $color-alto; + border-left: 1px solid $color-alto; + border-right: 1px solid $color-alto; + margin: 0; + padding: 8px; + text-align: center; + + &:hover { + background-color: $color-mystic; + } + } +} diff --git a/app/controllers/user_notifications_controller.rb b/app/controllers/user_notifications_controller.rb index a74e0d44b..767ddfc86 100644 --- a/app/controllers/user_notifications_controller.rb +++ b/app/controllers/user_notifications_controller.rb @@ -1,4 +1,47 @@ class UserNotificationsController < ApplicationController + layout 'main' + + def index + @last_notification_id = params[:from].to_i || 0 + @per_page = 10 + + @notifications = + UserNotification.last_notifications(@current_user, + @last_notification_id, + @per_page + 1) + + @more_notifications_url = '' + + @overflown = @notifications.length > @per_page + + @notifications = + UserNotification.last_notifications(@current_user, + @last_notification_id, + @per_page) + + if @notifications.count > 0 + @more_notifications_url = url_for( + controller: 'user_notifications', + action: 'index', + format: :json, + from: @notifications.last.id + ) + end + + respond_to do |format| + format.html + format.json do + render json: { + per_page: @per_page, + results_number: @notifications.length, + more_notifications_url: @more_notifications_url, + html: render_to_string(partial: 'list.html.erb') + } + end + end + UserNotification.seen_by_user(current_user) + end + def recent_notifications @recent_notifications = UserNotification.recent_notifications(current_user) diff --git a/app/models/user_notification.rb b/app/models/user_notification.rb index ea34f52a0..17f9eb275 100644 --- a/app/models/user_notification.rb +++ b/app/models/user_notification.rb @@ -2,6 +2,15 @@ class UserNotification < ActiveRecord::Base belongs_to :user belongs_to :notification + def self.last_notifications(user, last_notification_id = nil, per_page = 10) + last_notification_id = 999999999999999999999999 if last_notification_id < 1 + Notification.joins(:user_notifications) + .where('user_notifications.user_id = ?', user.id) + .where('notifications.id < ?', last_notification_id) + .order(created_at: :DESC) + .limit(per_page) + end + def self.recent_notifications(user) Notification.joins(:user_notifications) .where('user_notifications.user_id = ?', user.id) diff --git a/app/views/user_notifications/_list.html.erb b/app/views/user_notifications/_list.html.erb new file mode 100644 index 000000000..831906c3f --- /dev/null +++ b/app/views/user_notifications/_list.html.erb @@ -0,0 +1,27 @@ +<% @notifications.each do |notification| %> +