notifications 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6c1411a1372418b519675ff4778fc9b6ce5667e
4
- data.tar.gz: 5d88e4b9ed4a7abd5ea0dc5af06a72df5e1ec196
3
+ metadata.gz: da3d093b0b1103eaf30087ae164dffd0c081ab08
4
+ data.tar.gz: f87db9bac406ca6547a5a24e7eb5580b3d4bc97f
5
5
  SHA512:
6
- metadata.gz: be0439a6e8a0dcc21cc045a67719f51038b2d8964d7800fc146c811f5ef3d5d12e45e502e98606d1bc22d7ee4b53fe5786ccc8e680cd73aa23569295256b8fe9
7
- data.tar.gz: 335956df1f27ed9f3cf279735ff9ad94eb0b883cc89b9968299f6daa8ef6e3b3c0178f845a92784ebaa6e8156695165f74f8f7e1b3da05818d463c410abb17d3
6
+ metadata.gz: b09f5e76bc019607928a8360810f4da6fbd3730aa29adf9dc9fb344d5ae9cbf120bc454bb803064c5ebd71fc947fadd28f834093e59190da8c246d803680b2e8
7
+ data.tar.gz: d99136bd5ccd35afc9771beec8d342c75ba6423e53ebcffc5ef3456c8dfa0939f5fe7ad8d6476534277daa8f625e7a41d3fe9e6112da37fb4b72dca840681ee2
data/README.md CHANGED
@@ -2,6 +2,75 @@
2
2
 
