bible270 1.8.3 → 1.8.5
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/CHANGELOG.md +3 -0
- data/app/controllers/bible270/admin_controller.rb +1 -1
- data/app/controllers/bible270/readers_controller.rb +13 -2
- data/app/models/bible270/comment.rb +8 -1
- data/app/models/bible270/reader.rb +11 -0
- data/app/views/bible270/admin/index.html.erb +2 -1
- data/app/views/bible270/admin/show.html.erb +3 -1
- data/app/views/bible270/readers/index.html.erb +1 -0
- data/app/views/bible270/readers/progress.html.erb +3 -1
- data/app/views/bible270/readers/show.html.erb +4 -1
- data/app/views/bible270/shared/_reflections.html.erb +29 -4
- data/app/views/bible270/shared/_styles.html.erb +1 -0
- data/lib/bible270/reader_progress_report.rb +5 -12
- data/lib/bible270/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37c1e22aede65482ba3d194eb1d2e74efde387475c1f264c30496e6330d3666c
|
|
4
|
+
data.tar.gz: 298306a3422ce83b4f68b2a8e8acaa16b956c30475a7d9d36afd88a76f086450
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 471fff64f3f002999a00c5785bdf975aa5c5ed4723c9c107e7e738161f4b4740b7f73c29067f0aa22a5bdb3d0c5cf818b5e3ebcb27b9b89898a7e1a1340b0abf
|
|
7
|
+
data.tar.gz: b68eddc3274715999dde7df1df9928f4b0899e45323f18b91ba9e7d17781c81ad02df129ac52fcb09427fce8e8466d87f3b51be211c37fbbf30ad4fef8f15b15
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,9 @@ All notable changes to bible270. Format follows [Keep a Changelog](https://keepa
|
|
|
7
7
|
### Changed
|
|
8
8
|
|
|
9
9
|
- keep Proverbs 7 whole and divide Proverbs 10 and 16 into four readings
|
|
10
|
+
- show likes and replies on My Progress and reader pages, with admin edit links on reader pages
|
|
11
|
+
- show each reader's pace beside their completed-day count for admins on Community
|
|
12
|
+
- add edit, like, and reply controls to reflections on Admin reader pages
|
|
10
13
|
|
|
11
14
|
**[Full Changelog](https://github.com/avonderluft/bible270/compare/v1.8.1...main)**
|
|
12
15
|
|
|
@@ -97,7 +97,7 @@ module Bible270
|
|
|
97
97
|
@comment_notifications_available = comment_notifications_available_for?(@reader)
|
|
98
98
|
@completion_dove_preference_available = completion_dove_available_for(@reader)
|
|
99
99
|
@days_completed = @reader.days_completed
|
|
100
|
-
@comments = @reader.comments.order(created_at: :desc).limit(50)
|
|
100
|
+
@comments = @reader.comments.includes(likes: :reader).order(created_at: :desc).limit(50)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
# ---- reflections ------------------------------------------------------
|
|
@@ -17,7 +17,7 @@ module Bible270
|
|
|
17
17
|
def progress
|
|
18
18
|
@reader = current_reader
|
|
19
19
|
# Defaults keep the open visitor page simple and make every view input explicit.
|
|
20
|
-
@recent_comments = @reader ? @reader
|
|
20
|
+
@recent_comments = @reader ? recent_reflections(@reader, limit: 5) : []
|
|
21
21
|
@partial_day_tasks = []
|
|
22
22
|
@remaining_partial_days = 0
|
|
23
23
|
return unless @reader
|
|
@@ -34,7 +34,7 @@ module Bible270
|
|
|
34
34
|
redirect_to(community_path, alert: 'Reader not found.') and return unless @reader
|
|
35
35
|
|
|
36
36
|
@days_completed = @reader.days_completed
|
|
37
|
-
@recent_comments = @reader
|
|
37
|
+
@recent_comments = recent_reflections(@reader, limit: 20)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def mention_suggestions
|
|
@@ -43,5 +43,16 @@ module Bible270
|
|
|
43
43
|
response.headers['Cache-Control'] = 'private, no-store'
|
|
44
44
|
render json: { suggestions: Reader.mention_suggestions(params[:q], except: current_reader) }
|
|
45
45
|
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def recent_reflections(reader, limit:)
|
|
50
|
+
comments = reader.comments.recent
|
|
51
|
+
.includes(:reader, { likes: :reader }, { replies: [:reader, { likes: :reader }] })
|
|
52
|
+
.limit(limit).to_a
|
|
53
|
+
ids = comments.map(&:id)
|
|
54
|
+
# A reader's own replies already appear beneath any listed parent reflection.
|
|
55
|
+
comments.reject { |comment| ids.include?(comment.parent_id) }
|
|
56
|
+
end
|
|
46
57
|
end
|
|
47
58
|
end
|
|
@@ -150,7 +150,14 @@ module Bible270
|
|
|
150
150
|
def edited? = updated_at - created_at > 1
|
|
151
151
|
|
|
152
152
|
# Visible replies, oldest first: a conversation reads forwards.
|
|
153
|
-
def visible_replies
|
|
153
|
+
def visible_replies
|
|
154
|
+
if replies.loaded?
|
|
155
|
+
replies.select(&:approved?).sort_by { |reply| [reply.created_at, reply.id] }
|
|
156
|
+
else
|
|
157
|
+
replies.approved.order(created_at: :asc, id: :asc)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
154
161
|
def moderated? = moderated_at.present?
|
|
155
162
|
|
|
156
163
|
private
|
|
@@ -643,6 +643,17 @@ module Bible270
|
|
|
643
643
|
Plan.day_for(Bible270.today, effective_start_date)
|
|
644
644
|
end
|
|
645
645
|
|
|
646
|
+
def progress_status(completed_days: days_completed)
|
|
647
|
+
today = calendar_day
|
|
648
|
+
return 'undated' unless today
|
|
649
|
+
|
|
650
|
+
difference = completed_days - today
|
|
651
|
+
return 'on track' if difference.zero?
|
|
652
|
+
|
|
653
|
+
amount = difference.abs
|
|
654
|
+
"#{amount} #{amount == 1 ? 'day' : 'days'} #{difference.positive? ? 'ahead' : 'behind'}"
|
|
655
|
+
end
|
|
656
|
+
|
|
646
657
|
# Raw, unclamped — lets callers distinguish "not started yet" / "finished".
|
|
647
658
|
# The plan day that today actually is, or nil when today falls outside the
|
|
648
659
|
# plan's window. calendar_day clamps, so before the start date it reports day
|
|
@@ -90,8 +90,9 @@
|
|
|
90
90
|
<% else %>
|
|
91
91
|
<%= reader.provider %>
|
|
92
92
|
<% end %>
|
|
93
|
-
· <%= @days_completed[reader.id] %>/<%= Bible270::Plan::DAYS %> days
|
|
94
93
|
<% if reader.dated? %>· started <%= reader.effective_start_date.strftime('%b %-d, %Y') %><% end %>
|
|
94
|
+
· <%= @days_completed[reader.id] %>/<%= Bible270::Plan::DAYS %> days
|
|
95
|
+
· <%= @reader_report.status_for(reader) %>
|
|
95
96
|
</div>
|
|
96
97
|
<div class="sub b270-reader-activity">
|
|
97
98
|
<% if (activity = @recent_reader_activities[reader.id]) %>
|
|
@@ -115,7 +115,8 @@
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
<div class="b270-panel">
|
|
118
|
-
<%= render "bible270/shared/
|
|
118
|
+
<%= render "bible270/shared/interaction_status" %>
|
|
119
|
+
<%= render "bible270/shared/reflections", comments: @comments, moderate: true, editable: true, actions: true %>
|
|
119
120
|
</div>
|
|
120
121
|
|
|
121
122
|
<div class="b270-panel">
|
|
@@ -172,3 +173,4 @@
|
|
|
172
173
|
</div>
|
|
173
174
|
|
|
174
175
|
<p style="margin-top:18px"><%= link_to '← All readers', admin_path %></p>
|
|
176
|
+
<%= render "bible270/shared/interaction_ui" %>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
joined <%= Bible270.local_time(r.created_at).strftime("%b %-d %Y") %><% if @show_admin_progress %>
|
|
15
15
|
· <%= link_to "#{@days_completed[r.id]} of #{Bible270::Plan::DAYS} days complete",
|
|
16
16
|
admin_reader_path(r), class: "b270-admin-progress" %>
|
|
17
|
+
· <%= r.progress_status(completed_days: @days_completed[r.id].to_i) %>
|
|
17
18
|
<% end %>
|
|
18
19
|
</div>
|
|
19
20
|
</div>
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
<% if @reader %>
|
|
14
14
|
<div class="b270-panel">
|
|
15
|
+
<%= render "bible270/shared/interaction_status" %>
|
|
15
16
|
<%= render "bible270/shared/reflections", comments: @recent_comments,
|
|
16
|
-
title: "Your recent reflections", editable: true,
|
|
17
|
+
title: "Your recent reflections", editable: true, conversations: true,
|
|
17
18
|
empty_text: "You have not written any reflections yet." %>
|
|
18
19
|
</div>
|
|
20
|
+
<%= render "bible270/shared/interaction_ui" %>
|
|
19
21
|
<% end %>
|
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div class="b270-panel">
|
|
19
|
+
<%= render "bible270/shared/interaction_status" %>
|
|
19
20
|
<%= render "bible270/shared/reflections", comments: @recent_comments,
|
|
20
|
-
title: "Their reflections", empty_text: "No reflections yet."
|
|
21
|
+
title: "Their reflections", empty_text: "No reflections yet.",
|
|
22
|
+
conversations: true, editable: Bible270.config.admin?(current_reader) %>
|
|
21
23
|
</div>
|
|
22
24
|
|
|
23
25
|
<%= render "bible270/shared/day_index", reader: @reader, expanded: true %>
|
|
26
|
+
<%= render "bible270/shared/interaction_ui" %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%# locals: (comments:, title: "Their reflections", moderate: false, editable: false, empty_text: "None yet.") %>
|
|
1
|
+
<%# locals: (comments:, title: "Their reflections", moderate: false, editable: false, actions: false, conversations: false, reply: false, empty_text: "None yet.") %>
|
|
2
2
|
<%#
|
|
3
3
|
A reader's reflections. Three views showed near-identical markup: the admin
|
|
4
4
|
page, a reader's public page, and the progress page, differing only in whether
|
|
@@ -11,17 +11,21 @@
|
|
|
11
11
|
No ERB tags in this comment: the first close-tag would end it and the rest
|
|
12
12
|
would become live template code.
|
|
13
13
|
%>
|
|
14
|
-
|
|
14
|
+
<% if title.present? %><h2 class="b270-subhead"><%= title %></h2><% end %>
|
|
15
15
|
|
|
16
16
|
<% if comments.any? %>
|
|
17
17
|
<% comments.each do |comment| %>
|
|
18
|
-
<div class="b270-comment">
|
|
18
|
+
<div class="b270-comment <%= 'b270-reply' if reply %>" id="comment-<%= comment.id %>">
|
|
19
|
+
<% if reply %><%= b270_avatar(comment.reader, size: 36) %><% end %>
|
|
19
20
|
<div style="flex:1">
|
|
20
21
|
<div class="b270-cmeta">
|
|
22
|
+
<% if reply %>
|
|
23
|
+
<strong><%= link_to comment.reader.display_name, reader_path(comment.reader) %></strong> ·
|
|
24
|
+
<% end %>
|
|
21
25
|
<%= link_to "Day #{comment.day}", day_path(comment.day) %>
|
|
22
26
|
· <%= b270_date(comment.created_at) %>
|
|
23
27
|
<% if moderate && comment.hidden? %><span class="b270-badge">Hidden</span><% end %>
|
|
24
|
-
<% if editable && b270_can_edit?(comment) %>
|
|
28
|
+
<% if editable && !comment.hidden? && b270_can_edit?(comment) %>
|
|
25
29
|
<%= link_to "edit", day_path(comment.day, edit: comment.id, anchor: "comment-#{comment.id}"),
|
|
26
30
|
class: "b270-cedit" %>
|
|
27
31
|
<% end %>
|
|
@@ -29,6 +33,27 @@
|
|
|
29
33
|
|
|
30
34
|
<div class="b270-cbody"><%= b270_comment_body(comment) %></div>
|
|
31
35
|
|
|
36
|
+
<% if (actions || conversations) && !comment.hidden? %>
|
|
37
|
+
<div class="b270-cactions">
|
|
38
|
+
<%= render "bible270/likes/likes", comment: comment %>
|
|
39
|
+
<% if !comment.reply? && signed_in? && comment.reader_id != current_reader.id %>
|
|
40
|
+
<%= link_to "Reply", day_path(comment.day, reply_to: comment.id, anchor: "new_comment_form"),
|
|
41
|
+
class: "b270-linkbtn" %>
|
|
42
|
+
<% end %>
|
|
43
|
+
</div>
|
|
44
|
+
<% end %>
|
|
45
|
+
<% if conversations %>
|
|
46
|
+
<% unless comment.reply? %>
|
|
47
|
+
<div class="b270-replies" id="replies-<%= comment.id %>">
|
|
48
|
+
<% replies = comment.visible_replies %>
|
|
49
|
+
<% if replies.any? %>
|
|
50
|
+
<%= render "bible270/shared/reflections", comments: replies, title: nil,
|
|
51
|
+
conversations: true, reply: true, editable: editable %>
|
|
52
|
+
<% end %>
|
|
53
|
+
</div>
|
|
54
|
+
<% end %>
|
|
55
|
+
<% end %>
|
|
56
|
+
|
|
32
57
|
<% if moderate %>
|
|
33
58
|
<div style="display:flex;gap:10px;margin-top:6px">
|
|
34
59
|
<% if comment.hidden? %>
|
|
@@ -239,6 +239,7 @@
|
|
|
239
239
|
.b270-mention{color:var(--teal);font-weight:600;text-decoration:none}
|
|
240
240
|
.b270-mention:hover{text-decoration:underline}
|
|
241
241
|
.b270-cactions{display:flex;align-items:center;gap:12px;margin-top:6px;flex-wrap:wrap}
|
|
242
|
+
.b270-cactions .b270-linkbtn{margin:0}
|
|
242
243
|
.b270-likes{display:inline-flex;align-items:center;gap:3px;position:relative}
|
|
243
244
|
.b270-heart{font-size:13px;line-height:1;cursor:default}
|
|
244
245
|
/* The single heart is also the toggle for signed-in readers. It stays red
|
|
@@ -28,12 +28,16 @@ module Bible270
|
|
|
28
28
|
Row.new(
|
|
29
29
|
name: reader.display_name,
|
|
30
30
|
days_read: days_read,
|
|
31
|
-
status:
|
|
31
|
+
status: reader.progress_status(completed_days: days_read),
|
|
32
32
|
last_activity: last_activity_date(reader)
|
|
33
33
|
)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def status_for(reader)
|
|
38
|
+
reader.progress_status(completed_days: completed_days.fetch(reader.id, 0))
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def empty? = rows.empty?
|
|
38
42
|
|
|
39
43
|
def to_table
|
|
@@ -79,16 +83,5 @@ module Bible270
|
|
|
79
83
|
occurred_at = recent_activities[reader.id]&.occurred_at
|
|
80
84
|
occurred_at ? Bible270.local_time(occurred_at).strftime('%b %-d, %Y') : '—'
|
|
81
85
|
end
|
|
82
|
-
|
|
83
|
-
def status(reader, days_read)
|
|
84
|
-
calendar_day = reader.calendar_day
|
|
85
|
-
return 'undated' unless calendar_day
|
|
86
|
-
|
|
87
|
-
difference = days_read - calendar_day
|
|
88
|
-
return 'on track' if difference.zero?
|
|
89
|
-
|
|
90
|
-
amount = difference.abs
|
|
91
|
-
"#{amount} #{amount == 1 ? 'day' : 'days'} #{difference.positive? ? 'ahead' : 'behind'}"
|
|
92
|
-
end
|
|
93
86
|
end
|
|
94
87
|
end
|
data/lib/bible270/version.rb
CHANGED