notey 0.2.0 → 0.4.0
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 +45 -2
- data/app/delivery_methods/notey/email.rb +4 -0
- data/app/models/notey/delete_old_attempts.rb +19 -0
- data/app/models/notey/mark_read.rb +23 -0
- data/app/models/notey/notification.rb +2 -1
- data/app/views/notey/_inbox.html.erb +16 -0
- data/lib/notey/version.rb +1 -1
- data/lib/notey.rb +10 -1
- data/the_local/agents/notey-develop.md +30 -8
- data/the_local/agents/notey-info.md +3 -2
- data/the_local/agents/notey-install.md +21 -3
- data/the_local/interface.yml +8 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7610a3ba662e8faccd42819f0422ba19dd6b23f65619de246b28b89b201d7cbd
|
|
4
|
+
data.tar.gz: ce7e9b0e188efd5790e8b2d9a8545d0fdfc418133db9f7fca3f78cf529eb2e71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 961ec39375572d803830b55c13bc140c44a2a999d7ce6bdc55ee5124ef5bf9f059adb46bbb87fce89af72b6a9bfb61ce5617bdd513fb0be725d48df2cbf88e4e
|
|
7
|
+
data.tar.gz: cf7398efa6cd3d2a7f8afe4ff6a7dd83076db6cc4929f3ca80506c590d5ab86aadf5fea04ec6cb3cac8119d4d00ec34c7e3112dc2c25ecc4e8dde29f44b44125
|
data/README.md
CHANGED
|
@@ -163,8 +163,8 @@ end
|
|
|
163
163
|
|
|
164
164
|
## Settings sections
|
|
165
165
|
|
|
166
|
-
Notey ships its
|
|
167
|
-
settings shell renders them inside its own
|
|
166
|
+
Notey ships its screens as partials and their saving as action objects, so a
|
|
167
|
+
settings shell renders them inside its own page frame rather than linking away.
|
|
168
168
|
With [`bureau`](https://github.com/DYB-Development/bureau):
|
|
169
169
|
|
|
170
170
|
```ruby
|
|
@@ -180,6 +180,29 @@ A section registered this way is served by the settings shell, so the shell's
|
|
|
180
180
|
own capability check guards it. A section that only links to a mounted path is
|
|
181
181
|
not guarded, because the shell never renders it.
|
|
182
182
|
|
|
183
|
+
## The inbox
|
|
184
|
+
|
|
185
|
+
The inbox is the same shape and is not a setting, so render it wherever a
|
|
186
|
+
person's notifications belong in your own pages:
|
|
187
|
+
|
|
188
|
+
```erb
|
|
189
|
+
<%= render "notey/inbox",
|
|
190
|
+
person: current_user,
|
|
191
|
+
account: current_account.id,
|
|
192
|
+
submit_url: notifications_path %>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
It lists the notifications that person received in that account, newest first,
|
|
196
|
+
marking the unread ones. Marking one read posts to the url you named, so the
|
|
197
|
+
person stays on your page, and the action behind it runs:
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
Notey::MarkRead.new(person: current_user, account: current_account.id, values: params).call
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
It marks only a notification that person received in that account, so an id
|
|
204
|
+
from anywhere else does nothing.
|
|
205
|
+
|
|
183
206
|
`Notey::SavePreferences` and `Notey::SaveDestination` take `person:`, `account:`
|
|
184
207
|
and `values:`, and answer with an object responding to `ok?` and `message`. The
|
|
185
208
|
engine's own pages call the same two actions.
|
|
@@ -198,6 +221,26 @@ Each run enqueues one job per person, so one failing send does not stop the
|
|
|
198
221
|
rest. A window is sent once even if the run overlaps itself; a send that fails
|
|
199
222
|
releases the window so it can be sent again.
|
|
200
223
|
|
|
224
|
+
## Deleting old delivery records
|
|
225
|
+
|
|
226
|
+
Notey writes one record per notification per channel that leaves the
|
|
227
|
+
application, and nothing deletes them on its own. Say how long to keep them:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
# config/initializers/notey.rb
|
|
231
|
+
Notey.attempt_retention = 90.days
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Then run the deletion on a schedule, the way you run the digest windows:
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
Notey::DeleteOldAttempts.new.call
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Everything older than the period goes and everything inside it stays, so
|
|
241
|
+
running it twice leaves the same records as running it once. With no period set
|
|
242
|
+
it refuses to run rather than deleting nothing quietly.
|
|
243
|
+
|
|
201
244
|
## Destinations
|
|
202
245
|
|
|
203
246
|
A channel like email reaches a person at an address the app already holds. A
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Notey
|
|
4
|
+
class DeleteOldAttempts
|
|
5
|
+
UNSET = "notey deletes delivery records older than attempt_retention, which is not set"
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
raise MissingRetention, UNSET if retention.nil?
|
|
9
|
+
|
|
10
|
+
Attempt.where(created_at: ...retention.ago).delete_all
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def retention
|
|
16
|
+
Notey.attempt_retention
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Notey
|
|
4
|
+
class MarkRead
|
|
5
|
+
def initialize(values:, person: nil, account: nil)
|
|
6
|
+
@person = person
|
|
7
|
+
@account_id = account.respond_to?(:id) ? account.id : account
|
|
8
|
+
@values = values
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call
|
|
12
|
+
notification&.mark_as_read!
|
|
13
|
+
|
|
14
|
+
Kept.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def notification
|
|
20
|
+
Inbox.for(@person, account_id: @account_id).find_by(id: @values[:read])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -27,7 +27,8 @@ module Notey
|
|
|
27
27
|
config = ActiveSupport::OrderedOptions.new
|
|
28
28
|
config[:class] = channel.delivery_method if channel.delivery_method
|
|
29
29
|
config[:notey_channel] = channel.name
|
|
30
|
-
config[:if] = Notey.sends(notey_notification_type, on: channel.name, addressed: channel.addressed
|
|
30
|
+
config[:if] = Notey.sends(notey_notification_type, on: channel.name, addressed: channel.addressed?,
|
|
31
|
+
via: Notey.known_delivery_method(channel))
|
|
31
32
|
config
|
|
32
33
|
end
|
|
33
34
|
private_class_method :delivery_config
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<% notifications = Notey::Inbox.for(person, account_id: account).includes(:event).order(created_at: :desc) %>
|
|
2
|
+
|
|
3
|
+
<% notifications.each do |notification| %>
|
|
4
|
+
<%= ui_panel do %>
|
|
5
|
+
<div data-notification-id="<%= notification.id %>">
|
|
6
|
+
<%= notification.event.title %>
|
|
7
|
+
<%= ui_badge(label: notification.read? ? "Read" : "Unread") %>
|
|
8
|
+
<% unless notification.read? %>
|
|
9
|
+
<%= ui_form(action: submit_url, method: :patch) do %>
|
|
10
|
+
<%= hidden_field_tag "read", notification.id, id: nil %>
|
|
11
|
+
<%= ui_button(label: "Mark read") %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
</div>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
data/lib/notey/version.rb
CHANGED
data/lib/notey.rb
CHANGED
|
@@ -19,9 +19,11 @@ module Notey
|
|
|
19
19
|
class MissingSender < StandardError; end
|
|
20
20
|
class UnsendableChannel < StandardError; end
|
|
21
21
|
class UnsendableAttempt < StandardError; end
|
|
22
|
+
class MissingRetention < StandardError; end
|
|
22
23
|
|
|
23
24
|
class << self
|
|
24
25
|
attr_writer :notification_url, :mailer_sender
|
|
26
|
+
attr_accessor :attempt_retention
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def self.mailer_sender
|
|
@@ -95,6 +97,12 @@ module Notey
|
|
|
95
97
|
"the channel #{channel.name} needs the option #{required.first}, which notey does not supply"
|
|
96
98
|
end
|
|
97
99
|
|
|
100
|
+
def self.known_delivery_method(channel)
|
|
101
|
+
delivery_method_for(channel)
|
|
102
|
+
rescue UnsendableChannel
|
|
103
|
+
nil
|
|
104
|
+
end
|
|
105
|
+
|
|
98
106
|
def self.delivery_method_for(channel)
|
|
99
107
|
name = channel.delivery_method || "Noticed::DeliveryMethods::#{channel.name.camelize}"
|
|
100
108
|
name.to_s.constantize
|
|
@@ -108,11 +116,12 @@ module Notey
|
|
|
108
116
|
raise MissingSender, "notey sends digests by email and no mailer_sender is set"
|
|
109
117
|
end
|
|
110
118
|
|
|
111
|
-
def self.sends(notification_type, on:, addressed: false)
|
|
119
|
+
def self.sends(notification_type, on:, addressed: false, via: nil)
|
|
112
120
|
lambda do
|
|
113
121
|
decision = Channels.decision_for(recipient, notification_type, account_id: event.account_id)
|
|
114
122
|
|
|
115
123
|
next false unless decision.window == "immediate" && decision.channels.include?(on.to_s)
|
|
124
|
+
next false if via.respond_to?(:reachable?) && !via.reachable?(recipient)
|
|
116
125
|
next true unless addressed
|
|
117
126
|
|
|
118
127
|
Destinations.for(event.account_id, on, member: recipient).present?
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: notey-develop
|
|
3
3
|
description: Use PROACTIVELY for defining a notification type, sending one to the recipients your own code resolved, sending one when a domain event fires, addressing a channel at a person, scheduling daily and weekly digest runs, reading a person's inbox, and reading their channels and window — MUST BE USED instead of hand-rolling preference checks, per-person delivery addresses, or a digest loop.
|
|
4
4
|
tools: Read, Write, Edit, Grep
|
|
5
|
-
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel
|
|
5
|
+
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel that the host keeps for a period it sets
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
This local follows the steps below exactly and invents no others. Where a step
|
|
@@ -40,8 +40,16 @@ This local assumes the gem is already hooked into the app; if it is not, that is
|
|
|
40
40
|
- `Notey::DigestRun` — sends one window's digests, with `call` for everyone on
|
|
41
41
|
that window and `deliver_to_member(member, account_id)` for one person in one
|
|
42
42
|
account.
|
|
43
|
+
- `Notey::DeleteOldAttempts` — deletes every record of what was sent that is
|
|
44
|
+
older than `Notey.attempt_retention`, and refuses to run when no retention is
|
|
45
|
+
set.
|
|
43
46
|
- `Notey::Inbox.for(member, account_id:)` — returns that person's notifications
|
|
44
47
|
for that account, as a relation.
|
|
48
|
+
- `notey/inbox` — the partial a host renders inside a page of its own to show a
|
|
49
|
+
person their notifications, taking `person`, `account` and the `submit_url`
|
|
50
|
+
that marking one read posts to.
|
|
51
|
+
- `Notey::MarkRead` — marks the notification a person picked as read, and marks
|
|
52
|
+
nothing when the id belongs to another person or another account.
|
|
45
53
|
- `wants?(type, on:, account_id:)` — on the recipient model, true when that
|
|
46
54
|
person wants that type on that channel in that account.
|
|
47
55
|
- `channels_for(type, account_id:)` — on the recipient model, the channels that
|
|
@@ -133,7 +141,21 @@ This local assumes the gem is already hooked into the app; if it is not, that is
|
|
|
133
141
|
in this app — cron, a scheduler gem, or a platform scheduler — and at what
|
|
134
142
|
hour each window should go out.
|
|
135
143
|
|
|
136
|
-
7.
|
|
144
|
+
7. Schedule the deletion of old delivery records alongside the windows:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
Notey::DeleteOldAttempts.new.call
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
notey writes one record per notification per channel that leaves the
|
|
151
|
+
application and deletes none of them on its own, so a host that never runs
|
|
152
|
+
this keeps every row forever. It deletes everything older than
|
|
153
|
+
`Notey.attempt_retention` and refuses to run when that is not set, which
|
|
154
|
+
`notey-install` is the step that sets. Running it twice leaves the same
|
|
155
|
+
records as running it once, so a schedule that overlaps itself is safe. Ask
|
|
156
|
+
the developer how often it should run.
|
|
157
|
+
|
|
158
|
+
8. Read a person's notifications through the inbox rather than querying Noticed
|
|
137
159
|
directly:
|
|
138
160
|
|
|
139
161
|
```ruby
|
|
@@ -143,7 +165,7 @@ This local assumes the gem is already hooked into the app; if it is not, that is
|
|
|
143
165
|
It returns a relation, so chain `.unread`, `.order` and `.limit` onto it. With
|
|
144
166
|
no account it returns an empty relation, never another account's rows.
|
|
145
167
|
|
|
146
|
-
|
|
168
|
+
9. Read a person's preferences from the host's own code when the app needs to
|
|
147
169
|
branch on them:
|
|
148
170
|
|
|
149
171
|
```ruby
|
|
@@ -156,7 +178,7 @@ This local assumes the gem is already hooked into the app; if it is not, that is
|
|
|
156
178
|
three read a person's stored row for that type, and fall back to email and
|
|
157
179
|
in-app when they have never stored one.
|
|
158
180
|
|
|
159
|
-
|
|
181
|
+
10. In tests that register their own channels or notification types, call
|
|
160
182
|
`Notey.reset!` in teardown. Both are held for the life of the process, so a
|
|
161
183
|
test that skips this leaves its channels and types in place for every test
|
|
162
184
|
after it.
|
|
@@ -185,7 +207,7 @@ This local assumes the gem is already hooked into the app; if it is not, that is
|
|
|
185
207
|
no row saying it went out.
|
|
186
208
|
- **Notification types, subscribers and digest schedules all belong in the
|
|
187
209
|
host's code**, never in the gem.
|
|
188
|
-
- **Out of scope.** Registering the channels the application has,
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
`notey-install`.
|
|
210
|
+
- **Out of scope.** Registering the channels the application has, setting how
|
|
211
|
+
long delivery records are kept, making a model a recipient, setting the
|
|
212
|
+
current person and account, storing an account's addresses, and the pages a
|
|
213
|
+
person picks their own channels on all belong to `notey-install`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: notey-info
|
|
3
3
|
description: Use to learn what notey offers — notification types and the channels they allow, per-person per-account delivery preferences, digest windows, an in-app inbox, and per-account destinations.
|
|
4
4
|
tools: Read
|
|
5
|
-
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel
|
|
5
|
+
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel that the host keeps for a period it sets
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
This local explains what notey is and which of its other two locals you need. It
|
|
@@ -80,4 +80,5 @@ has already been sent, you are building, and `notey-develop` owns it.
|
|
|
80
80
|
- **Attempt** — one row per notification per outbound channel, claimed before the
|
|
81
81
|
send and marked after, holding whether it was sent and what a failure said. It
|
|
82
82
|
is what answers why one person was not reached, and it is what stops the same
|
|
83
|
-
channel sending twice for the same notification.
|
|
83
|
+
channel sending twice for the same notification. The host says how long these
|
|
84
|
+
are kept and runs the deletion that enforces it.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: notey-install
|
|
3
3
|
description: Use to hook notey into a project — installing its tables, mounting its engine, registering the channels the application can send on, making a model a recipient, setting the current person and account, putting the account on Noticed's rows, supplying a notification url, and reaching the preferences, inbox and destinations pages.
|
|
4
4
|
tools: Bash, Read, Edit
|
|
5
|
-
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel
|
|
5
|
+
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel that the host keeps for a period it sets
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
This local follows the steps below exactly and invents no others. Where a step
|
|
@@ -33,6 +33,9 @@ different notifications in each.
|
|
|
33
33
|
through it.
|
|
34
34
|
- `Notey.notification_url=` — takes a lambda returning the host's own url for
|
|
35
35
|
one notification, used to link the rows in a digest email.
|
|
36
|
+
- `Notey.attempt_retention=` — takes how long notey keeps the record of what it
|
|
37
|
+
sent on each channel, such as `90.days`. Nothing is deleted until the host
|
|
38
|
+
runs the deletion.
|
|
36
39
|
- `Notey.check!` — raises when a registered channel names a delivery method that
|
|
37
40
|
does not exist or needs an option notey does not supply, and when notey has no
|
|
38
41
|
sender address for its digests. notey runs it itself after initialization when
|
|
@@ -162,7 +165,18 @@ moves all three.
|
|
|
162
165
|
the engine's copy. Ask the developer whether these pages should carry the
|
|
163
166
|
app's navigation.
|
|
164
167
|
|
|
165
|
-
12. Set
|
|
168
|
+
12. Set the retention for delivery records in
|
|
169
|
+
`config/initializers/notey.rb`:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
Notey.attempt_retention = 90.days
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Ask the developer how long this application should keep the record of what
|
|
176
|
+
was sent on each channel; there is no default. Scheduling the deletion is
|
|
177
|
+
`notey-develop`'s step, and nothing is deleted until it runs.
|
|
178
|
+
|
|
179
|
+
13. Set up destinations only if a registered channel needs an address. The stored credential is encrypted, so
|
|
166
180
|
Active Record encryption keys must be configured in the host's credentials
|
|
167
181
|
(`bin/rails db:encryption:init` generates a set) or saving a destination
|
|
168
182
|
raises. Ask the developer whether any channel needs this before doing it.
|
|
@@ -190,6 +204,10 @@ moves all three.
|
|
|
190
204
|
that changes it.
|
|
191
205
|
- **Re-run `bin/rails notey:install:migrations` after upgrading the gem.** It
|
|
192
206
|
copies only the migrations the host does not already have.
|
|
193
|
-
- **
|
|
207
|
+
- **Nothing deletes a delivery record until the host runs the deletion.** The
|
|
208
|
+
table grows for every notification on every outbound channel, so a host that
|
|
209
|
+
sets no retention and schedules no deletion keeps every row forever.
|
|
210
|
+
- **Out of scope.** Scheduling the digest runs and the deletion of old delivery
|
|
211
|
+
records, writing a notification type,
|
|
194
212
|
sending one when a domain event fires, and reading the inbox from the host's
|
|
195
213
|
own code all belong to `notey-develop`.
|
data/the_local/interface.yml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel
|
|
1
|
+
scope: notifications — application-wide channel registrations, notification types that name no channel, per-person per-account channel preferences, digest windows, an in-app inbox, per-account destinations, and a record of what was sent on each channel that the host keeps for a period it sets
|
|
2
2
|
|
|
3
3
|
install:
|
|
4
4
|
- bin/rails notey:install:migrations
|
|
@@ -8,6 +8,7 @@ install:
|
|
|
8
8
|
- Notey::Notification
|
|
9
9
|
- Notey::Current
|
|
10
10
|
- Notey.notification_url=
|
|
11
|
+
- Notey.attempt_retention=
|
|
11
12
|
- Notey.check!
|
|
12
13
|
- /notey/preferences
|
|
13
14
|
- /notey/notifications
|
|
@@ -19,7 +20,10 @@ develop:
|
|
|
19
20
|
- notify
|
|
20
21
|
- Notey::Destinations.for
|
|
21
22
|
- Notey::DigestRun
|
|
23
|
+
- Notey::DeleteOldAttempts
|
|
22
24
|
- Notey::Inbox.for
|
|
25
|
+
- notey/inbox
|
|
26
|
+
- Notey::MarkRead
|
|
23
27
|
- wants?
|
|
24
28
|
- channels_for
|
|
25
29
|
- digest_window_for
|
|
@@ -40,6 +44,9 @@ sources:
|
|
|
40
44
|
- app/models/notey/destination.rb
|
|
41
45
|
- app/models/notey/digest.rb
|
|
42
46
|
- app/models/notey/attempt.rb
|
|
47
|
+
- app/models/notey/delete_old_attempts.rb
|
|
48
|
+
- app/models/notey/mark_read.rb
|
|
49
|
+
- app/views/notey/_inbox.html.erb
|
|
43
50
|
- app/delivery_methods/notey/email.rb
|
|
44
51
|
- app/delivery_methods/notey/in_app.rb
|
|
45
52
|
- app/jobs/notey/digest_job.rb
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: notey
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tylercschneider
|
|
@@ -88,9 +88,11 @@ files:
|
|
|
88
88
|
- app/models/notey/application_record.rb
|
|
89
89
|
- app/models/notey/attempt.rb
|
|
90
90
|
- app/models/notey/current.rb
|
|
91
|
+
- app/models/notey/delete_old_attempts.rb
|
|
91
92
|
- app/models/notey/destination.rb
|
|
92
93
|
- app/models/notey/digest.rb
|
|
93
94
|
- app/models/notey/kept.rb
|
|
95
|
+
- app/models/notey/mark_read.rb
|
|
94
96
|
- app/models/notey/notification.rb
|
|
95
97
|
- app/models/notey/preference.rb
|
|
96
98
|
- app/models/notey/refusal.rb
|
|
@@ -98,6 +100,7 @@ files:
|
|
|
98
100
|
- app/models/notey/save_my_destination.rb
|
|
99
101
|
- app/models/notey/save_preferences.rb
|
|
100
102
|
- app/views/notey/_destinations.html.erb
|
|
103
|
+
- app/views/notey/_inbox.html.erb
|
|
101
104
|
- app/views/notey/_my_destinations.html.erb
|
|
102
105
|
- app/views/notey/_preferences.html.erb
|
|
103
106
|
- app/views/notey/destinations/show.html.erb
|