3
3
  Rails mountable Notification for any applications.
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/notifications.svg)](https://badge.fury.io/rb/notifications) [![Build Status](https://travis-ci.org/rails-engine/notifications.svg)](https://travis-ci.org/rails-engine/notifications) [![Code Climate](https://codeclimate.com/github/rails-engine/notifications/badges/gpa.svg)](https://codeclimate.com/github/rails-engine/notifications) [![codecov.io](https://codecov.io/github/rails-engine/notifications/coverage.svg?branch=master)](https://codecov.io/github/rails-engine/notifications?branch=master) [![](http://inch-ci.org/github/rails-engine/notifications.svg?branch=master)](http://inch-ci.org/github/rails-engine/notifications?branch=master)
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ # Gemfile
11
+ gem 'notifications'
12
+ ```
13
+
14
+ And then run `bundle install`.
15
+
16
+ Now you have notifications generator in Rails application:
17
+
18
+ ```bash
19
+ $ rails g notifications:install
20
+ ```
21
+
22
+ And, you can generate views, controller if you need custom them:
23
+
24
+ ```bash
25
+ $ rails g notifications:views
26
+ $ rails g notifications:controllers
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ### Create a Notification
32
+
33
+ ```ruby
34
+ class User
35
+ def follow(user)
36
+ Notification.create(notify_type: 'follow', actor: self, user: user)
37
+ end
38
+ end
39
+
40
+ class Comment
41
+ belongs_to :post
42
+ belongs_user :user
43
+
44
+ after_commit :create_notifications, on: [:create]
45
+ def create_notifications
46
+ Notification.create(
47
+ notify_type: 'comment',
48
+ actor: self.user,
49
+ user: self.post.user,
50
+ target: self)
51
+ end
52
+ end
53
+ ```
54
+
55
+ Get user unread count:
56
+
57
+ ```rb
58
+ count = Notification.unread_count(current_user)
59
+ ```
60
+
61
+ ### Write your custom Notification partial view for notify_types:
62
+
63
+ TODO...
64
+
65
+ ### Mark notifications as read
66
+
67
+ You can set multiple Notification as read by:
68
+
69
+ ```ruby
70
+ notification_ids = [1, 2 ...]
71
+ Notification.read!(current_user.id, notification_ids)
72
+ ```
73
+
5
74
  ## Contributing
6
75
  Contribution directions go here.
7
76
 
data/Rakefile CHANGED
@@ -4,24 +4,11 @@ rescue LoadError
4
4
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
5
  end
6
6
 
7
- require 'rdoc/task'
8
-
9
- RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'Notifications'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
15
- end
16
-
17
7
  APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
- load 'rails/tasks/engine.rake'
19
-
20
8
 
9
+ load 'rails/tasks/engine.rake'
21
10
  load 'rails/tasks/statistics.rake'
22
11
 
23
-
24
-
25
12
  Bundler::GemHelper.install_tasks
26
13
 
27
14
  require 'rake/testtask'
@@ -33,5 +20,5 @@ Rake::TestTask.new(:test) do |t|
33
20
  t.verbose = false
34
21
  end
35
22
 
36
-
23
+ task 'assets:precompile' => 'app:assets:precompile'
37
24
  task default: :test
@@ -1,5 +1,18 @@
1
1
  module Notifications
2
- class ApplicationController < ActionController::Base
3
- protect_from_forgery with: :exception
2
+ class ApplicationController < ::ApplicationController
3
+ helper_method :current_user, :owner?, :admin?
4
+
5
+ alias_method :origin_current_user, Notifications.config.current_user_method.to_sym
6
+ alias_method :origin_authenticate_user!, Notifications.config.authenticate_user_method.to_sym
7
+
8
+ before_action :authenticate_user!
9
+
10
+ def current_user
11
+ origin_current_user
12
+ end
13
+
14
+ def authenticate_user!
15
+ origin_authenticate_user!
16
+ end
4
17
  end
5
18
  end
@@ -0,0 +1,18 @@
1
+ module Notifications
2
+ class NotificationsController < Notifications::ApplicationController
3
+ def index
4
+ @notifications = current_user.notifications.includes(:actor).order('id desc')
5
+
6
+ unread_ids = []
7
+ @notifications.each do |n|
8
+ unread_ids << n.id unless n.read?
9
+ end
10
+ # Notification.read!(unread_ids)
11
+ end
12
+
13
+ def clean
14
+ Notification.where(user_id: current_user.id).delete_all
15
+ redirect_to notifications_path
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ # Auto generate with notifications gem.
2
+ class Notification < ActiveRecord::Base
3
+ include Notifications::Model
4
+
5
+ # Write your custom methods...
6
+ end
@@ -0,0 +1,13 @@
1
+ <div id="notification-<%= notification.id %>"
2
+ data-id="<%= notification.id %>"
3
+ class="media notification<%= ' unread' if !notification.read? %>">
4
+ <div class="media-left">
5
+ <%= link_to image_tag(notification.actor_avatar_url), notification.actor_profile_url, title: notification.actor_name, class: 'user-avatar' %>
6
+ </div>
7
+ <div class="media-body">
8
+ <%= render partial: "/notifications/#{notification.notify_type}", locals: { notification: notification } %>
9
+ </div>
10
+ <div class="media-right">
11
+ <%= l notification.created_at, format: :short %>
12
+ </div>
13
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="notifications row">
2
+ <div class="heading clearfix">
3
+ <%= t('notifications.all_notifications') %>
4
+
5
+ <span class="pull-xs-right">
6
+ <%= link_to t('notifications.clean_all'), notifications.clean_notifications_path, class: 'btn btn-danger', method: 'delete' %>
7
+ </span>
8
+ </div>
9
+ <div class="list">
10
+ <%= render @notifications %>
11
+ </div>
12
+ </div>
@@ -0,0 +1,22 @@
1
+ # notifications Config
2
+ Notifications.configure do
3
+ # Class name of you User model, default: 'User'
4
+ # self.user_class = 'User'
5
+
6
+ # Method of user name in User model, default: 'name'
7
+ # self.user_name_method = 'name'
8
+
9
+ # Method of user avatar in User model, default: nil
10
+ # self.user_avatar_url_method = nil
11
+
12
+ # Method name of user profile page path, in User model, default: 'profile_url'
13
+ # self.user_profile_url_method = 'profile_url'
14
+
15
+ # authenticate_user method in your Controller, default: 'authenticate_user!'
16
+ # If you use Devise, authenticate_user! is correct
17
+ # self.authenticate_user_method = 'authenticate_user!'
18
+
19
+ # current_user method name in your Controller, default: 'current_user'
20
+ # If you use Devise, current_user is correct
21
+ # self.current_user_method = 'current_user'
22
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ notifications:
3
+ all_notifications: 'All Notifications'
4
+ clean_all: 'Clean All'
data/config/routes.rb CHANGED
@@ -1,2 +1,7 @@
1
1
  Notifications::Engine.routes.draw do
2
+ resources :notifications, path: '' do
3
+ collection do
4
+ delete :clean
5
+ end
6
+ end
2
7
  end
@@ -0,0 +1,21 @@
1
+ class CreateNotifications < ActiveRecord::Migration
2
+ def change
3
+ create_table :notifications do |t|
4
+ t.integer :user_id, null: false
5
+ t.integer :actor_id
6
+ t.string :notify_type, null: false
7
+ t.string :target_type
8
+ t.integer :target_id
9
+ t.string :second_target_type
10
+ t.integer :second_target_id
11
+ t.string :third_target_type
12
+ t.integer :third_target_id
13
+ t.datetime :read_at
14
+
15
+ t.timestamps null: false
16
+ end
17
+
18
+ add_index :notifications, [:user_id, :notify_type]
19
+ add_index :notifications, [:user_id]
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ require 'rails/generators'
3
+ module Notifications
4
+ module Generators
5
+ class ControllersGenerator < Rails::Generators::Base #:nodoc:
6
+ source_root File.expand_path("../../../../app/controllers", __FILE__)
7
+ desc "Used to copy Notifications's controllers to your application's controllers."
8
+
9
+ def copy_controllers
10
+ %w(nodes replies topics).each do |fname|
11
+ path = "#{Rails.root}/app/controllers/notifications/#{fname}_controller.rb"
12
+ if File.exists?(path)
13
+ puts "Skipping notifications/#{fname}_controller.rb creation, as file already exists!"
14
+ else
15
+ puts "Adding controller (notifications/#{fname}_controller.rb)..."
16
+ template "notifications/#{fname}_controller.rb", path
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails/generators'
2
+ module Notifications
3
+ module Generators
4
+ class I18nGenerator < Rails::Generators::Base
5
+ desc "Create Notifications's default I18n files"
6
+ source_root File.expand_path("../../../../", __FILE__)
7
+
8
+ def add_locales
9
+ %w(en.yml zh-CN.yml).each do |fname|
10
+ path = "#{Rails.root}/config/locales/notifications.#{fname}"
11
+ if File.exists?(path)
12
+ puts "Skipping config/locales/notifications.#{fname} creation, as file already exists!"
13
+ else
14
+ puts "Adding locale (config/locales/notifications.#{fname})..."
15
+ template "config/locales/notifications.#{fname}", path
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ require 'rails/generators'
2
+ module Notifications
3
+ module Generators
4
+ class InstallGenerator < Rails::Generators::Base
5
+ desc "Create Notifications's base files"
6
+ source_root File.expand_path("../../../../", __FILE__)
7
+
8
+ def add_initializer
9
+ path = "#{Rails.root}/config/initializers/notifications.rb"
10
+ if File.exists?(path)
11
+ puts "Skipping config/initializers/notifications.rb creation, as file already exists!"
12
+ else
13
+ puts "Adding Homeland initializer (config/initializers/notifications.rb)..."
14
+ template "config/initializers/notifications.rb", path
15
+ end
16
+ end
17
+
18
+ def add_models
19
+ path = "#{Rails.root}/app/models/notification.rb"
20
+ if File.exists?(path)
21
+ puts "Skipping notification.rb creation, as file already exists!"
22
+ else
23
+ puts "Adding model (notification.rb)..."
24
+ template "app/models/notification.rb", path
25
+ end
26
+ end
27
+
28
+ def add_migrations
29
+ exec("rails notifications:install:migrations")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ require 'rails/generators'
3
+ module Notifications
4
+ module Generators
5
+ class ViewsGenerator < Rails::Generators::Base #:nodoc:
6
+ source_root File.expand_path("../../../../app/views", __FILE__)
7
+ desc "Used to copy Notifications's views to your application's views."
8
+
9
+ def copy_views
10
+ directory 'homeland', "app/views/notifications"
11
+ directory 'layouts/notifications', "app/views/layouts/notifications"
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/notifications.rb CHANGED
@@ -1,5 +1,25 @@
1
+ require "notifications/model"
1
2
  require "notifications/engine"
3
+ require "notifications/configuration"
4
+ require "notifications/version"
2
5
 
3
6
  module Notifications
4
- # Your code goes here...
7
+ class << self
8
+ def config
9
+ return @config if defined?(@config)
10
+ @config = Configuration.new
11
+ @config.per_page = 32
12
+ @config.user_class = 'User'
13
+ @config.user_name_method = 'name'
14
+ @config.user_avatar_url_method = nil
15
+ @config.user_profile_url_method = 'profile_url'
16
+ @config.authenticate_user_method = 'authenticate_user!'
17
+ @config.current_user_method = 'current_user'
18
+ @config
19
+ end
20
+
21
+ def configure(&block)
22
+ config.instance_exec(&block)
23
+ end
24
+ end
5
25
  end
@@ -0,0 +1,46 @@
1
+ module Notifications
2
+ class Configuration
3
+ # class name of you User model, default: 'User'
4
+ attr_accessor :user_class
5
+
6
+ # method of user name in User model, default: 'name'
7
+ attr_accessor :user_name_method
8
+
9
+ # method of user avatar in User model, default: nil
10
+ #
11
+ # We suggest you give image size more than 48x48 px.
12
+ #
13
+ # Example:
14
+ #
15
+ # class User
16
+ # def avatar_url
17
+ # self.avatar.url('48x48')
18
+ # end
19
+ # end
20
+ #
21
+ # config.user_avatar_url_method = :avatar_url
22
+ #
23
+ attr_accessor :user_avatar_url_method
24
+
25
+ # method name of user profile page path, in User model, default: 'profile_url'
26
+ # Example:
27
+ #
28
+ # class User
29
+ # def profile_url
30
+ # "http://www.host.com/u/#{self.username}"
31
+ # end
32
+ # end
33
+ #
34
+ # config.user_profile_url_method = 'profile_url'
35
+ attr_accessor :user_profile_url_method
36
+
37
+ # current_user method name in your Controller, default: 'current_user'
38
+ attr_accessor :current_user_method
39
+
40
+ # authenticate_user method in your Controller, default: 'authenticate_user!'
41
+ attr_accessor :authenticate_user_method
42
+
43
+ # pagination size, default: 32
44
+ attr_accessor :per_page
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ module Notifications
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ DEFAULT_AVATAR = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAMAAAAJixmgAAAAFVBMVEWkpKSnp6eqqqq3t7fS0tLV1dXZ2dmshcKEAAAAtklEQVR4Ae3XsRGAAAjAQFRk/5HtqaTz5H+DlInvAQAAAAAAAAAAAAAAAAAAAACymiveO6o7BQsWLFiwYMGCBS8PFixYsGDBggULFixYsGDBggULFixYsGDBggULFixYsGDBc4IFCxYsWLBgwYIFC14ZfOeAPRQ8IliwYMGCBQsWLFiwYMGCBQsWLFiwYMGCBQsWLFiwYMGCBQsWLFiwYMGCBQv+JQAAAAAAAAAAAAAAAAAAAOAB4KJfdHmj+kwAAAAASUVORK5CYII='
6
+
7
+ included do
8
+ belongs_to :actor, class_name: Notifications.config.user_class
9
+ belongs_to :user, class_name: Notifications.config.user_class
10
+
11
+ belongs_to :target, polymorphic: true
12
+ belongs_to :second_target, polymorphic: true
13
+ belongs_to :third_target, polymorphic: true
14
+
15
+ scope :unread, -> { where(read_at: nil) }
16
+ end
17
+
18
+ def read?
19
+ self.read_at.present?
20
+ end
21
+
22
+ def actor_name
23
+ return "" if self.actor.blank?
24
+ self.actor.send(Notifications.config.user_name_method)
25
+ end
26
+
27
+ def actor_avatar_url
28
+ return DEFAULT_AVATAR if Notifications.config.user_avatar_url_method.blank?
29
+ return DEFAULT_AVATAR if self.actor.blank?
30
+ self.actor.send(Notifications.config.user_avatar_url_method)
31
+ end
32
+
33
+ def actor_profile_url
34
+ return '#' if self.actor.blank?
35
+ self.actor.send(Notifications.config.user_profile_url_method)
36
+ end
37
+
38
+ module ClassMethods
39
+ def read!(ids = [])
40
+ return if ids.blank?
41
+ Notification.where(id: ids).update_all(read_at: Time.now)
42
+ end
43
+
44
+ def unread_count(user)
45
+ Notification.where(user: user).unread.count
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module Notifications
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notifications
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
@@ -30,20 +30,6 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '5.1'
33
- - !ruby/object:Gem::Dependency
34
- name: mysql2
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
- type: :development
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
33
  description: Rails mountable Notification for any applications.
48
34
  email:
49
35
  - huacnlee@gmail.com
@@ -54,18 +40,23 @@ files:
54
40
  - MIT-LICENSE
55
41
  - README.md
56
42
  - Rakefile
57
- - app/assets/config/notifications_manifest.js
58
- - app/assets/javascripts/notifications/application.js
59
- - app/assets/stylesheets/notifications/application.css
60
43
  - app/controllers/notifications/application_controller.rb
61
- - app/helpers/notifications/application_helper.rb
62
- - app/jobs/notifications/application_job.rb
63
- - app/mailers/notifications/application_mailer.rb
64
- - app/models/notifications/application_record.rb
65
- - app/views/layouts/notifications/application.html.erb
44
+ - app/controllers/notifications/notifications_controller.rb
45
+ - app/models/notification.rb
46
+ - app/views/notifications/notifications/_notification.html.erb
47
+ - app/views/notifications/notifications/index.html.erb
48
+ - config/initializers/notifications.rb
49
+ - config/locales/notifications.en.yml
66
50
  - config/routes.rb
51
+ - db/migrate/20160328045436_create_notifications.rb
52
+ - lib/generators/notifications/controllers_generator.rb
53
+ - lib/generators/notifications/i18n_generator.rb
54
+ - lib/generators/notifications/install_generator.rb
55
+ - lib/generators/notifications/views_generator.rb
67
56
  - lib/notifications.rb
57
+ - lib/notifications/configuration.rb
68
58
  - lib/notifications/engine.rb
59
+ - lib/notifications/model.rb
69
60
  - lib/notifications/version.rb
70
61
  - lib/tasks/notifications_tasks.rake
71
62
  homepage: https://github.com/rails-engine/notifications
@@ -1,2 +0,0 @@
1
- //= link_directory ../javascripts/notifications .js
2
- //= link_directory ../stylesheets/notifications .css
@@ -1,13 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- //= require_tree .
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,4 +0,0 @@
1
- module Notifications
2
- module ApplicationHelper
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module Notifications
2
- class ApplicationJob < ActiveJob::Base
3
- end
4
- end
@@ -1,6 +0,0 @@
1
- module Notifications
2
- class ApplicationMailer < ActionMailer::Base
3
- default from: 'from@example.com'
4
- layout 'mailer'
5
- end
6
- end
@@ -1,5 +0,0 @@
1
- module Notifications
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
- end
5
- end
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Notifications</title>
5
- <%= stylesheet_link_tag "notifications/application", media: "all" %>
6
- <%= javascript_include_tag "notifications/application" %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>