thredded 0.15.1 → 0.15.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 +1 -1
- data/app/assets/stylesheets/thredded/_thredded.scss +1 -0
- data/app/assets/stylesheets/thredded/components/_base.scss +4 -0
- data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +2 -2
- data/app/assets/stylesheets/thredded/layout/_moderation.scss +8 -7
- data/app/assets/stylesheets/thredded/layout/_navigation.scss +61 -26
- data/app/assets/stylesheets/thredded/layout/_scoped-navigation.scss +5 -0
- data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +4 -2
- data/app/controllers/thredded/application_controller.rb +52 -1
- data/app/controllers/thredded/topics_controller.rb +41 -39
- data/app/helpers/thredded/application_helper.rb +14 -15
- data/app/helpers/thredded/nav_helper.rb +12 -0
- data/app/helpers/thredded/urls_helper.rb +11 -0
- data/app/models/thredded/messageboard.rb +1 -0
- data/app/models/thredded/topic.rb +7 -0
- data/app/views/thredded/messageboards/_messageboard_actions.html.erb +7 -0
- data/app/views/thredded/private_topics/_form.html.erb +1 -1
- data/app/views/thredded/shared/_nav.html.erb +5 -0
- data/app/views/thredded/shared/nav/_moderation.html.erb +1 -1
- data/app/views/thredded/shared/nav/_notification_preferences.html.erb +1 -2
- data/app/views/thredded/shared/nav/_private_topics.html.erb +1 -1
- data/app/views/thredded/shared/nav/_unread_topics.html.erb +12 -0
- data/app/views/thredded/topics/_form.html.erb +1 -1
- data/app/views/thredded/topics/index.html.erb +2 -8
- data/app/views/thredded/topics/unread.html.erb +33 -0
- data/config/locales/de.yml +7 -0
- data/config/locales/en.yml +7 -0
- data/config/locales/es.yml +7 -0
- data/config/locales/fr.yml +7 -0
- data/config/locales/it.yml +7 -0
- data/config/locales/pl.yml +7 -0
- data/config/locales/pt-BR.yml +7 -0
- data/config/locales/ru.yml +7 -0
- data/config/locales/zh-CN.yml +7 -0
- data/config/routes.rb +7 -0
- data/lib/thredded/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb521ffdf8a0e754e7e55a856a649913e79295cd33799f29efeab2311f7f0f12
|
4
|
+
data.tar.gz: 0c40013b94c70655bb7de0edcb84bae86a6c4a8d66dc9e84a95682f82e568293
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf907ac1caa92e8d6362369c13eb0be750f95237c8a4670426f7973346de420bf6e17fa5bbd54ece98a06acad5522eb601838ea0b0c97e4799d926039be3b95d
|
7
|
+
data.tar.gz: 626752cbba2144434a985f4af447dcf174dd33bf1dbc8e93a28124d34be5177ddcbae74a7232dbbb821419a49e82da2af670f0dc4de4dad8514fdac06213557e
|
data/README.md
CHANGED
@@ -95,7 +95,7 @@ Then, see the rest of this Readme for more information about using and customizi
|
|
95
95
|
Add the gem to your Gemfile:
|
96
96
|
|
97
97
|
```ruby
|
98
|
-
gem 'thredded', '~> 0.15.
|
98
|
+
gem 'thredded', '~> 0.15.2'
|
99
99
|
```
|
100
100
|
|
101
101
|
Add the Thredded [initializer] to your parent app by running the install generator.
|
@@ -3,14 +3,15 @@
|
|
3
3
|
@include thredded-media-desktop-and-up {
|
4
4
|
margin-bottom: $thredded-base-spacing;
|
5
5
|
}
|
6
|
+
}
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
.thredded--moderation-navigation--items {
|
9
|
+
@extend %thredded--nav-tabs;
|
10
|
+
margin-bottom: $thredded-small-spacing;
|
11
|
+
}
|
12
|
+
|
13
|
+
.thredded--moderation-navigation--item {
|
14
|
+
@extend %thredded--nav-tabs--item;
|
14
15
|
}
|
15
16
|
|
16
17
|
.thredded--pending-moderation .thredded--moderation-navigation--pending,
|
@@ -1,4 +1,6 @@
|
|
1
1
|
.thredded--navigation {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
2
4
|
position: relative;
|
3
5
|
.thredded--icon {
|
4
6
|
display: none;
|
@@ -6,7 +8,29 @@
|
|
6
8
|
}
|
7
9
|
|
8
10
|
@include thredded-media-tablet-and-down {
|
9
|
-
$icon-nav-item-
|
11
|
+
$icon-nav-item-gutter: 0.5rem;
|
12
|
+
$icon-nav-item-width: (2.125rem + $icon-nav-item-gutter);
|
13
|
+
%icon-nav-item {
|
14
|
+
box-sizing: border-box;
|
15
|
+
margin: 0 0 0 $icon-nav-item-gutter;
|
16
|
+
padding: 0;
|
17
|
+
vertical-align: top;
|
18
|
+
a {
|
19
|
+
position: relative;
|
20
|
+
display: block;
|
21
|
+
padding: 0.4375rem 0 0.375rem 0;
|
22
|
+
}
|
23
|
+
.thredded--icon {
|
24
|
+
display: block;
|
25
|
+
width: 2rem;
|
26
|
+
height: 2rem;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
%icon-counter {
|
30
|
+
bottom: 0.3125rem;
|
31
|
+
position: absolute;
|
32
|
+
right: -0.1875rem;
|
33
|
+
}
|
10
34
|
.thredded--navigation {
|
11
35
|
position: relative;
|
12
36
|
width: 100%;
|
@@ -17,11 +41,18 @@
|
|
17
41
|
}
|
18
42
|
.thredded--navigation-breadcrumbs {
|
19
43
|
font-size: $thredded-font-size-small;
|
20
|
-
padding-right: $icon-nav-item-width *
|
21
|
-
.thredded--
|
44
|
+
padding-right: $icon-nav-item-width * 1;
|
45
|
+
.thredded--global-nav-icons-1 & {
|
46
|
+
padding-right: $icon-nav-item-width * 2;
|
47
|
+
}
|
48
|
+
.thredded--global-nav-icons-2 & {
|
22
49
|
padding-right: $icon-nav-item-width * 3;
|
23
50
|
}
|
51
|
+
.thredded--global-nav-icons-3 & {
|
52
|
+
padding-right: $icon-nav-item-width * 4;
|
53
|
+
}
|
24
54
|
}
|
55
|
+
|
25
56
|
.thredded--navigation--search-topics {
|
26
57
|
display: none;
|
27
58
|
.thredded--messageboards-index &,
|
@@ -29,6 +60,7 @@
|
|
29
60
|
.thredded--topic-search-results & {
|
30
61
|
@media screen {
|
31
62
|
display: block;
|
63
|
+
width: 100%;
|
32
64
|
}
|
33
65
|
}
|
34
66
|
}
|
@@ -42,37 +74,22 @@
|
|
42
74
|
display: block;
|
43
75
|
margin-bottom: 0;
|
44
76
|
}
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
margin: 0 0 0 ($thredded-small-spacing/2);
|
49
|
-
padding: 0;
|
50
|
-
vertical-align: top;
|
51
|
-
a {
|
52
|
-
position: relative;
|
53
|
-
display: block;
|
54
|
-
padding: 0.4375rem 0 0.375rem 0;
|
77
|
+
&--item {
|
78
|
+
.thredded--nav-text {
|
79
|
+
display: none;
|
55
80
|
}
|
56
|
-
.thredded--icon {
|
57
|
-
display: block;
|
58
|
-
width: 2rem;
|
59
|
-
height: 2rem;
|
60
|
-
}
|
61
|
-
}
|
62
|
-
%icon-counter {
|
63
|
-
bottom: 0.3125rem;
|
64
|
-
position: absolute;
|
65
|
-
right: -0.1875rem;
|
66
81
|
}
|
67
|
-
|
68
|
-
|
82
|
+
&--unread-topics {
|
83
|
+
@extend %icon-nav-item;
|
84
|
+
&--followed-count {
|
85
|
+
@extend %icon-counter;
|
86
|
+
}
|
69
87
|
}
|
70
88
|
&--settings {
|
71
89
|
@extend %icon-nav-item;
|
72
90
|
}
|
73
91
|
&--private-topics {
|
74
92
|
@extend %icon-nav-item;
|
75
|
-
margin-top: 1px;
|
76
93
|
&--unread {
|
77
94
|
@extend %icon-counter;
|
78
95
|
}
|
@@ -83,5 +100,23 @@
|
|
83
100
|
@extend %icon-counter
|
84
101
|
}
|
85
102
|
}
|
103
|
+
&--moderation.thredded--is-current ~ &--settings,
|
104
|
+
&--moderation.thredded--is-current ~ &--private-topics {
|
105
|
+
display: none;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
.thredded--scoped-navigation {
|
109
|
+
position: absolute;
|
110
|
+
top: 0;
|
111
|
+
right: 0;
|
112
|
+
.thredded--global-nav-icons-1 & {
|
113
|
+
right: $icon-nav-item-width;
|
114
|
+
}
|
115
|
+
.thredded--global-nav-icons-2 & {
|
116
|
+
right: $icon-nav-item-width * 2;
|
117
|
+
}
|
118
|
+
.thredded--global-nav-icons-3 & {
|
119
|
+
right: $icon-nav-item-width * 3;
|
120
|
+
}
|
86
121
|
}
|
87
122
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
.thredded--user-navigation {
|
2
2
|
@extend %thredded--nav-tabs;
|
3
|
-
|
3
|
+
display: flex;
|
4
|
+
justify-content: flex-end;
|
4
5
|
@media print {
|
5
6
|
display: none;
|
6
7
|
}
|
@@ -15,6 +16,7 @@
|
|
15
16
|
}
|
16
17
|
|
17
18
|
.thredded--user-navigation--private-topics--unread,
|
18
|
-
.thredded--user-navigation--moderation--pending-count
|
19
|
+
.thredded--user-navigation--moderation--pending-count,
|
20
|
+
.thredded--user-navigation--unread-topics--followed-count {
|
19
21
|
@extend %thredded--nav-tabs--item--badge;
|
20
22
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thredded
|
4
|
-
class ApplicationController < ::ApplicationController
|
4
|
+
class ApplicationController < ::ApplicationController # rubocop:disable Metrics/ClassLength
|
5
5
|
layout :thredded_layout
|
6
6
|
include ::Thredded::UrlsHelper
|
7
7
|
include Pundit
|
@@ -12,6 +12,9 @@ module Thredded
|
|
12
12
|
:thredded_current_user,
|
13
13
|
:messageboard,
|
14
14
|
:messageboard_or_nil,
|
15
|
+
:unread_private_topics_count,
|
16
|
+
:unread_followed_topics_count,
|
17
|
+
:unread_topics_count,
|
15
18
|
:preferences,
|
16
19
|
:thredded_signed_in?
|
17
20
|
|
@@ -124,6 +127,54 @@ module Thredded
|
|
124
127
|
nil
|
125
128
|
end
|
126
129
|
|
130
|
+
def in_messageboard?
|
131
|
+
params.key?(:messageboard_id)
|
132
|
+
end
|
133
|
+
|
134
|
+
# @return [ActiveRecord::Relation]
|
135
|
+
def topics_scope
|
136
|
+
@topics_scope ||=
|
137
|
+
if in_messageboard?
|
138
|
+
policy_scope(messageboard.topics)
|
139
|
+
else
|
140
|
+
policy_scope(Thredded::Topic.all).joins(:messageboard).merge(policy_scope(Thredded::Messageboard.all))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def unread_private_topics_count
|
145
|
+
@unread_private_topics_count ||=
|
146
|
+
if thredded_signed_in?
|
147
|
+
Thredded::PrivateTopic
|
148
|
+
.for_user(thredded_current_user)
|
149
|
+
.unread(thredded_current_user)
|
150
|
+
.count
|
151
|
+
else
|
152
|
+
0
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def unread_followed_topics_count
|
157
|
+
@unread_followed_topics_count ||=
|
158
|
+
if thredded_signed_in?
|
159
|
+
scope = topics_scope
|
160
|
+
scope = topics_scope.where(messageboard_id: messageboard.id) if in_messageboard?
|
161
|
+
scope.unread_followed_by(thredded_current_user).count
|
162
|
+
else
|
163
|
+
0
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def unread_topics_count
|
168
|
+
@unread_topics_count ||=
|
169
|
+
if thredded_signed_in?
|
170
|
+
scope = topics_scope
|
171
|
+
scope = topics_scope.where(messageboard_id: messageboard.id) if in_messageboard?
|
172
|
+
scope.unread(thredded_current_user).count
|
173
|
+
else
|
174
|
+
0
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
127
178
|
def preferences
|
128
179
|
@preferences ||= thredded_current_user.thredded_user_preference
|
129
180
|
end
|
@@ -6,67 +6,42 @@ module Thredded
|
|
6
6
|
include Thredded::NewPostParams
|
7
7
|
|
8
8
|
before_action :thredded_require_login!,
|
9
|
-
only: %i[edit new update create destroy follow unfollow]
|
9
|
+
only: %i[edit new update create destroy follow unfollow unread]
|
10
|
+
|
11
|
+
before_action :verify_messageboard,
|
12
|
+
only: %i[index search unread]
|
10
13
|
|
11
14
|
before_action :use_topic_messageboard,
|
12
15
|
only: %i[show edit update destroy follow unfollow]
|
13
16
|
|
14
17
|
after_action :update_user_activity
|
15
18
|
|
16
|
-
after_action :verify_authorized, except: %i[search]
|
19
|
+
after_action :verify_authorized, except: %i[search unread]
|
17
20
|
after_action :verify_policy_scoped, except: %i[show new create edit update destroy follow unfollow]
|
18
21
|
|
19
22
|
def index
|
20
|
-
authorize_reading messageboard
|
21
|
-
unless params_match?(canonical_messageboard_params)
|
22
|
-
skip_policy_scope
|
23
|
-
return redirect_to(canonical_messageboard_params)
|
24
|
-
end
|
25
|
-
|
26
23
|
page_scope = policy_scope(messageboard.topics)
|
27
24
|
.order_sticky_first.order_recently_posted_first
|
25
|
+
.includes(:categories, :last_user, :user)
|
28
26
|
.page(current_page)
|
29
27
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
30
28
|
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
31
|
-
|
32
|
-
@new_topic = form if policy(form.topic).create?
|
33
|
-
end
|
29
|
+
@new_topic = init_new_topic
|
34
30
|
end
|
35
31
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
.
|
41
|
-
.includes(:user, :messageboard, :postable)
|
32
|
+
def unread
|
33
|
+
page_scope = topics_scope
|
34
|
+
.unread(thredded_current_user)
|
35
|
+
.order_followed_first(thredded_current_user).order_recently_posted_first
|
36
|
+
.includes(:categories, :last_user, :user)
|
42
37
|
.page(current_page)
|
43
38
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
44
|
-
@
|
45
|
-
|
46
|
-
if thredded_signed_in?
|
47
|
-
Thredded::UserTopicReadState.touch!(thredded_current_user.id, topic.id, page_scope.last)
|
48
|
-
end
|
49
|
-
|
50
|
-
@new_post = Thredded::PostForm.new(user: thredded_current_user, topic: topic, post_params: new_post_params)
|
39
|
+
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
40
|
+
@new_topic = init_new_topic
|
51
41
|
end
|
52
42
|
|
53
43
|
def search
|
54
|
-
in_messageboard = params.key?(:messageboard_id)
|
55
|
-
if in_messageboard
|
56
|
-
authorize_reading messageboard
|
57
|
-
unless params_match?(canonical_messageboard_params)
|
58
|
-
skip_policy_scope
|
59
|
-
return redirect_to(canonical_messageboard_params)
|
60
|
-
end
|
61
|
-
end
|
62
44
|
@query = params[:q].to_s
|
63
|
-
topics_scope = policy_scope(
|
64
|
-
if in_messageboard
|
65
|
-
messageboard.topics
|
66
|
-
else
|
67
|
-
Thredded::Topic.where(messageboard_id: policy_scope(Thredded::Messageboard.all).pluck(:id))
|
68
|
-
end
|
69
|
-
)
|
70
45
|
page_scope = topics_scope
|
71
46
|
.search_query(@query)
|
72
47
|
.order_recently_posted_first
|
@@ -76,6 +51,19 @@ module Thredded
|
|
76
51
|
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
77
52
|
end
|
78
53
|
|
54
|
+
def show
|
55
|
+
authorize topic, :read?
|
56
|
+
return redirect_to(canonical_topic_params) unless params_match?(canonical_topic_params)
|
57
|
+
page_scope = policy_scope(topic.posts)
|
58
|
+
.order_oldest_first
|
59
|
+
.includes(:user, :messageboard, :postable)
|
60
|
+
.page(current_page)
|
61
|
+
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
62
|
+
@posts = Thredded::TopicPostsPageView.new(thredded_current_user, topic, page_scope)
|
63
|
+
Thredded::UserTopicReadState.touch!(thredded_current_user.id, topic.id, page_scope.last) if thredded_signed_in?
|
64
|
+
@new_post = Thredded::PostForm.new(user: thredded_current_user, topic: topic, post_params: new_post_params)
|
65
|
+
end
|
66
|
+
|
79
67
|
def new
|
80
68
|
@new_topic = Thredded::TopicForm.new(new_topic_params)
|
81
69
|
authorize_creating @new_topic.topic
|
@@ -153,6 +141,20 @@ module Thredded
|
|
153
141
|
|
154
142
|
private
|
155
143
|
|
144
|
+
def init_new_topic
|
145
|
+
return unless in_messageboard?
|
146
|
+
form = Thredded::TopicForm.new(messageboard: messageboard, user: thredded_current_user)
|
147
|
+
form if policy(form.topic).create?
|
148
|
+
end
|
149
|
+
|
150
|
+
def verify_messageboard
|
151
|
+
return unless in_messageboard?
|
152
|
+
authorize_reading messageboard
|
153
|
+
return if params_match?(canonical_messageboard_params)
|
154
|
+
skip_policy_scope
|
155
|
+
redirect_to(canonical_messageboard_params)
|
156
|
+
end
|
157
|
+
|
156
158
|
def canonical_messageboard_params
|
157
159
|
{ messageboard_id: messageboard.slug }
|
158
160
|
end
|
@@ -20,9 +20,20 @@ module Thredded
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def thredded_container_classes
|
23
|
-
[
|
24
|
-
|
25
|
-
|
23
|
+
[
|
24
|
+
'thredded--main-container',
|
25
|
+
content_for(:thredded_page_id),
|
26
|
+
"thredded--global-nav-icons-#{global_nav_icons_count}",
|
27
|
+
('thredded--is-moderator' unless moderatable_messageboards_ids.empty?),
|
28
|
+
('thredded--private-messaging-enabled' if Thredded.private_messaging_enabled),
|
29
|
+
].compact
|
30
|
+
end
|
31
|
+
|
32
|
+
def global_nav_icons_count
|
33
|
+
result = 1 # Notification Settings
|
34
|
+
result += 1 if Thredded.private_messaging_enabled
|
35
|
+
result += 1 if moderatable_messageboards_ids.present?
|
36
|
+
result
|
26
37
|
end
|
27
38
|
|
28
39
|
# Render the page container with the supplied block as content.
|
@@ -104,18 +115,6 @@ module Thredded
|
|
104
115
|
end
|
105
116
|
end
|
106
117
|
|
107
|
-
def unread_private_topics_count
|
108
|
-
@unread_private_topics_count ||=
|
109
|
-
if thredded_signed_in?
|
110
|
-
Thredded::PrivateTopic
|
111
|
-
.for_user(thredded_current_user)
|
112
|
-
.unread(thredded_current_user)
|
113
|
-
.count
|
114
|
-
else
|
115
|
-
0
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
118
|
def moderatable_messageboards_ids
|
120
119
|
@moderatable_messageboards_ids ||=
|
121
120
|
thredded_current_user.thredded_can_moderate_messageboards.pluck(:id)
|
@@ -27,6 +27,14 @@ module Thredded
|
|
27
27
|
]
|
28
28
|
)
|
29
29
|
|
30
|
+
USER_NAV_UNREAD_TOPICS = Set.new(
|
31
|
+
%w[thredded--unread-topics]
|
32
|
+
)
|
33
|
+
|
34
|
+
def current_page_unread_topics?
|
35
|
+
USER_NAV_UNREAD_TOPICS.include?(content_for(:thredded_page_id))
|
36
|
+
end
|
37
|
+
|
30
38
|
def current_page_preferences?
|
31
39
|
USER_NAV_PREFERENCES_PAGES.include?(content_for(:thredded_page_id))
|
32
40
|
end
|
@@ -38,5 +46,9 @@ module Thredded
|
|
38
46
|
def current_page_private_topics?
|
39
47
|
USER_NAV_PRIVATE_TOPICS_PAGES.include?(content_for(:thredded_page_id))
|
40
48
|
end
|
49
|
+
|
50
|
+
def nav_back_path(messageboard = nil)
|
51
|
+
messageboard ? messageboard_topics_path(messageboard) : messageboards_path
|
52
|
+
end
|
41
53
|
end
|
42
54
|
end
|
@@ -95,6 +95,17 @@ module Thredded
|
|
95
95
|
edit_preferences_url(messageboard, params.merge(only_path: true))
|
96
96
|
end
|
97
97
|
|
98
|
+
# @param [Thredded::Messageboard, nil] messageboard
|
99
|
+
# @param [Hash] params additional params
|
100
|
+
def unread_topics_path(messageboard: nil, **params)
|
101
|
+
params[:only_path] = true
|
102
|
+
if messageboard
|
103
|
+
unread_messageboard_topics_url(messageboard, params)
|
104
|
+
else
|
105
|
+
unread_topics_url(params)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
98
109
|
# @param messageboard [Thredded::Messageboard, nil]
|
99
110
|
# @return [String] the path to the global or messageboard search.
|
100
111
|
def search_path(messageboard = nil)
|
@@ -14,6 +14,13 @@ module Thredded
|
|
14
14
|
scope :search_query, ->(query) { ::Thredded::TopicsSearch.new(query, self).search }
|
15
15
|
|
16
16
|
scope :order_sticky_first, -> { order(sticky: :desc) }
|
17
|
+
scope :order_followed_first, lambda { |user|
|
18
|
+
user_follows = UserTopicFollow.arel_table
|
19
|
+
joins(arel_table.join(user_follows, Arel::Nodes::OuterJoin)
|
20
|
+
.on(user_follows[:topic_id].eq(arel_table[:id])
|
21
|
+
.and(user_follows[:user_id].eq(user.id))).join_sources)
|
22
|
+
.order(Arel::Nodes::Ascending.new(user_follows[:id].eq(nil)))
|
23
|
+
}
|
17
24
|
|
18
25
|
scope :followed_by, lambda { |user|
|
19
26
|
joins(:user_follows)
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<ul class="thredded--form-list on-top">
|
12
12
|
<li class="title">
|
13
13
|
<%= form.label :title, t('thredded.private_topics.form.title_label') %>
|
14
|
-
<%= form.text_field :title, placeholder: placeholder, required: true %>
|
14
|
+
<%= form.text_field :title, placeholder: placeholder, required: true, autocomplete: 'off' %>
|
15
15
|
<%= render 'thredded/shared/field_errors', messages: form.object.errors[:title] if form.object.errors.include?(:title) %>
|
16
16
|
</li>
|
17
17
|
<li>
|
@@ -12,8 +12,13 @@
|
|
12
12
|
<%= yield :thredded_main_navigation %>
|
13
13
|
<% else %>
|
14
14
|
<div class="thredded--main-navigation">
|
15
|
+
<%# Navigation scoped to the current messageboard if any. %>
|
15
16
|
<%= yield :thredded_breadcrumbs %>
|
16
17
|
<%= render 'thredded/search/form', messageboard: messageboard_or_nil %>
|
18
|
+
<div class="thredded--spacer"></div>
|
19
|
+
<div class="thredded--scoped-navigation">
|
20
|
+
<%= render 'thredded/shared/nav/unread_topics', messageboard: messageboard_or_nil %>
|
21
|
+
</div>
|
17
22
|
</div>
|
18
23
|
<% end %>
|
19
24
|
</nav>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% if moderatable_messageboards_ids.present? %>
|
2
2
|
<% current = current_page_moderation? %>
|
3
3
|
<li class="thredded--user-navigation--item thredded--user-navigation--moderation<%= ' thredded--is-current' if current %>">
|
4
|
-
<%= link_to
|
4
|
+
<%= link_to current ? nav_back_path : pending_moderation_path, rel: 'nofollow' do %>
|
5
5
|
<%= inline_svg 'thredded/moderation.svg',
|
6
6
|
class: 'thredded--icon',
|
7
7
|
title: t('thredded.nav.moderation') %>
|
@@ -1,7 +1,6 @@
|
|
1
1
|
<% current = current_page_preferences? %>
|
2
2
|
<li class="thredded--user-navigation--settings thredded--user-navigation--item<%= ' thredded--is-current' if current %>">
|
3
|
-
<%= link_to current ? (messageboard
|
4
|
-
: edit_preferences_path(messageboard), rel: 'nofollow' do %>
|
3
|
+
<%= link_to current ? nav_back_path(messageboard) : edit_preferences_path(messageboard), rel: 'nofollow' do %>
|
5
4
|
<%= inline_svg 'thredded/settings.svg', class: 'thredded--icon', title: t('thredded.nav.settings') %>
|
6
5
|
<span class="thredded--nav-text"><%= t('thredded.nav.settings') %></span>
|
7
6
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% current = current_page_private_topics? %>
|
2
2
|
<li class="thredded--user-navigation--item thredded--user-navigation--private-topics<%= ' thredded--is-current' if current %>">
|
3
|
-
<%= link_to
|
3
|
+
<%= link_to current ? nav_back_path : private_topics_path, rel: 'nofollow' do %>
|
4
4
|
<%= inline_svg 'thredded/private-messages.svg',
|
5
5
|
class: 'thredded--icon',
|
6
6
|
title: t('thredded.nav.private_topics') %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% current = current_page_unread_topics? %>
|
2
|
+
<% if unread_topics_count > 0 || current %>
|
3
|
+
<li class="thredded--user-navigation--unread-topics thredded--user-navigation--item<%= ' thredded--is-current' if current %>">
|
4
|
+
<%= link_to current ? nav_back_path(messageboard) : unread_topics_path(messageboard: messageboard), rel: 'nofollow' do %>
|
5
|
+
<%= inline_svg 'thredded/follow.svg', class: 'thredded--icon' %>
|
6
|
+
<span class="thredded--nav-text"><%= t('thredded.nav.unread_topics') %></span>
|
7
|
+
<% if unread_followed_topics_count > 0 -%>
|
8
|
+
<span class="thredded--user-navigation--unread-topics--followed-count"><%= unread_followed_topics_count %></span>
|
9
|
+
<% end -%>
|
10
|
+
<% end %>
|
11
|
+
</li>
|
12
|
+
<% end %>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
<ul class="thredded--form-list on-top">
|
10
10
|
<li class="title">
|
11
11
|
<%= form.label :title, t('thredded.topics.form.title_label') %>
|
12
|
-
<%= form.text_field :title, placeholder: placeholder, required: true %>
|
12
|
+
<%= form.text_field :title, placeholder: placeholder, required: true, autocomplete: 'off' %>
|
13
13
|
<%= render 'thredded/shared/field_errors', messages: form.object.errors[:title] if form.object.errors.include?(:title) %>
|
14
14
|
</li>
|
15
15
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
|
4
4
|
|
5
5
|
<%= thredded_page do %>
|
6
|
-
<div class="thredded--svg-definitions
|
6
|
+
<div class="thredded--svg-definitions">
|
7
7
|
<%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
|
8
8
|
<%= inline_svg 'thredded/unfollow.svg', id: 'thredded-unfollow-icon' %>
|
9
9
|
</div>
|
@@ -25,11 +25,5 @@
|
|
25
25
|
<%= paginate @topics %>
|
26
26
|
</footer>
|
27
27
|
|
28
|
-
|
29
|
-
<% if policy(messageboard).update? %>
|
30
|
-
<a class="thredded--button" href="<%= edit_messageboard_path(messageboard) %>" rel="nofollow">
|
31
|
-
<%= t('thredded.nav.edit_messageboard') %>
|
32
|
-
</a>
|
33
|
-
<% end %>
|
34
|
-
</div>
|
28
|
+
<%= render 'thredded/messageboards/messageboard_actions', messageboard: messageboard %>
|
35
29
|
<% end %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<% content_for :thredded_page_title,
|
2
|
+
messageboard_or_nil ?
|
3
|
+
t('thredded.unread_topics.page_title_in_messageboard', messageboard: messageboard.name) :
|
4
|
+
t('thredded.unread_topics.page_title') %>
|
5
|
+
<% content_for :thredded_page_id, 'thredded--unread-topics' %>
|
6
|
+
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
|
7
|
+
|
8
|
+
<%= thredded_page do %>
|
9
|
+
<% if @topics.present? %>
|
10
|
+
<div class="thredded--svg-definitions ">
|
11
|
+
<%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
|
12
|
+
<%= inline_svg 'thredded/unfollow.svg', id: 'thredded-unfollow-icon' %>
|
13
|
+
</div>
|
14
|
+
<%= content_tag :section, class: 'thredded--main-section thredded--topics', 'data-thredded-topics' => true do %>
|
15
|
+
<%= render 'thredded/topics/form',
|
16
|
+
topic: @new_topic,
|
17
|
+
css_class: 'thredded--is-compact',
|
18
|
+
placeholder: t('thredded.topics.form.title_placeholder_start') if @new_topic %>
|
19
|
+
<%= render partial: 'thredded/topics/topic',
|
20
|
+
collection: @topics,
|
21
|
+
locals: { topics: @topics } %>
|
22
|
+
<% end %>
|
23
|
+
<footer class="thredded--pagination-bottom">
|
24
|
+
<%= paginate @topics %>
|
25
|
+
</footer>
|
26
|
+
<% else %>
|
27
|
+
<div class="thredded--empty">
|
28
|
+
<h3 class="thredded--empty--title"><%= t 'thredded.unread_topics.empty.title' %></h3>
|
29
|
+
<p><%= t 'thredded.unread_topics.empty.content' %></p>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
<%= render 'thredded/messageboards/messageboard_actions', messageboard: messageboard if messageboard_or_nil %>
|
33
|
+
<% end %>
|
data/config/locales/de.yml
CHANGED
@@ -117,6 +117,7 @@ de:
|
|
117
117
|
moderation_users: Nutzer
|
118
118
|
private_topics: Private Unterhaltungen
|
119
119
|
settings: Benachrichtigungseinstellungen
|
120
|
+
unread_topics: Ungelesen
|
120
121
|
null_user_name: Gelöschte Nutzer
|
121
122
|
posts:
|
122
123
|
delete: Beitrag gelöscht
|
@@ -242,6 +243,12 @@ de:
|
|
242
243
|
unfollow: Nich mehr folgen
|
243
244
|
unfollowed_notice: Du folgst der Diskussion nicht mehr
|
244
245
|
updated_notice: Beitrag aktualisiert
|
246
|
+
unread_topics:
|
247
|
+
empty:
|
248
|
+
content: Du hast alles gelesen, was es gibt. Komm später wieder für mehr!
|
249
|
+
title: Alles gelesen!
|
250
|
+
page_title: Ungelesene Themen
|
251
|
+
page_title_in_messageboard: "%{messageboard}: Ungelesene Themen"
|
245
252
|
users:
|
246
253
|
currently_online: Zurzeit Online
|
247
254
|
last_active_html: Zuletzt aktiv %{time_ago}
|
data/config/locales/en.yml
CHANGED
@@ -116,6 +116,7 @@ en:
|
|
116
116
|
moderation_users: Users
|
117
117
|
private_topics: Private Messages
|
118
118
|
settings: Notification Settings
|
119
|
+
unread_topics: Unread
|
119
120
|
null_user_name: Deleted user
|
120
121
|
posts:
|
121
122
|
delete: Delete Post
|
@@ -238,6 +239,12 @@ en:
|
|
238
239
|
unfollow: Stop following
|
239
240
|
unfollowed_notice: You are no longer following this topic
|
240
241
|
updated_notice: Topic updated
|
242
|
+
unread_topics:
|
243
|
+
empty:
|
244
|
+
content: You've read all there is. Come back later for more!
|
245
|
+
title: All read!
|
246
|
+
page_title: Unread topics
|
247
|
+
page_title_in_messageboard: "%{messageboard}: Unread topics"
|
241
248
|
users:
|
242
249
|
currently_online: Currently Online
|
243
250
|
last_active_html: Last active %{time_ago}
|
data/config/locales/es.yml
CHANGED
@@ -118,6 +118,7 @@ es:
|
|
118
118
|
moderation_users: Usuarios
|
119
119
|
private_topics: Mensajes Privados
|
120
120
|
settings: Ajuste de Notificaciones
|
121
|
+
unread_topics: No leído
|
121
122
|
null_user_name: Usuario eliminado
|
122
123
|
posts:
|
123
124
|
delete: Eliminar Mensaje
|
@@ -242,6 +243,12 @@ es:
|
|
242
243
|
unfollow: Deja de seguir
|
243
244
|
unfollowed_notice: Has dejado de seguir este tema
|
244
245
|
updated_notice: Tema actualizado
|
246
|
+
unread_topics:
|
247
|
+
empty:
|
248
|
+
content: Has leído todo lo que hay. ¡Vuelve más tarde para más!
|
249
|
+
title: "¡Todo leido!"
|
250
|
+
page_title: Temas no leídos
|
251
|
+
page_title_in_messageboard: "%{messageboard}: temas no leídos"
|
245
252
|
users:
|
246
253
|
currently_online: En línea
|
247
254
|
last_active_html: Última vez activo hace %{time_ago}
|
data/config/locales/fr.yml
CHANGED
@@ -116,6 +116,7 @@ fr:
|
|
116
116
|
moderation_users: Utilisateurs
|
117
117
|
private_topics: Messages privés
|
118
118
|
settings: Paramètres de notifications
|
119
|
+
unread_topics: Non lu
|
119
120
|
null_user_name: Utilisateur effacé
|
120
121
|
posts:
|
121
122
|
delete: Supprimer le commentaire
|
@@ -240,6 +241,12 @@ fr:
|
|
240
241
|
unfollow: Arrêter de suivre
|
241
242
|
unfollowed_notice: Vous ne suivez dorénavant plus ce sujet
|
242
243
|
updated_notice: Sujet mis à jour
|
244
|
+
unread_topics:
|
245
|
+
empty:
|
246
|
+
content: Vous avez lu tout ce qu'il y a. Revenez plus tard pour plus!
|
247
|
+
title: Tout lire!
|
248
|
+
page_title: Sujets non lus
|
249
|
+
page_title_in_messageboard: "%{messageboard}: sujets non lus"
|
243
250
|
users:
|
244
251
|
currently_online: En ce moment connecté
|
245
252
|
last_active_html: 'Actif pour la dernière fois : %{time_ago}'
|
data/config/locales/it.yml
CHANGED
@@ -116,6 +116,7 @@ it:
|
|
116
116
|
moderation_users: Utenti
|
117
117
|
private_topics: Messaggi Privati
|
118
118
|
settings: Impostazioni Notifiche
|
119
|
+
unread_topics: Non letto
|
119
120
|
null_user_name: Utente cancellato
|
120
121
|
posts:
|
121
122
|
delete: Cancella messaggio
|
@@ -242,6 +243,12 @@ it:
|
|
242
243
|
unfollow: Non seguire più questa discussione
|
243
244
|
unfollowed_notice: Ora non stai più seguendo questa discussione
|
244
245
|
updated_notice: Discussione aggiornata
|
246
|
+
unread_topics:
|
247
|
+
empty:
|
248
|
+
content: Hai letto tutto quello che c'è. Torna più tardi per di più!
|
249
|
+
title: Tutto letto!
|
250
|
+
page_title: Argomenti non letti
|
251
|
+
page_title_in_messageboard: "%{messageboard}: argomenti non letti"
|
245
252
|
users:
|
246
253
|
currently_online: Attualmente connessi
|
247
254
|
last_active_html: Ultima attività %{time_ago}
|
data/config/locales/pl.yml
CHANGED
@@ -116,6 +116,7 @@ pl:
|
|
116
116
|
moderation_users: Użytkownicy
|
117
117
|
private_topics: Prywatne wiadomości
|
118
118
|
settings: Ustawienia powiadomień
|
119
|
+
unread_topics: Nieprzeczytane
|
119
120
|
null_user_name: Usunięci użytkownicy
|
120
121
|
posts:
|
121
122
|
delete: Usuń post
|
@@ -238,6 +239,12 @@ pl:
|
|
238
239
|
unfollow: Przestań obserwować
|
239
240
|
unfollowed_notice: Przestałeś obserwować ten temat
|
240
241
|
updated_notice: Temat zaktualizowany
|
242
|
+
unread_topics:
|
243
|
+
empty:
|
244
|
+
content: Przeczytałeś wszystko, co istnieje. Przyjdź później po więcej!
|
245
|
+
title: Wszystko przeczytane!
|
246
|
+
page_title: Nieprzeczytane tematy
|
247
|
+
page_title_in_messageboard: "%{messageboard}: Nieprzeczytane tematy"
|
241
248
|
users:
|
242
249
|
currently_online: Aktualnie online
|
243
250
|
last_active_html: Ostatnio aktywny %{time_ago}
|
data/config/locales/pt-BR.yml
CHANGED
@@ -118,6 +118,7 @@ pt-BR:
|
|
118
118
|
moderation_users: Usuários
|
119
119
|
private_topics: Mensagens Privadas
|
120
120
|
settings: Configurações de Notificação
|
121
|
+
unread_topics: Não lida
|
121
122
|
null_user_name: Usuário deletado
|
122
123
|
posts:
|
123
124
|
delete: Remover Post
|
@@ -243,6 +244,12 @@ pt-BR:
|
|
243
244
|
unfollow: Pare de seguir
|
244
245
|
unfollowed_notice: Você não está mais seguindo este tópico
|
245
246
|
updated_notice: Tópico atualizado
|
247
|
+
unread_topics:
|
248
|
+
empty:
|
249
|
+
content: Você leu tudo o que existe. Volte mais tarde para mais!
|
250
|
+
title: Tudo lido!
|
251
|
+
page_title: Tópicos não lidos
|
252
|
+
page_title_in_messageboard: "%{messageboard}: Tópicos não lidos"
|
246
253
|
users:
|
247
254
|
currently_online: Atualmente Online
|
248
255
|
last_active_html: Última %{time_ago} ativa
|
data/config/locales/ru.yml
CHANGED
@@ -114,6 +114,7 @@ ru:
|
|
114
114
|
moderation_users: Пользователи
|
115
115
|
private_topics: Личное
|
116
116
|
settings: Настройки
|
117
|
+
unread_topics: Непрочитанные
|
117
118
|
null_user_name: Пользователь удален
|
118
119
|
posts:
|
119
120
|
delete: Удалить пост
|
@@ -236,6 +237,12 @@ ru:
|
|
236
237
|
unfollow: Не следить за темой
|
237
238
|
unfollowed_notice: Вы не следите за темой
|
238
239
|
updated_notice: Тема обновлена
|
240
|
+
unread_topics:
|
241
|
+
empty:
|
242
|
+
content: Вы все прочитали. Вернитесь позже и может будет еще что-нибудь!
|
243
|
+
title: Все прочитано!
|
244
|
+
page_title: Непрочитанные темы
|
245
|
+
page_title_in_messageboard: "%{messageboard}: непрочитанные темы"
|
239
246
|
users:
|
240
247
|
currently_online: Онлайн
|
241
248
|
last_active_html: Последняя активность %{time_ago}
|
data/config/locales/zh-CN.yml
CHANGED
@@ -111,6 +111,7 @@ zh-CN:
|
|
111
111
|
moderation_users: 用户
|
112
112
|
private_topics: 私人对话
|
113
113
|
settings: 通知设置
|
114
|
+
unread_topics: 未读
|
114
115
|
null_user_name: 删除用户
|
115
116
|
posts:
|
116
117
|
delete: 删除回复
|
@@ -231,6 +232,12 @@ zh-CN:
|
|
231
232
|
unfollow: 取消关注
|
232
233
|
unfollowed_notice: 你不再关注该帖子
|
233
234
|
updated_notice: 帖子已更新
|
235
|
+
unread_topics:
|
236
|
+
empty:
|
237
|
+
content: 你已经读完了。稍后再回来获取更多!
|
238
|
+
title: 全部阅读!
|
239
|
+
page_title: 未读主题
|
240
|
+
page_title_in_messageboard: "%{messageboard}:未读主题"
|
234
241
|
users:
|
235
242
|
currently_online: 目前在线
|
236
243
|
last_active_html: 最后活跃%{time_ago}
|
data/config/routes.rb
CHANGED
@@ -52,6 +52,12 @@ Thredded::Engine.routes.draw do # rubocop:disable Metrics/BlockLength
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
resources :topics, path: '', only: [] do
|
56
|
+
collection do
|
57
|
+
get '/unread', action: :unread, as: :unread
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
55
61
|
resource :preferences, only: %i[edit update], as: :global_preferences
|
56
62
|
resource :messageboard, path: 'messageboards', only: [:new]
|
57
63
|
resources :messageboards, only: %i[edit update]
|
@@ -64,6 +70,7 @@ Thredded::Engine.routes.draw do # rubocop:disable Metrics/BlockLength
|
|
64
70
|
collection do
|
65
71
|
get '(page-:page)', action: :index, as: '', constraints: page_constraint
|
66
72
|
get '/category/:category_id', action: :category, as: :categories
|
73
|
+
get '/unread', action: :unread, as: :unread
|
67
74
|
end
|
68
75
|
member do
|
69
76
|
get '(page-:page)', action: :show, as: '', constraints: page_constraint
|
data/lib/thredded/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thredded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.15.
|
4
|
+
version: 0.15.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-06-
|
12
|
+
date: 2018-06-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pundit
|
@@ -733,6 +733,7 @@ files:
|
|
733
733
|
- app/assets/stylesheets/thredded/layout/_main-navigation.scss
|
734
734
|
- app/assets/stylesheets/thredded/layout/_moderation.scss
|
735
735
|
- app/assets/stylesheets/thredded/layout/_navigation.scss
|
736
|
+
- app/assets/stylesheets/thredded/layout/_scoped-navigation.scss
|
736
737
|
- app/assets/stylesheets/thredded/layout/_search-navigation.scss
|
737
738
|
- app/assets/stylesheets/thredded/layout/_user-navigation.scss
|
738
739
|
- app/assets/stylesheets/thredded/layout/_user.scss
|
@@ -861,6 +862,7 @@ files:
|
|
861
862
|
- app/views/thredded/messageboard_groups/new.html.erb
|
862
863
|
- app/views/thredded/messageboards/_form.html.erb
|
863
864
|
- app/views/thredded/messageboards/_messageboard.html.erb
|
865
|
+
- app/views/thredded/messageboards/_messageboard_actions.html.erb
|
864
866
|
- app/views/thredded/messageboards/_messageboard_meta.html.erb
|
865
867
|
- app/views/thredded/messageboards/edit.html.erb
|
866
868
|
- app/views/thredded/messageboards/index.html.erb
|
@@ -945,6 +947,7 @@ files:
|
|
945
947
|
- app/views/thredded/shared/nav/_private_topics.html.erb
|
946
948
|
- app/views/thredded/shared/nav/_standalone.html.erb
|
947
949
|
- app/views/thredded/shared/nav/_standalone_profile.html.erb
|
950
|
+
- app/views/thredded/shared/nav/_unread_topics.html.erb
|
948
951
|
- app/views/thredded/shared/preview.html.erb
|
949
952
|
- app/views/thredded/theme_previews/_section_title.html.erb
|
950
953
|
- app/views/thredded/theme_previews/show.html.erb
|
@@ -960,6 +963,7 @@ files:
|
|
960
963
|
- app/views/thredded/topics/new.html.erb
|
961
964
|
- app/views/thredded/topics/search.html.erb
|
962
965
|
- app/views/thredded/topics/show.html.erb
|
966
|
+
- app/views/thredded/topics/unread.html.erb
|
963
967
|
- app/views/thredded/users/_link.html.erb
|
964
968
|
- app/views/thredded/users/_post.html.erb
|
965
969
|
- app/views/thredded/users/_posts.html.erb
|