notifly 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +37 -12
- data/app/assets/javascripts/notifly.js +3 -0
- data/app/assets/javascripts/notifly_dropdown.js +1 -1
- data/app/controllers/notifly/notifications_controller.rb +2 -1
- data/app/models/notifly/notification.rb +5 -1
- data/app/views/notifly/layouts/_empty.html.erb +3 -0
- data/app/views/notifly/layouts/_notifly.html.erb +1 -3
- data/app/views/notifly/notifications/index.js.erb +8 -3
- data/app/views/notifly/notifications/seen.js.erb +2 -1
- data/vendor/assets/javascripts/tinycon.js +279 -0
- data/vendor/assets/javascripts/twitter/{bootstrap.js → bootstrap/dropdown.js} +0 -0
- metadata +5 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 079f1db58c119ea5ec0aa5b487c0aa45f6b24d61
|
4
|
+
data.tar.gz: b1a215bc6e1d3caccafedd29e86c2ee5e90467df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3aa005a8e84945e9228599e91a3b791a8ff8a9923af1cc5cff9e043e5bcd0e8a47ad9c17586ba5002183e2a28032be4b32d83f4ed93cc7ad48044f96ab3a2991
|
7
|
+
data.tar.gz: a31efb84696178c8126b037f221a4e0cab4e5f4e3f4779eea11071fbcc5422c04be383b9b8820769726dc9ff8e71a83a3d695828e315ede74707f816d1fda7bb
|
data/README.md
CHANGED
@@ -161,7 +161,8 @@ end
|
|
161
161
|
| `template: :foo` | send email using `foo` mail template and a notification using notifly template |
|
162
162
|
|
163
163
|
Notiflies with `mail: { only: true }` will persist notifications, but them won't
|
164
|
-
be in receivers notifications views. If you use
|
164
|
+
be in receivers notifications views. If you use
|
165
|
+
[delayed_job](https://github.com/collectiveidea/delayed_job)
|
165
166
|
or [sidekiq](https://github.com/mperham/sidekiq) mails will be sent async.
|
166
167
|
|
167
168
|
### Notifications access
|
@@ -181,15 +182,33 @@ You can access the notifications using the following methods:
|
|
181
182
|
|
182
183
|
## Front-end
|
183
184
|
|
184
|
-
First, you need to have a `current_user
|
185
|
-
[Devise](https://github.com/plataformatec/devise) it is already there.
|
185
|
+
First, you need to have a `current_user`, if you use
|
186
|
+
[Devise](https://github.com/plataformatec/devise) maybe it is already there. If you
|
187
|
+
haven't a `current_user`, just define a method in `ApplicationController` and
|
188
|
+
add it to the helpers methods. Your controller should look like this:
|
186
189
|
|
187
|
-
|
190
|
+
```ruby
|
191
|
+
class ApplicationController < ActionController::Base
|
192
|
+
def current_user
|
193
|
+
current_talker
|
194
|
+
end
|
195
|
+
|
196
|
+
ActiveSupport.on_load(:action_controller) do
|
197
|
+
helper_method :current_user
|
198
|
+
end
|
199
|
+
end
|
200
|
+
``
|
201
|
+
|
202
|
+
After that you need our assets, add them to your `application.js` and `application.css`.
|
188
203
|
|
189
204
|
```javascript
|
190
205
|
//= require notifly
|
191
206
|
```
|
192
207
|
|
208
|
+
The `notifly` contain the code to do all requests and notifications injection, if
|
209
|
+
you do not use [Twitter bootstrap](http://getbootstrap.com/) you will need
|
210
|
+
to add `//= notifly_dropdown` to the code above.
|
211
|
+
|
193
212
|
```css
|
194
213
|
/*
|
195
214
|
*= require notifly
|
@@ -206,11 +225,7 @@ This will inject our views and it will be like that
|
|
206
225
|
|
207
226
|

|
208
227
|
|
209
|
-
|
210
|
-
template but if you want to change or create new ones run the generate below
|
211
|
-
with the option that you want or create them in `app/views/notifly/templates/`.
|
212
|
-
Remember that notifications templates should be in `notifications` folder and
|
213
|
-
mails templates in `mails` folder.
|
228
|
+
If you want to change something just use the code below
|
214
229
|
|
215
230
|
```shell
|
216
231
|
$ rails generate notifly:views
|
@@ -222,6 +237,12 @@ mails templates in `mails` folder.
|
|
222
237
|
| `--layout` | generates layout files |
|
223
238
|
| `--mail` | generates mail templates files |
|
224
239
|
|
240
|
+
Notifications and Mails are rendered with their templates. They use a simple default
|
241
|
+
template but if you want to change or create new ones run the generate above
|
242
|
+
with the option that you want or create them in `app/views/notifly/templates/`.
|
243
|
+
Remember that notifications templates should be in `notifications` folder and
|
244
|
+
mails templates in `mails` folder.
|
245
|
+
|
225
246
|
If you already have a layout and just want add our features to it, take a look
|
226
247
|
at [Adapting your layout](#adapting).
|
227
248
|
|
@@ -235,11 +256,11 @@ you can change it in `config/locales/notifly.en.yaml` or create your own.
|
|
235
256
|
All partials that we insert in your layout are in the gem or if you generated them,
|
236
257
|
they will be in `app/views/notifly/layouts/`
|
237
258
|
|
238
|
-
|
259
|
+
Below are the elements that will loading the Notifly in your layout
|
239
260
|
|
240
261
|
- **Counter**: this element will show how many notifications are not seen. It
|
241
|
-
should have the id `#notifly-counter`, and
|
242
|
-
|
262
|
+
should have the id `#notifly-counter`, and it will be replaced by the
|
263
|
+
`_counter.html.erb`
|
243
264
|
- **Notifications icon**: this element is the trigger to load the notifications
|
244
265
|
and you should have an icon to show when the user "have notifications" and
|
245
266
|
"do not have notifications" this element should have the id `#notifly-icon`. The
|
@@ -261,6 +282,10 @@ Above are the elements that will loading the Notifly in your layout
|
|
261
282
|
- **Toggle read**: this link will be rendered by `_actions.html.erb' in
|
262
283
|
`_notification.html.erb`
|
263
284
|
|
285
|
+
Those elements should be inside an element with id `#notifly` and the dropdown
|
286
|
+
trigger should have the id `#notifly-trigger`. For more info and examples, just
|
287
|
+
take a look at `_notifly.html.erb`
|
288
|
+
|
264
289
|
# Contributing
|
265
290
|
|
266
291
|
Consider to use [zenhub](https://www.zenhub.io/), with it will know what issues
|
@@ -1,5 +1,6 @@
|
|
1
1
|
//= require 'jquery'
|
2
2
|
//= require 'jquery_ujs'
|
3
|
+
//= require 'tinycon'
|
3
4
|
//= require 'notifly/get_notifications'
|
4
5
|
//= require 'notifly/seen_notifications'
|
5
6
|
//= require 'notifly/read_notifications'
|
@@ -9,4 +10,6 @@ $(document).ready(function() {
|
|
9
10
|
$(document).on('click', '#notifly-notifications-panel.dropdown-menu', function (e) {
|
10
11
|
$('#notifly').hasClass('keep_open') && e.stopPropagation();
|
11
12
|
});
|
13
|
+
|
14
|
+
Tinycon.setBubble(0);
|
12
15
|
});
|
@@ -1 +1 @@
|
|
1
|
-
//= require 'twitter/bootstrap'
|
1
|
+
//= require 'twitter/bootstrap/dropdown'
|
@@ -4,7 +4,7 @@ module Notifly
|
|
4
4
|
belongs_to :sender, polymorphic: true
|
5
5
|
belongs_to :receiver, polymorphic: true
|
6
6
|
|
7
|
-
before_validation :convert_data, :set_template
|
7
|
+
before_validation :convert_data, :set_template, :set_mail
|
8
8
|
|
9
9
|
scope :all_from, -> (receiver) { where(receiver: receiver) }
|
10
10
|
scope :unseen, -> { where(seen: false) }
|
@@ -44,5 +44,9 @@ module Notifly
|
|
44
44
|
def set_template
|
45
45
|
self.template ||= :default
|
46
46
|
end
|
47
|
+
|
48
|
+
def set_mail
|
49
|
+
self.mail ||= :never
|
50
|
+
end
|
47
51
|
end
|
48
52
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
<!-- This partial requires the locals: receiver -->
|
2
|
-
|
3
1
|
<div id="notifly" class="dropdown keep_open">
|
4
2
|
|
5
3
|
<a id="notifly-trigger" href="#" class="dropdown-toggle" data-toggle="dropdown">
|
@@ -18,7 +16,7 @@
|
|
18
16
|
</div>
|
19
17
|
|
20
18
|
<div id="notifly-notifications-content">
|
21
|
-
<div class="loading">Loading notifications...</div>
|
19
|
+
<div class="notifly-loading">Loading notifications...</div>
|
22
20
|
</div>
|
23
21
|
|
24
22
|
<div id="notifly-notifications-footer">
|
@@ -3,8 +3,10 @@
|
|
3
3
|
<% last_notification = @notifications.last.try(:id) %>
|
4
4
|
<% first_notification = @notifications.first.try(:id) %>
|
5
5
|
|
6
|
+
$('#notifly-notifications-content .notifly-loading').remove();
|
7
|
+
$('#notifly-notifications-content .notifly-empty').remove();
|
8
|
+
|
6
9
|
<% if @notifications.any? %>
|
7
|
-
$('#notifly-notifications-content .loading').remove();
|
8
10
|
|
9
11
|
<% if @scope_param == 'older' %>
|
10
12
|
$('#notifly-notifications-content').append("<%= j rendered_notifications %>");
|
@@ -20,14 +22,17 @@
|
|
20
22
|
<% end %>
|
21
23
|
|
22
24
|
<% else %>
|
23
|
-
if (notiflyLastNotification == undefined)
|
25
|
+
if (notiflyLastNotification == undefined) {
|
24
26
|
$('#notifly-more-notifications-link').remove();
|
27
|
+
$('#notifly-notifications-content').append("<%= j(render 'notifly/layouts/empty')%>")
|
28
|
+
}
|
25
29
|
|
26
30
|
<% end %>
|
27
31
|
|
28
|
-
<% if @scope_param == 'older' and
|
32
|
+
<% if @scope_param == 'older' and @user.notifly_notifications.older(than: last_notification).blank? %>
|
29
33
|
$('#notifly-more-notifications-link').remove();
|
30
34
|
<% end %>
|
31
35
|
|
32
36
|
$('#notifly-counter').replaceWith("<%= j(render 'notifly/layouts/counter', counter: @counter)%>");
|
33
37
|
$('#notifly-icon').replaceWith("<%= j notifly_icon(@counter > 0) %>")
|
38
|
+
Tinycon.setBubble(<%= @counter %>);
|
@@ -1,2 +1,3 @@
|
|
1
1
|
$('#notifly-counter').replaceWith("<%= j(render 'notifly/layouts/counter', counter: @counter)%>");
|
2
|
-
$('#notifly-icon').replaceWith("<%= j notifly_icon(@counter > 0) %>")
|
2
|
+
$('#notifly-icon').replaceWith("<%= j notifly_icon(@counter > 0) %>");
|
3
|
+
Tinycon.setBubble(<%= @counter %>);
|
@@ -0,0 +1,279 @@
|
|
1
|
+
/*!
|
2
|
+
* Tinycon - A small library for manipulating the Favicon
|
3
|
+
* Tom Moor, http://tommoor.com
|
4
|
+
* Copyright (c) 2012 Tom Moor
|
5
|
+
* @license MIT Licensed
|
6
|
+
* @version 0.6.3
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function(){
|
10
|
+
|
11
|
+
var Tinycon = {};
|
12
|
+
var currentFavicon = null;
|
13
|
+
var originalFavicon = null;
|
14
|
+
var faviconImage = null;
|
15
|
+
var canvas = null;
|
16
|
+
var options = {};
|
17
|
+
var r = window.devicePixelRatio || 1;
|
18
|
+
var size = 16 * r;
|
19
|
+
var defaults = {
|
20
|
+
width: 7,
|
21
|
+
height: 9,
|
22
|
+
font: 10 * r + 'px arial',
|
23
|
+
colour: '#ffffff',
|
24
|
+
background: '#F03D25',
|
25
|
+
fallback: true,
|
26
|
+
crossOrigin: true,
|
27
|
+
abbreviate: true
|
28
|
+
};
|
29
|
+
|
30
|
+
var ua = (function () {
|
31
|
+
var agent = navigator.userAgent.toLowerCase();
|
32
|
+
// New function has access to 'agent' via closure
|
33
|
+
return function (browser) {
|
34
|
+
return agent.indexOf(browser) !== -1;
|
35
|
+
};
|
36
|
+
}());
|
37
|
+
|
38
|
+
var browser = {
|
39
|
+
ie: ua('msie'),
|
40
|
+
chrome: ua('chrome'),
|
41
|
+
webkit: ua('chrome') || ua('safari'),
|
42
|
+
safari: ua('safari') && !ua('chrome'),
|
43
|
+
mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')
|
44
|
+
};
|
45
|
+
|
46
|
+
// private methods
|
47
|
+
var getFaviconTag = function(){
|
48
|
+
|
49
|
+
var links = document.getElementsByTagName('link');
|
50
|
+
|
51
|
+
for(var i=0, len=links.length; i < len; i++) {
|
52
|
+
if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
53
|
+
return links[i];
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
return false;
|
58
|
+
};
|
59
|
+
|
60
|
+
var removeFaviconTag = function(){
|
61
|
+
|
62
|
+
var links = document.getElementsByTagName('link');
|
63
|
+
var head = document.getElementsByTagName('head')[0];
|
64
|
+
|
65
|
+
for(var i=0, len=links.length; i < len; i++) {
|
66
|
+
var exists = (typeof(links[i]) !== 'undefined');
|
67
|
+
if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
68
|
+
head.removeChild(links[i]);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
var getCurrentFavicon = function(){
|
74
|
+
|
75
|
+
if (!originalFavicon || !currentFavicon) {
|
76
|
+
var tag = getFaviconTag();
|
77
|
+
originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
|
78
|
+
}
|
79
|
+
|
80
|
+
return currentFavicon;
|
81
|
+
};
|
82
|
+
|
83
|
+
var getCanvas = function (){
|
84
|
+
|
85
|
+
if (!canvas) {
|
86
|
+
canvas = document.createElement("canvas");
|
87
|
+
canvas.width = size;
|
88
|
+
canvas.height = size;
|
89
|
+
}
|
90
|
+
|
91
|
+
return canvas;
|
92
|
+
};
|
93
|
+
|
94
|
+
var setFaviconTag = function(url){
|
95
|
+
removeFaviconTag();
|
96
|
+
|
97
|
+
var link = document.createElement('link');
|
98
|
+
link.type = 'image/x-icon';
|
99
|
+
link.rel = 'icon';
|
100
|
+
link.href = url;
|
101
|
+
document.getElementsByTagName('head')[0].appendChild(link);
|
102
|
+
};
|
103
|
+
|
104
|
+
var log = function(message){
|
105
|
+
if (window.console) window.console.log(message);
|
106
|
+
};
|
107
|
+
|
108
|
+
var drawFavicon = function(label, colour) {
|
109
|
+
|
110
|
+
// fallback to updating the browser title if unsupported
|
111
|
+
if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') {
|
112
|
+
return updateTitle(label);
|
113
|
+
}
|
114
|
+
|
115
|
+
var context = getCanvas().getContext("2d");
|
116
|
+
var colour = colour || '#000000';
|
117
|
+
var src = getCurrentFavicon();
|
118
|
+
|
119
|
+
faviconImage = document.createElement('img');
|
120
|
+
faviconImage.onload = function() {
|
121
|
+
|
122
|
+
// clear canvas
|
123
|
+
context.clearRect(0, 0, size, size);
|
124
|
+
|
125
|
+
// draw the favicon
|
126
|
+
context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size);
|
127
|
+
|
128
|
+
// draw bubble over the top
|
129
|
+
if ((label + '').length > 0) drawBubble(context, label, colour);
|
130
|
+
|
131
|
+
// refresh tag in page
|
132
|
+
refreshFavicon();
|
133
|
+
};
|
134
|
+
|
135
|
+
// allow cross origin resource requests if the image is not a data:uri
|
136
|
+
// as detailed here: https://github.com/mrdoob/three.js/issues/1305
|
137
|
+
if (!src.match(/^data/) && options.crossOrigin) {
|
138
|
+
faviconImage.crossOrigin = 'anonymous';
|
139
|
+
}
|
140
|
+
|
141
|
+
faviconImage.src = src;
|
142
|
+
};
|
143
|
+
|
144
|
+
var updateTitle = function(label) {
|
145
|
+
|
146
|
+
if (options.fallback) {
|
147
|
+
// Grab the current title that we can prefix with the label
|
148
|
+
var originalTitle = document.title;
|
149
|
+
|
150
|
+
// Strip out the old label if there is one
|
151
|
+
if (originalTitle[0] === '(') {
|
152
|
+
originalTitle = originalTitle.slice(originalTitle.indexOf(' '));
|
153
|
+
}
|
154
|
+
|
155
|
+
if ((label + '').length > 0) {
|
156
|
+
document.title = '(' + label + ') ' + originalTitle;
|
157
|
+
} else {
|
158
|
+
document.title = originalTitle;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
};
|
162
|
+
|
163
|
+
var drawBubble = function(context, label, colour) {
|
164
|
+
|
165
|
+
// automatic abbreviation for long (>2 digits) numbers
|
166
|
+
if (typeof label == 'number' && label > 99 && options.abbreviate) {
|
167
|
+
label = abbreviateNumber(label);
|
168
|
+
}
|
169
|
+
|
170
|
+
// bubble needs to be larger for double digits
|
171
|
+
var len = (label + '').length-1;
|
172
|
+
|
173
|
+
var width = options.width * r + (6 * r * len),
|
174
|
+
height = options.height * r;
|
175
|
+
|
176
|
+
var top = size - height,
|
177
|
+
left = size - width - r,
|
178
|
+
bottom = 16 * r,
|
179
|
+
right = 16 * r,
|
180
|
+
radius = 2 * r;
|
181
|
+
|
182
|
+
// webkit seems to render fonts lighter than firefox
|
183
|
+
context.font = (browser.webkit ? 'bold ' : '') + options.font;
|
184
|
+
context.fillStyle = options.background;
|
185
|
+
context.strokeStyle = options.background;
|
186
|
+
context.lineWidth = r;
|
187
|
+
|
188
|
+
// bubble
|
189
|
+
context.beginPath();
|
190
|
+
context.moveTo(left + radius, top);
|
191
|
+
context.quadraticCurveTo(left, top, left, top + radius);
|
192
|
+
context.lineTo(left, bottom - radius);
|
193
|
+
context.quadraticCurveTo(left, bottom, left + radius, bottom);
|
194
|
+
context.lineTo(right - radius, bottom);
|
195
|
+
context.quadraticCurveTo(right, bottom, right, bottom - radius);
|
196
|
+
context.lineTo(right, top + radius);
|
197
|
+
context.quadraticCurveTo(right, top, right - radius, top);
|
198
|
+
context.closePath();
|
199
|
+
context.fill();
|
200
|
+
|
201
|
+
// bottom shadow
|
202
|
+
context.beginPath();
|
203
|
+
context.strokeStyle = "rgba(0,0,0,0.3)";
|
204
|
+
context.moveTo(left + radius / 2.0, bottom);
|
205
|
+
context.lineTo(right - radius / 2.0, bottom);
|
206
|
+
context.stroke();
|
207
|
+
|
208
|
+
// label
|
209
|
+
context.fillStyle = options.colour;
|
210
|
+
context.textAlign = "right";
|
211
|
+
context.textBaseline = "top";
|
212
|
+
|
213
|
+
// unfortunately webkit/mozilla are a pixel different in text positioning
|
214
|
+
context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r);
|
215
|
+
};
|
216
|
+
|
217
|
+
var refreshFavicon = function(){
|
218
|
+
// check support
|
219
|
+
if (!getCanvas().getContext) return;
|
220
|
+
|
221
|
+
setFaviconTag(getCanvas().toDataURL());
|
222
|
+
};
|
223
|
+
|
224
|
+
var abbreviateNumber = function(label) {
|
225
|
+
var metricPrefixes = [
|
226
|
+
['G', 1000000000],
|
227
|
+
['M', 1000000],
|
228
|
+
['k', 1000]
|
229
|
+
];
|
230
|
+
|
231
|
+
for(var i = 0; i < metricPrefixes.length; ++i) {
|
232
|
+
if (label >= metricPrefixes[i][1]) {
|
233
|
+
label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0];
|
234
|
+
break;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
return label;
|
239
|
+
};
|
240
|
+
|
241
|
+
var round = function (value, precision) {
|
242
|
+
var number = new Number(value);
|
243
|
+
return number.toFixed(precision);
|
244
|
+
};
|
245
|
+
|
246
|
+
// public methods
|
247
|
+
Tinycon.setOptions = function(custom){
|
248
|
+
options = {};
|
249
|
+
|
250
|
+
for(var key in defaults){
|
251
|
+
options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key];
|
252
|
+
}
|
253
|
+
return this;
|
254
|
+
};
|
255
|
+
|
256
|
+
Tinycon.setImage = function(url){
|
257
|
+
currentFavicon = url;
|
258
|
+
refreshFavicon();
|
259
|
+
return this;
|
260
|
+
};
|
261
|
+
|
262
|
+
Tinycon.setBubble = function(label, colour) {
|
263
|
+
label = label || '';
|
264
|
+
drawFavicon(label, colour);
|
265
|
+
return this;
|
266
|
+
};
|
267
|
+
|
268
|
+
Tinycon.reset = function(){
|
269
|
+
setFaviconTag(originalFavicon);
|
270
|
+
};
|
271
|
+
|
272
|
+
Tinycon.setOptions(defaults);
|
273
|
+
window.Tinycon = Tinycon;
|
274
|
+
|
275
|
+
if(typeof define === 'function' && define.amd) {
|
276
|
+
define(Tinycon);
|
277
|
+
}
|
278
|
+
|
279
|
+
})();
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notifly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Passalini
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-12-
|
12
|
+
date: 2014-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -73,62 +73,6 @@ dependencies:
|
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
- !ruby/object:Gem::Dependency
|
77
|
-
name: rspec-rails
|
78
|
-
requirement: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 3.1.0
|
83
|
-
type: :development
|
84
|
-
prerelease: false
|
85
|
-
version_requirements: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 3.1.0
|
90
|
-
- !ruby/object:Gem::Dependency
|
91
|
-
name: capybara
|
92
|
-
requirement: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 2.4.4
|
97
|
-
type: :development
|
98
|
-
prerelease: false
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 2.4.4
|
104
|
-
- !ruby/object:Gem::Dependency
|
105
|
-
name: poltergeist
|
106
|
-
requirement: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 1.5.1
|
111
|
-
type: :development
|
112
|
-
prerelease: false
|
113
|
-
version_requirements: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 1.5.1
|
118
|
-
- !ruby/object:Gem::Dependency
|
119
|
-
name: shoulda-matchers
|
120
|
-
requirement: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 2.7.0
|
125
|
-
type: :development
|
126
|
-
prerelease: false
|
127
|
-
version_requirements: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 2.7.0
|
132
76
|
- !ruby/object:Gem::Dependency
|
133
77
|
name: pry-rails
|
134
78
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,20 +115,6 @@ dependencies:
|
|
171
115
|
- - ">="
|
172
116
|
- !ruby/object:Gem::Version
|
173
117
|
version: '0'
|
174
|
-
- !ruby/object:Gem::Dependency
|
175
|
-
name: launchy
|
176
|
-
requirement: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
181
|
-
type: :development
|
182
|
-
prerelease: false
|
183
|
-
version_requirements: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
118
|
- !ruby/object:Gem::Dependency
|
189
119
|
name: better_errors
|
190
120
|
requirement: !ruby/object:Gem::Requirement
|
@@ -255,6 +185,7 @@ files:
|
|
255
185
|
- app/models/notifly/notification.rb
|
256
186
|
- app/views/notifly/layouts/_actions.html.erb
|
257
187
|
- app/views/notifly/layouts/_counter.html.erb
|
188
|
+
- app/views/notifly/layouts/_empty.html.erb
|
258
189
|
- app/views/notifly/layouts/_index.html.erb
|
259
190
|
- app/views/notifly/layouts/_notification.html.erb
|
260
191
|
- app/views/notifly/layouts/_notifly.html.erb
|
@@ -284,7 +215,8 @@ files:
|
|
284
215
|
- lib/notifly/models/options/fly.rb
|
285
216
|
- lib/notifly/railtie.rb
|
286
217
|
- lib/tasks/notifly_tasks.rake
|
287
|
-
- vendor/assets/javascripts/
|
218
|
+
- vendor/assets/javascripts/tinycon.js
|
219
|
+
- vendor/assets/javascripts/twitter/bootstrap/dropdown.js
|
288
220
|
- vendor/assets/stylesheets/twitter/bootstrap.css
|
289
221
|
homepage: https://github.com/algorich/notifly
|
290
222
|
licenses:
|