diff --git a/app/assets/javascripts/notifications.js b/app/assets/javascripts/notifications.js new file mode 100644 index 000000000..38185e762 --- /dev/null +++ b/app/assets/javascripts/notifications.js @@ -0,0 +1,17 @@ +$(document.body).ready(function () { + $('.btn-more-notifications') + .on("ajax:success", function (e, data) { + if (data.html) { + var list = $('.notifications-list'); + var moreBtn = $('.btn-more-notifications'); + // 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); + } + }); +}); diff --git a/app/assets/stylesheets/notifications.scss b/app/assets/stylesheets/notifications.scss index 397347c2f..7c7d54d63 100644 --- a/app/assets/stylesheets/notifications.scss +++ b/app/assets/stylesheets/notifications.scss @@ -1,58 +1,82 @@ @import "colors"; @import "mixins"; -.notifications-list { - list-style: none; - min-width: 450px; - padding-bottom: 0; - padding-top: 0; +.notifications-container { + margin-top: 20px; +} - .notification { - border-bottom: 1px solid $color-alto; - padding-bottom: 10px; - padding-top: 10px; +.notifications-header { + background-color: $color-concrete; + border-top: 1px solid $color-alto; + border-left: 1px solid $color-alto; + border-right: 1px solid $color-alto; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + color: $color-dove-gray; + font-weight: bold; + padding: 8px; +} - &:hover { - background-color: $color-concrete; +.notifications-body { + + .notifications-list { + background-color: $color-white; + border: 1px solid $color-alto; + list-style: none; + margin-bottom: 0px; + padding: 0; + + .notification { + border-bottom: 1px solid $color-alto; + padding-bottom: 10px; + padding-top: 10px; + + &:hover { + background-color: #ECF5FC; + } + } + + .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; } } +} - .unseen { - border-left: 4px solid $color-theme-primary; - } +.notifications-footer { - .text-center { - margin-left: 10px; - padding-top: 10px; - } + background-color: $color-mystic; - .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-header { - background-color: $color-theme-primary; - color: $color-wild-sand; - font-weight: bold; - padding: 8px; - } - - .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: 0px; 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 16949262d..6530e3dde 100644 --- a/app/controllers/user_notifications_controller.rb +++ b/app/controllers/user_notifications_controller.rb @@ -1,9 +1,44 @@ class UserNotificationsController < ApplicationController - layout "fluid" + layout 'main' def index - @notifications = UserNotification.list_all(@current_user) - @notifications_by_type = { :assignment => 3, :recent_changes => 4, :system_message => 5 } + @last_notification_id = params[:from].to_i || 0 + @per_page = 5 + + @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 { + 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 + mark_seen_notification @notifications end def recent_notifications diff --git a/app/models/user_notification.rb b/app/models/user_notification.rb index ca37d07d4..17f9eb275 100644 --- a/app/models/user_notification.rb +++ b/app/models/user_notification.rb @@ -2,10 +2,13 @@ class UserNotification < ActiveRecord::Base belongs_to :user belongs_to :notification - def self.list_all(user) + 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) diff --git a/app/views/user_notifications/_list.html.erb b/app/views/user_notifications/_list.html.erb new file mode 100644 index 000000000..906bb0fa9 --- /dev/null +++ b/app/views/user_notifications/_list.html.erb @@ -0,0 +1,27 @@ +<% @notifications.each do |notification| %> +