notification-settings 3.0.2 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -275
- data/lib/notifications-rails.rb +6 -0
- metadata +15 -25
- data/app/models/notification_settings/subscription.rb +0 -14
- data/lib/generators/notification_settings/install_generator.rb +0 -42
- data/lib/generators/templates/install/initializer.rb +0 -40
- data/lib/generators/templates/install/notifications_migration.rb.erb +0 -25
- data/lib/notification-settings.rb +0 -20
- data/lib/notification_settings/category_preferences_form.rb +0 -13
- data/lib/notification_settings/configuration.rb +0 -38
- data/lib/notification_settings/delivery_method_preferences_form.rb +0 -15
- data/lib/notification_settings/engine.rb +0 -9
- data/lib/notification_settings/notification_lib.rb +0 -168
- data/lib/notification_settings/notification_scopes.rb +0 -24
- data/lib/notification_settings/preferences_form.rb +0 -11
- data/lib/notification_settings/settings.rb +0 -28
- data/lib/notification_settings/status.rb +0 -64
- data/lib/notification_settings/subscribable.rb +0 -48
- data/lib/notification_settings/subscriber.rb +0 -34
- data/lib/notification_settings/target.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81f51d7d4a8dca20f5f20c248b34ea9f9290e8844285dfd93b93111d3f1c27cd
|
4
|
+
data.tar.gz: bd923e061018cffba1249a8f728db477acad1a3eea9879f7965bc786245c54ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4f50488e3f1d1b4df6f290e02fedbe56a544cbd870e7f7d59b22787da3464663258abe3b4e12ce2c38478cf0753a6973556d0b3fd3e7f73ce7b1facedb097b0
|
7
|
+
data.tar.gz: 1c55207dc022117e228e7f39753ae322999d6dae499e53b78cfb3bdf4830eb8404b6b035e9ab19dbb096489430ed9e0abeb3adc6e50b074ba60c8d3ada3bab71
|
data/README.md
CHANGED
@@ -1,316 +1,84 @@
|
|
1
|
-
#
|
1
|
+
# notifications-rails
|
2
2
|
|
3
|
-
|
3
|
+
notifications-rails is the most powerful notification library for Rails. It offers not only simple APIs to create and render notifications but also supports user-integration and cross-platform delivery of notifications.
|
4
4
|
|
5
|
-
|
5
|
+
## Philosophy
|
6
6
|
|
7
|
-
|
7
|
+
notifications-rails has been built with modularity in mind. It currently consists of four components each of which bringing one essential functionality to the integration of notifications in your Rails app.
|
8
8
|
|
9
|
-
|
9
|
+
**[notification-handler](notification-handler):** Create and modify your notifications through a simple API.
|
10
10
|
|
11
|
-
|
12
|
-
* [Usage](#usage)
|
13
|
-
* [Categories](#categories)
|
14
|
-
* [Settings](#settings)
|
15
|
-
* [Category-specific settings](#category-specific-settings)
|
16
|
-
* [Pusher-specific settings](#pusher-specific-settings)
|
17
|
-
* [Updating settings](#updating-settings)
|
18
|
-
* [Subscriptions](#subscriptions)
|
19
|
-
* [Status](#status)
|
20
|
-
* [Configuration](#configuration)
|
21
|
-
* [Status](#status)
|
22
|
-
* [To Do](#to-do)
|
23
|
-
* [Contributing](#contributing)
|
24
|
-
* [Semantic versioning](#semantic-versioning)
|
11
|
+
**[notification-renderer](notification-renderer):** Render your notifications in various contexts.
|
25
12
|
|
26
|
-
|
13
|
+
**[notification-pusher](notification-pusher):** Deliver your notifications to various services, including [Email](notification-pusher/notification-pusher-actionmailer) and [OneSignal](notification-pusher/notification-pusher-onesignal).
|
27
14
|
|
28
|
-
|
29
|
-
|
30
|
-
NotificationSettings works with Rails 5 onwards. You can add it to your `Gemfile` with:
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
gem 'notification-settings'
|
34
|
-
```
|
35
|
-
|
36
|
-
And then execute:
|
37
|
-
|
38
|
-
$ bundle
|
39
|
-
|
40
|
-
Or install it yourself as:
|
41
|
-
|
42
|
-
$ gem install notification-settings
|
43
|
-
|
44
|
-
Now run the generator:
|
45
|
-
|
46
|
-
$ rails g notification_handler:install
|
47
|
-
$ rails g notification_settings:install
|
48
|
-
|
49
|
-
To wrap things up, migrate the changes to your database:
|
50
|
-
|
51
|
-
$ rails db:migrate
|
52
|
-
|
53
|
-
---
|
54
|
-
|
55
|
-
## Usage
|
56
|
-
|
57
|
-
First, you have to add some attributes to every model that acts as a `notification_target`:
|
58
|
-
|
59
|
-
```ruby
|
60
|
-
class User
|
61
|
-
# ...
|
62
|
-
|
63
|
-
notification_target
|
64
|
-
end
|
65
|
-
```
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
# A Hashie::Mash object that stores all the settings of a notification target.
|
69
|
-
add_column :users, :settings, :text
|
70
|
-
|
71
|
-
# A string that describes a notification-relevant state of a notification target.
|
72
|
-
add_column :users, :status, :string
|
73
|
-
```
|
74
|
-
|
75
|
-
### Categories
|
76
|
-
|
77
|
-
NotificationSettings uses categories to allow your notification targets to define specific preferences. This is how you are able to specify the `category` of a `Notification` record:
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
notification = Notification.create(target: User.first, object: Recipe.first, category: :notification)
|
81
|
-
```
|
82
|
-
|
83
|
-
**Note:** The `category` attribute of any new `Notification` record will default to the [`default_category` configuration](#configuration).
|
84
|
-
|
85
|
-
You can also scope records by their category:
|
86
|
-
|
87
|
-
```ruby
|
88
|
-
# Return records with `'notification'` as category
|
89
|
-
Notification.notification_category
|
90
|
-
|
91
|
-
# Return records with `'follow'` as category
|
92
|
-
Notification.follow_category
|
93
|
-
```
|
94
|
-
|
95
|
-
### Settings
|
96
|
-
|
97
|
-
You can completely disable notifications for a given notification target:
|
98
|
-
|
99
|
-
```ruby
|
100
|
-
settings = User.first.settings
|
101
|
-
|
102
|
-
settings.enabled = false
|
103
|
-
```
|
104
|
-
|
105
|
-
This will prevent you from creating any new notifications with this user as target.
|
106
|
-
|
107
|
-
The default is `true` (enabled) for this setting and the other settings.
|
108
|
-
|
109
|
-
#### Category-specific settings
|
110
|
-
|
111
|
-
A user can also have category-specific settings:
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
settings.categories!.send("#{category}!").enabled = false
|
115
|
-
```
|
116
|
-
|
117
|
-
#### Delivery-method-specific settings
|
118
|
-
|
119
|
-
He can have global or category-specific delivery method settings:
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
settings.delivery_methods!.enabled = false # Prevent delivering via *any* delivery method
|
123
|
-
settings.delivery_methods!.email!.enabled = false # Prevent delivering via the :email delivery method
|
124
|
-
settings.categories!.category!.delivery_methods!.email!.enabled = false # Prevent delivering via the :email delivery method for :category
|
125
|
-
```
|
126
|
-
|
127
|
-
#### Form objects
|
128
|
-
|
129
|
-
NotificationSettings comes with three form objects that simplify building forms for updating settings.
|
130
|
-
|
131
|
-
##### PreferencesForm
|
132
|
-
|
133
|
-
The preferences form has just one attribute: `enabled`. It can be used to update the global notification setting.
|
15
|
+
**[notification-settings](notification-settings):** Integrates with your authentication solution to craft a personalized user notification platform.
|
134
16
|
|
135
|
-
|
136
|
-
user = User.first
|
137
|
-
|
138
|
-
form = NotificationSettings::PreferencesForm.new(enabled: user.settings.enabled)
|
139
|
-
form.valid?
|
140
|
-
|
141
|
-
user.settings.enabled = form.enabled
|
142
|
-
```
|
143
|
-
|
144
|
-
##### CategoryPreferencesForm
|
145
|
-
|
146
|
-
The category preferences form has one attribute per category. It can be used to update category-specific settings.
|
147
|
-
|
148
|
-
```ruby
|
149
|
-
user = User.first
|
150
|
-
|
151
|
-
form = NotificationSettings::CategoryPreferencesForm.new(user.settings.categories_.to_h)
|
152
|
-
form.valid?
|
153
|
-
|
154
|
-
form.changed_attributes.each do |category|
|
155
|
-
user.settings.categories!.send(category, form.send(category))
|
156
|
-
end
|
157
|
-
```
|
158
|
-
|
159
|
-
##### DeliveryMethodPreferencesForm
|
160
|
-
|
161
|
-
The delivery method preferences form has one attribute per category and a general `enabled` attribute. It can be used to update delivery-method-specific settings or to disable all delivery methods.
|
162
|
-
|
163
|
-
```ruby
|
164
|
-
user = User.first
|
17
|
+
You may just use the components you actually need, or instead use this gem to bundle everything for a complete notification solution.
|
165
18
|
|
166
|
-
|
167
|
-
form.valid?
|
168
|
-
|
169
|
-
form.changed_attributes.each do |delivery_method|
|
170
|
-
user.settings.delivery_methods!.send(delivery_method, form.send(delivery_method))
|
171
|
-
end
|
172
|
-
```
|
173
|
-
|
174
|
-
### Subscriptions
|
175
|
-
|
176
|
-
Subscriptions are a way to better handle settings for notifications from different objects to one notification target.
|
177
|
-
|
178
|
-
This is how to subscribe/unsubscribe a target to an object:
|
179
|
-
|
180
|
-
```ruby
|
181
|
-
User.first.subscribe(Recipe.first)
|
182
|
-
User.first.unsubscribe(Recipe.first)
|
183
|
-
```
|
184
|
-
|
185
|
-
Now you can easily notify all subscribers from the subscribable object:
|
186
|
-
|
187
|
-
```ruby
|
188
|
-
Recipe.first.notify_subscribers(delivery_method: :ActionMailer)
|
189
|
-
```
|
190
|
-
|
191
|
-
Let's assume that we have a group which has multiple chats. When sending notifications to subscribers of a given chat, we only want them to get notified. But when sending notifications about the group, we want to have everyone notified, that is either subscribed to the group or subscribed to one of its chats. To do that you have to add the `private` method `notification_dependents` to your model (in this case `Group`) and return an array of ActiveRecord objects whose subscribers should receive notifications for objects of this class.
|
192
|
-
|
193
|
-
```ruby
|
194
|
-
has_many :chats
|
195
|
-
has_many :talks
|
196
|
-
|
197
|
-
private
|
198
|
-
|
199
|
-
def notification_dependents
|
200
|
-
self.chats
|
201
|
-
end
|
202
|
-
```
|
203
|
-
|
204
|
-
It is possible to override that behavior when notifying subscribers:
|
205
|
-
|
206
|
-
```ruby
|
207
|
-
# Disable notification dependents
|
208
|
-
Group.first.notify_subscribers(dependents: nil)
|
209
|
-
|
210
|
-
# Override notification dependents
|
211
|
-
Group.first.notify_subscribers(dependents: Group.first.chats + Group.first.talks)
|
212
|
-
```
|
213
|
-
|
214
|
-
You can customize settings & status for a single subscription just as you would for a notification target:
|
215
|
-
|
216
|
-
```ruby
|
217
|
-
user = User.first
|
218
|
-
subscription = user.notification_subscriptions.first
|
219
|
-
|
220
|
-
subscription.settings.enabled = false
|
221
|
-
subscription.status = 'online'
|
222
|
-
subscription.save
|
223
|
-
```
|
224
|
-
|
225
|
-
[Learn more](#settings)
|
19
|
+
## Installation
|
226
20
|
|
227
|
-
You can add
|
21
|
+
You can add notifications-rails to your `Gemfile` with:
|
228
22
|
|
229
23
|
```ruby
|
230
|
-
|
231
|
-
# List all subscriptions of a subscriber
|
232
|
-
subscriber.notification_subscribables
|
233
|
-
# List all subscribables of a specific type a subscriber subscribed to
|
234
|
-
has_many :subscribed_products, through: :notification_subscribables, source: :subscribable, source_type: 'Product'
|
235
|
-
|
236
|
-
# For subscribables:
|
237
|
-
# List all subscriptions of a subscriber
|
238
|
-
subscribable.notification_subscribers
|
239
|
-
# List all subscribers of a specific type that subscribed to a subscribable
|
240
|
-
has_many :subscribed_users, through: :notification_subscribers, source: :subscriber, source_type: 'User'
|
24
|
+
gem 'notifications-rails'
|
241
25
|
```
|
242
26
|
|
243
|
-
|
27
|
+
And then run:
|
244
28
|
|
245
|
-
|
29
|
+
$ bundle install
|
246
30
|
|
247
|
-
|
248
|
-
|
249
|
-
```ruby
|
250
|
-
User.first.update(status: 'do not disturb')
|
251
|
-
```
|
252
|
-
|
253
|
-
**Note:** You can set `status` to any string you like.
|
254
|
-
|
255
|
-
`status` has three possible values that are being used as defaults. Normally it defaults to `'online'`. If the `last_seen` [configuration](#configuration) option has been set, it can also default to `'idle'` or `'offline'` depending on the `idle_after` and `offline_after` [configuration](#configuration) options.
|
31
|
+
Or install it yourself as:
|
256
32
|
|
257
|
-
|
33
|
+
$ gem install notifications-rails
|
258
34
|
|
259
|
-
|
35
|
+
If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
|
260
36
|
|
261
37
|
```ruby
|
262
|
-
|
263
|
-
config.do_not_notify_statuses = ['do not notify']
|
264
|
-
config.do_not_deliver_statuses = ['do not disturb']
|
265
|
-
end
|
38
|
+
gem 'notifications-rails', github: 'jonhue/notifications-rails'
|
266
39
|
```
|
267
40
|
|
268
|
-
|
269
|
-
|
270
|
-
## Configuration
|
271
|
-
|
272
|
-
You can configure NotificationSettings by passing a block to `configure`. This can be done in `config/initializers/notification-settings.rb`:
|
273
|
-
|
274
|
-
```ruby
|
275
|
-
NotificationSettings.configure do |config|
|
276
|
-
config.categories = [:notification]
|
277
|
-
end
|
278
|
-
```
|
41
|
+
## Usage
|
279
42
|
|
280
|
-
|
43
|
+
Details on usage are provided in the [documentation](#philosophy) of the specific modules.
|
281
44
|
|
282
|
-
|
45
|
+
## Development
|
283
46
|
|
284
|
-
|
47
|
+
To start development you first have to fork this repository and locally clone your fork.
|
285
48
|
|
286
|
-
|
49
|
+
Install the projects dependencies by running:
|
287
50
|
|
288
|
-
|
51
|
+
$ bundle install
|
289
52
|
|
290
|
-
|
53
|
+
### Testing
|
291
54
|
|
292
|
-
|
55
|
+
Tests are written with RSpec. Integration tests are located in `/spec`, unit tests can be found in `<module>/spec`.
|
293
56
|
|
294
|
-
|
57
|
+
To run all tests:
|
295
58
|
|
296
|
-
|
59
|
+
$ ./rspec
|
297
60
|
|
298
|
-
|
61
|
+
To run RuboCop:
|
299
62
|
|
300
|
-
|
63
|
+
$ bundle exec rubocop
|
301
64
|
|
302
|
-
|
65
|
+
You can find all commands run by the CI workflow in `.github/workflows/ci.yml`.
|
303
66
|
|
304
|
-
|
67
|
+
## Contributing
|
305
68
|
|
306
|
-
|
69
|
+
We warmly welcome everyone who is intersted in contributing. Please reference our [contributing guidelines](CONTRIBUTING.md) and our [Code of Conduct](CODE_OF_CONDUCT.md).
|
307
70
|
|
308
|
-
##
|
71
|
+
## Releases
|
309
72
|
|
310
|
-
|
73
|
+
[Here](https://github.com/jonhue/notifications-rails/releases) you can find details on all past releases. Unreleased breaking changes that are on the current master can be found [here](CHANGELOG.md).
|
311
74
|
|
312
|
-
|
75
|
+
notifications-rails follows Semantic Versioning 2.0 as defined at http://semver.org. Reference our [security policy](SECURITY.md).
|
313
76
|
|
314
|
-
###
|
77
|
+
### Publishing
|
315
78
|
|
316
|
-
|
79
|
+
1. Review breaking changes and deprecations in `CHANGELOG.md`.
|
80
|
+
1. Change the gem version in `VERSION`.
|
81
|
+
1. Reset `CHANGELOG.md`.
|
82
|
+
1. Create a pull request to merge the changes into `master`.
|
83
|
+
1. After the pull request was merged, create a new release listing the breaking changes and commits on `master` since the last release.
|
84
|
+
1. The release workflow will publish the gems to RubyGems.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notification-settings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Hübotter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -56,30 +56,36 @@ dependencies:
|
|
56
56
|
name: hashie
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.6'
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '5.0'
|
62
65
|
type: :runtime
|
63
66
|
prerelease: false
|
64
67
|
version_requirements: !ruby/object:Gem::Requirement
|
65
68
|
requirements:
|
66
|
-
- - "
|
69
|
+
- - ">="
|
67
70
|
- !ruby/object:Gem::Version
|
68
71
|
version: '3.6'
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '5.0'
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: notification-handler
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
72
78
|
requirements:
|
73
79
|
- - '='
|
74
80
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.0.
|
81
|
+
version: 3.0.3
|
76
82
|
type: :runtime
|
77
83
|
prerelease: false
|
78
84
|
version_requirements: !ruby/object:Gem::Requirement
|
79
85
|
requirements:
|
80
86
|
- - '='
|
81
87
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.0.
|
88
|
+
version: 3.0.3
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
90
|
name: railties
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,30 +200,14 @@ dependencies:
|
|
194
200
|
version: '0'
|
195
201
|
description: Integrates with your authentication solution to craft a personalized
|
196
202
|
user notification platform.
|
197
|
-
email:
|
203
|
+
email: jonas.huebotter@gmail.com
|
198
204
|
executables: []
|
199
205
|
extensions: []
|
200
206
|
extra_rdoc_files: []
|
201
207
|
files:
|
202
208
|
- LICENSE
|
203
209
|
- README.md
|
204
|
-
-
|
205
|
-
- lib/generators/notification_settings/install_generator.rb
|
206
|
-
- lib/generators/templates/install/initializer.rb
|
207
|
-
- lib/generators/templates/install/notifications_migration.rb.erb
|
208
|
-
- lib/notification-settings.rb
|
209
|
-
- lib/notification_settings/category_preferences_form.rb
|
210
|
-
- lib/notification_settings/configuration.rb
|
211
|
-
- lib/notification_settings/delivery_method_preferences_form.rb
|
212
|
-
- lib/notification_settings/engine.rb
|
213
|
-
- lib/notification_settings/notification_lib.rb
|
214
|
-
- lib/notification_settings/notification_scopes.rb
|
215
|
-
- lib/notification_settings/preferences_form.rb
|
216
|
-
- lib/notification_settings/settings.rb
|
217
|
-
- lib/notification_settings/status.rb
|
218
|
-
- lib/notification_settings/subscribable.rb
|
219
|
-
- lib/notification_settings/subscriber.rb
|
220
|
-
- lib/notification_settings/target.rb
|
210
|
+
- lib/notifications-rails.rb
|
221
211
|
homepage: https://github.com/jonhue/notifications-rails/tree/master/notification-settings
|
222
212
|
licenses:
|
223
213
|
- MIT
|
@@ -238,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
228
|
- !ruby/object:Gem::Version
|
239
229
|
version: '0'
|
240
230
|
requirements: []
|
241
|
-
rubygems_version: 3.
|
231
|
+
rubygems_version: 3.1.4
|
242
232
|
signing_key:
|
243
233
|
specification_version: 4
|
244
234
|
summary: Integrates with your authentication solution to craft a personalized user
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NotificationSettings
|
4
|
-
class Subscription < ActiveRecord::Base
|
5
|
-
self.table_name = 'notification_settings_subscriptions'
|
6
|
-
|
7
|
-
include NotificationSettings::Settings
|
8
|
-
|
9
|
-
belongs_to :subscriber, polymorphic: true
|
10
|
-
belongs_to :subscribable, polymorphic: true
|
11
|
-
|
12
|
-
has_many :notifications, class_name: '::Notification'
|
13
|
-
end
|
14
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails/generators'
|
4
|
-
require 'rails/generators/migration'
|
5
|
-
|
6
|
-
module NotificationSettings
|
7
|
-
class InstallGenerator < Rails::Generators::Base
|
8
|
-
include Rails::Generators::Migration
|
9
|
-
|
10
|
-
source_root(File.join(File.dirname(__FILE__), '../templates/install'))
|
11
|
-
desc 'Install NotificationSettings'
|
12
|
-
|
13
|
-
def self.next_migration_number(dirname)
|
14
|
-
if ActiveRecord::Base.timestamped_migrations
|
15
|
-
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
16
|
-
else
|
17
|
-
format('%<migration_number>.3d',
|
18
|
-
migration_number: current_migration_number(dirname) + 1)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def create_initializer
|
23
|
-
template 'initializer.rb', 'config/initializers/notification_settings.rb'
|
24
|
-
end
|
25
|
-
|
26
|
-
def create_notifications_migration_file
|
27
|
-
migration_template(
|
28
|
-
'notifications_migration.rb.erb',
|
29
|
-
'db/migrate/notification_settings_migration.rb',
|
30
|
-
migration_version: migration_version
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def migration_version
|
37
|
-
return unless Rails.version >= '5.0.0'
|
38
|
-
|
39
|
-
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
NotificationSettings.configure do |config|
|
4
|
-
# An array of all notification categories. Takes an array of symbols.
|
5
|
-
# config.categories = [:notification]
|
6
|
-
|
7
|
-
# Choose your default notification category. Takes a symbol.
|
8
|
-
# config.default_category = :notification
|
9
|
-
|
10
|
-
### STATUS ###
|
11
|
-
|
12
|
-
# Time duration without activity after which the status defaults to `'idle'`.
|
13
|
-
# Takes a time.
|
14
|
-
# config.idle_after = 10.minutes
|
15
|
-
|
16
|
-
# Time duration without activity after which the status defaults to
|
17
|
-
# `'offline'`. Takes a time.
|
18
|
-
# config.offline_after = 3.hours
|
19
|
-
|
20
|
-
# Stringified datetime attribute name of `object` that defines the time of the
|
21
|
-
# last activity. Takes a symbol.
|
22
|
-
# config.last_seen = :last_seen
|
23
|
-
|
24
|
-
# Array of all possible statuses. Takes an array of strings.
|
25
|
-
# config.statuses = [
|
26
|
-
# 'online',
|
27
|
-
# 'idle',
|
28
|
-
# 'offline',
|
29
|
-
# 'do not notify',
|
30
|
-
# 'do not disturb'
|
31
|
-
# ]
|
32
|
-
|
33
|
-
# Array of possible statuses that will prevent creating notifications for a
|
34
|
-
# target. Takes an array of strings.
|
35
|
-
# config.do_not_notify_statuses = ['do not notify']
|
36
|
-
|
37
|
-
# Array of possible statuses that will prevent pushing notifications of a
|
38
|
-
# target. Takes an array of strings.
|
39
|
-
# config.do_not_deliver_statuses = ['do not disturb']
|
40
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class NotificationSettingsMigration < ActiveRecord::Migration<%= migration_version %>
|
4
|
-
def change
|
5
|
-
add_column :notifications, :subscription_id, :bigint, index: true
|
6
|
-
add_column :notifications, :category, :string, index: true
|
7
|
-
|
8
|
-
create_table :notification_settings_subscriptions do |t|
|
9
|
-
t.references :subscriber,
|
10
|
-
polymorphic: true,
|
11
|
-
index: {
|
12
|
-
name: 'idx_subscriptions_subscriber_type_subscriber_id'
|
13
|
-
}
|
14
|
-
t.references :subscribable,
|
15
|
-
polymorphic: true,
|
16
|
-
index: {
|
17
|
-
name: 'idx_subscriptions_subscribable_type_subscribable_id'
|
18
|
-
}
|
19
|
-
|
20
|
-
t.text :settings
|
21
|
-
|
22
|
-
t.timestamps
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NotificationSettings
|
4
|
-
require_relative 'notification_settings/configuration'
|
5
|
-
|
6
|
-
require_relative 'notification_settings/engine'
|
7
|
-
|
8
|
-
autoload :Target, 'notification_settings/target'
|
9
|
-
autoload :Subscriber, 'notification_settings/subscriber'
|
10
|
-
autoload :Subscribable, 'notification_settings/subscribable'
|
11
|
-
autoload :Settings, 'notification_settings/settings'
|
12
|
-
autoload :Status, 'notification_settings/status'
|
13
|
-
autoload :NotificationLib, 'notification_settings/notification_lib'
|
14
|
-
autoload :NotificationScopes, 'notification_settings/notification_scopes'
|
15
|
-
autoload :CategoryPreferencesForm,
|
16
|
-
'notification_settings/category_preferences_form'
|
17
|
-
autoload :DeliveryMethodPreferencesForm,
|
18
|
-
'notification_settings/delivery_method_preferences_form'
|
19
|
-
autoload :PreferencesForm, 'notification_settings/preferences_form'
|
20
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_model'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
class CategoryPreferencesForm
|
7
|
-
include ActiveModel::Model
|
8
|
-
|
9
|
-
NotificationSettings.configuration.categories.each do |category|
|
10
|
-
attribute category, :boolean, default: true
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NotificationSettings
|
4
|
-
class << self
|
5
|
-
attr_writer :configuration
|
6
|
-
|
7
|
-
def configuration
|
8
|
-
@configuration ||= Configuration.new
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.configure
|
13
|
-
yield configuration
|
14
|
-
end
|
15
|
-
|
16
|
-
class Configuration
|
17
|
-
attr_accessor :categories
|
18
|
-
attr_accessor :default_category
|
19
|
-
attr_accessor :last_seen
|
20
|
-
attr_accessor :idle_after
|
21
|
-
attr_accessor :offline_after
|
22
|
-
attr_accessor :statuses
|
23
|
-
attr_accessor :do_not_notify_statuses
|
24
|
-
attr_accessor :do_not_deliver_statuses
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
@categories = [:notification]
|
28
|
-
@default_category = :notification
|
29
|
-
@last_seen = :last_seen
|
30
|
-
@idle_after = 10.minutes
|
31
|
-
@offline_after = 3.hours
|
32
|
-
@statuses = ['online', 'idle', 'offline', 'do not notify',
|
33
|
-
'do not disturb']
|
34
|
-
@do_not_notify_statuses = ['do not notify']
|
35
|
-
@do_not_deliver_statuses = ['do not disturb']
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_model'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
class DeliveryMethodPreferencesForm
|
7
|
-
include ActiveModel::Model
|
8
|
-
|
9
|
-
attribute :enabled, :boolean, default: true
|
10
|
-
NotificationPusher.configuration.delivery_methods
|
11
|
-
.each do |delivery_method, _|
|
12
|
-
attribute delivery_method, :boolean, default: true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'notification-handler'
|
4
|
-
require 'active_support'
|
5
|
-
|
6
|
-
module NotificationSettings
|
7
|
-
module NotificationLib
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
included do
|
11
|
-
before_create :validate_create
|
12
|
-
|
13
|
-
validates :category, inclusion: {
|
14
|
-
in: NotificationSettings.configuration.categories + [nil]
|
15
|
-
}
|
16
|
-
|
17
|
-
belongs_to :subscription,
|
18
|
-
class_name: 'NotificationSettings::Subscription',
|
19
|
-
optional: true
|
20
|
-
|
21
|
-
include NotificationSettings::NotificationLib::InstanceMethods
|
22
|
-
end
|
23
|
-
|
24
|
-
# rubocop:disable Metrics/ModuleLength
|
25
|
-
module InstanceMethods
|
26
|
-
def category
|
27
|
-
self[:category] || NotificationSettings.configuration.default_category
|
28
|
-
end
|
29
|
-
|
30
|
-
def deliver(delivery_methods, delivery_options = {})
|
31
|
-
return false unless delivery_allowed?(delivery_methods)
|
32
|
-
|
33
|
-
super
|
34
|
-
end
|
35
|
-
|
36
|
-
def creation_allowed?
|
37
|
-
status_allows_creation? &&
|
38
|
-
settings_allow_creation? &&
|
39
|
-
category_settings_allow_creation?
|
40
|
-
end
|
41
|
-
|
42
|
-
# delivery_methods may be an array or a single value
|
43
|
-
def delivery_allowed?(delivery_methods)
|
44
|
-
creation_allowed? &&
|
45
|
-
status_allows_delivery? &&
|
46
|
-
delivery_methods_allowed?(Array(delivery_methods))
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def validate_create
|
52
|
-
throw(:abort) unless creation_allowed?
|
53
|
-
end
|
54
|
-
|
55
|
-
def status_allows_creation?
|
56
|
-
!do_not_notify_statuses.include?(target.status)
|
57
|
-
end
|
58
|
-
|
59
|
-
def settings_allow_creation?
|
60
|
-
target.settings.fetch(:enabled, true) &&
|
61
|
-
(subscription.nil? || subscription.settings.fetch(:enabled, true))
|
62
|
-
end
|
63
|
-
|
64
|
-
def category_settings_allow_creation?
|
65
|
-
category_settings(target, category).fetch(:enabled, true) &&
|
66
|
-
(subscription.nil? ||
|
67
|
-
category_settings(subscription, category).fetch(:enabled, true))
|
68
|
-
end
|
69
|
-
|
70
|
-
def delivery_methods_allowed?(delivery_methods)
|
71
|
-
delivery_methods.any? do |delivery_method|
|
72
|
-
delivery_method_allowed?(delivery_method)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def delivery_method_allowed?(delivery_method)
|
77
|
-
settings_allow_delivery?(delivery_method) &&
|
78
|
-
category_settings_allow_delivery?(delivery_method)
|
79
|
-
end
|
80
|
-
|
81
|
-
def status_allows_delivery?
|
82
|
-
!do_not_deliver_statuses.include?(target.status)
|
83
|
-
end
|
84
|
-
|
85
|
-
def settings_allow_delivery?(delivery_method)
|
86
|
-
if local_delivery_method_setting?(delivery_method)
|
87
|
-
local_settings_allow_delivery?(delivery_method)
|
88
|
-
else
|
89
|
-
global_settings_allow_delivery?
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def local_delivery_method_setting?(delivery_method)
|
94
|
-
!local_delivery_method_setting(delivery_method).nil?
|
95
|
-
end
|
96
|
-
|
97
|
-
def local_settings_allow_delivery?(delivery_method)
|
98
|
-
local_delivery_method_setting(delivery_method, true)
|
99
|
-
end
|
100
|
-
|
101
|
-
def local_delivery_method_setting(delivery_method, default = nil)
|
102
|
-
delivery_method_setting(target, delivery_method, default) &&
|
103
|
-
(subscription.nil? ||
|
104
|
-
delivery_method_setting(subscription, delivery_method, default))
|
105
|
-
end
|
106
|
-
|
107
|
-
def global_settings_allow_delivery?
|
108
|
-
delivery_method_setting(target, :enabled, true) &&
|
109
|
-
(subscription.nil? ||
|
110
|
-
delivery_method_setting(subscription, :enabled, true))
|
111
|
-
end
|
112
|
-
|
113
|
-
def category_settings_allow_delivery?(delivery_method)
|
114
|
-
if local_delivery_method_category_setting?(delivery_method)
|
115
|
-
local_category_settings_allow_delivery?(delivery_method)
|
116
|
-
else
|
117
|
-
global_category_settings_allow_delivery?
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def local_delivery_method_category_setting?(delivery_method)
|
122
|
-
!local_delivery_method_category_setting(delivery_method).nil?
|
123
|
-
end
|
124
|
-
|
125
|
-
def local_category_settings_allow_delivery?(delivery_method)
|
126
|
-
local_delivery_method_category_setting(delivery_method, true)
|
127
|
-
end
|
128
|
-
|
129
|
-
def local_delivery_method_category_setting(delivery_method, default = nil)
|
130
|
-
category_delivery_method_setting(target, category, delivery_method,
|
131
|
-
default) &&
|
132
|
-
(subscription.nil? ||
|
133
|
-
category_delivery_method_setting(subscription, category,
|
134
|
-
delivery_method, default))
|
135
|
-
end
|
136
|
-
|
137
|
-
def global_category_settings_allow_delivery?
|
138
|
-
category_delivery_method_setting(target, category, :enabled, true) &&
|
139
|
-
(subscription.nil? ||
|
140
|
-
category_delivery_method_setting(subscription, category, :enabled,
|
141
|
-
true))
|
142
|
-
end
|
143
|
-
|
144
|
-
def delivery_method_setting(object, delivery_method, default)
|
145
|
-
object.settings.delivery_methods_.fetch(delivery_method.to_s, default)
|
146
|
-
end
|
147
|
-
|
148
|
-
def category_settings(object, category)
|
149
|
-
object.settings.categories_.send("#{category}_")
|
150
|
-
end
|
151
|
-
|
152
|
-
def category_delivery_method_setting(object, category, delivery_method,
|
153
|
-
default)
|
154
|
-
category_settings(object, category).delivery_methods_
|
155
|
-
.fetch(delivery_method.to_s, default)
|
156
|
-
end
|
157
|
-
|
158
|
-
def do_not_notify_statuses
|
159
|
-
NotificationSettings.configuration.do_not_notify_statuses
|
160
|
-
end
|
161
|
-
|
162
|
-
def do_not_deliver_statuses
|
163
|
-
NotificationSettings.configuration.do_not_deliver_statuses
|
164
|
-
end
|
165
|
-
end
|
166
|
-
# rubocop:enable Metrics/ModuleLength
|
167
|
-
end
|
168
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'notification-handler'
|
4
|
-
require 'active_support'
|
5
|
-
|
6
|
-
module NotificationSettings
|
7
|
-
module NotificationScopes
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
def method_missing(method, *args)
|
12
|
-
if method.to_s[/(.+)_category/]
|
13
|
-
where(category: $1.singularize.classify)
|
14
|
-
else
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def respond_to_missing?(method, include_private = false)
|
20
|
-
super || method.to_s[/(.+)_category/]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
require 'hashie'
|
5
|
-
|
6
|
-
module NotificationSettings
|
7
|
-
module Settings
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
included do
|
11
|
-
before_validation :build_settings
|
12
|
-
|
13
|
-
serialize :settings, Hashie::Mash
|
14
|
-
|
15
|
-
include NotificationSettings::Settings::InstanceMethods
|
16
|
-
end
|
17
|
-
|
18
|
-
module InstanceMethods
|
19
|
-
private
|
20
|
-
|
21
|
-
def build_settings
|
22
|
-
return if settings.present? && settings.is_a?(Hashie::Mash)
|
23
|
-
|
24
|
-
self.settings = Hashie::Mash.new
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
module Status
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
validates :status,
|
11
|
-
inclusion: { in: NotificationSettings.configuration.statuses }
|
12
|
-
|
13
|
-
include NotificationSettings::Status::InstanceMethods
|
14
|
-
end
|
15
|
-
|
16
|
-
module InstanceMethods
|
17
|
-
def status
|
18
|
-
self[:status] || default_status
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def default_status
|
24
|
-
if idle? && !offline?
|
25
|
-
'idle'
|
26
|
-
elsif offline?
|
27
|
-
'offline'
|
28
|
-
else
|
29
|
-
'online'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def idle?
|
34
|
-
return unless time_since_last_seen_round
|
35
|
-
|
36
|
-
time_since_last_seen_round >= idle_after
|
37
|
-
end
|
38
|
-
|
39
|
-
def offline?
|
40
|
-
return unless time_since_last_seen_round
|
41
|
-
|
42
|
-
time_since_last_seen_round >= offline_after
|
43
|
-
end
|
44
|
-
|
45
|
-
def time_since_last_seen_round
|
46
|
-
time_since_last_seen&.round
|
47
|
-
end
|
48
|
-
|
49
|
-
def time_since_last_seen
|
50
|
-
return unless respond_to?(NotificationSettings.configuration.last_seen)
|
51
|
-
|
52
|
-
Time.now - send(NotificationSettings.configuration.last_seen)
|
53
|
-
end
|
54
|
-
|
55
|
-
def idle_after
|
56
|
-
NotificationSettings.configuration.idle_after
|
57
|
-
end
|
58
|
-
|
59
|
-
def offline_after
|
60
|
-
NotificationSettings.configuration.offline_after
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
module Subscribable
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
has_many :notification_subscribers,
|
11
|
-
as: :subscribable,
|
12
|
-
class_name: 'NotificationSettings::Subscription',
|
13
|
-
dependent: :destroy
|
14
|
-
|
15
|
-
include NotificationSettings::Subscribable::InstanceMethods
|
16
|
-
end
|
17
|
-
|
18
|
-
module InstanceMethods
|
19
|
-
def notify_subscribers(options = {})
|
20
|
-
options[:object] = self
|
21
|
-
subscriptions = notify_dependents(options.delete(:dependents))
|
22
|
-
notification_subscribers&.each do |subscription|
|
23
|
-
subscriptions << subscription
|
24
|
-
end
|
25
|
-
subscriptions.to_a.uniq&.each do |subscription|
|
26
|
-
subscription.subscriber.notify(options)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def notify_dependents(dependents)
|
31
|
-
subscriptions = []
|
32
|
-
dependents ||= notification_dependents
|
33
|
-
dependents&.each do |dependent|
|
34
|
-
dependent.notification_subscribers&.each do |subscription|
|
35
|
-
subscriptions << subscription
|
36
|
-
end
|
37
|
-
end
|
38
|
-
subscriptions
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def notification_dependents
|
44
|
-
[]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
module Subscriber
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
has_many :notification_subscribables,
|
11
|
-
as: :subscriber,
|
12
|
-
class_name: 'NotificationSettings::Subscription',
|
13
|
-
dependent: :destroy
|
14
|
-
|
15
|
-
include NotificationSettings::Subscriber::InstanceMethods
|
16
|
-
end
|
17
|
-
|
18
|
-
module InstanceMethods
|
19
|
-
def subscribe(subscribable, options = {})
|
20
|
-
notification_subscribables.create(
|
21
|
-
options.merge(subscribable: subscribable)
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
def unsubscribe(subscribable)
|
26
|
-
subscription = notification_subscribables.find_by(
|
27
|
-
subscribable_id: subscribable.id,
|
28
|
-
subscribable_type: subscribable.class.name
|
29
|
-
)
|
30
|
-
subscription&.destroy
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
|
5
|
-
module NotificationSettings
|
6
|
-
module Target
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
include NotificationSettings::Settings
|
11
|
-
include NotificationSettings::Status
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|