thredded 0.16.0 → 0.16.1
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 +10 -3
- data/app/assets/javascripts/thredded/components/topics.es6 +27 -6
- data/app/assets/javascripts/thredded/components/users_select.es6 +6 -3
- data/app/assets/stylesheets/thredded/base/_variables.scss +4 -1
- data/app/assets/stylesheets/thredded/components/_messageboard.scss +6 -1
- data/app/assets/stylesheets/thredded/components/_topic-header.scss +2 -2
- data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +7 -0
- data/app/controllers/thredded/autocomplete_users_controller.rb +3 -1
- data/app/controllers/thredded/moderation_controller.rb +5 -5
- data/app/controllers/thredded/private_topics_controller.rb +2 -2
- data/app/controllers/thredded/theme_previews_controller.rb +9 -3
- data/app/controllers/thredded/topics_controller.rb +19 -6
- data/app/helpers/thredded/application_helper.rb +1 -0
- data/app/helpers/thredded/icon_helper.rb +45 -0
- data/app/models/concerns/thredded/content_moderation_state.rb +1 -1
- data/app/models/concerns/thredded/topic_common.rb +6 -11
- data/app/models/concerns/thredded/user_topic_read_state_common.rb +5 -0
- data/app/models/thredded/null_user.rb +5 -0
- data/app/models/thredded/null_user_topic_read_state.rb +6 -0
- data/app/models/thredded/private_topic.rb +18 -0
- data/app/models/thredded/topic.rb +20 -6
- data/app/view_models/thredded/base_topic_view.rb +7 -8
- data/app/view_models/thredded/messageboard_group_view.rb +9 -2
- data/app/view_models/thredded/messageboard_view.rb +17 -3
- data/app/view_models/thredded/topic_view.rb +4 -4
- data/app/views/thredded/messageboards/_grid_sizers.html.erb +2 -0
- data/app/views/thredded/messageboards/index.html.erb +2 -4
- data/app/views/thredded/messageboards/messageboard/_meta.html.erb +1 -1
- data/app/views/thredded/messageboards/messageboard/_unread_followed_topics_badge.html.erb +1 -1
- data/app/views/thredded/private_topics/index.html.erb +3 -2
- data/app/views/thredded/shared/nav/_unread_topics.html.erb +3 -2
- data/app/views/thredded/theme_previews/show.html.erb +1 -4
- data/app/views/thredded/topics/_form.html.erb +2 -0
- data/app/views/thredded/topics/_topic.html.erb +11 -8
- data/app/views/thredded/topics/index.html.erb +7 -7
- data/app/views/thredded/topics/unread.html.erb +5 -5
- data/db/migrate/20160329231848_create_thredded.rb +2 -2
- data/lib/generators/thredded/install/templates/initializer.rb +8 -2
- data/lib/thredded/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aab83b50d26733e85b80ff5a6c6373c53ddc48b93ac14de35212bdea46ff3330
|
4
|
+
data.tar.gz: a02d079d68535ed32160d9e2d6299dc96918bbda7c694212441cf51091f367e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15f36babaaacfeeee4afc75863097638c919bb94bd6bd27501e0c4ebddb851bd45af5a664733ec8a823e1d39598f86bfeafe15eceae7d46942459f32d02e04d0
|
7
|
+
data.tar.gz: c6d79b3effb4bd22ba0b4dfe6e434d55ee445c5237b0e00f5d651a400e48d2c3a6c707503bf8f8803e54b170fef6c44f3c7fb5d131c4357aec1b7e5496b0beea
|
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.16.
|
98
|
+
gem 'thredded', '~> 0.16.1'
|
99
99
|
```
|
100
100
|
|
101
101
|
Add the Thredded [initializer] to your parent app by running the install generator.
|
@@ -559,13 +559,20 @@ Rails.application.config.to_prepare do
|
|
559
559
|
Thredded::ApplicationController.module_eval do
|
560
560
|
# Require authentication to access the forums:
|
561
561
|
before_action :thredded_require_login!
|
562
|
+
# NB: in rails 4.2 you will need to change this to:
|
563
|
+
# before_action { thredded_require_login! }
|
562
564
|
|
563
565
|
# You may also want to render a login form after the
|
564
566
|
# "Please sign in first" message:
|
565
567
|
rescue_from Thredded::Errors::LoginRequired do |exception|
|
566
568
|
# Place the code for rendering the login form here, for example:
|
567
|
-
|
568
|
-
|
569
|
+
flash.now[:notice] = exception.message
|
570
|
+
controller = Users::SessionsController.new
|
571
|
+
controller.request = request
|
572
|
+
controller.request.env['devise.mapping'] = Devise.mappings[:user]
|
573
|
+
controller.response = response
|
574
|
+
controller.response_options = { status: :forbidden }
|
575
|
+
controller.process(:new)
|
569
576
|
end
|
570
577
|
end
|
571
578
|
end
|
@@ -10,32 +10,53 @@
|
|
10
10
|
const TOPIC_UNREAD_CLASS = 'thredded--topic-unread';
|
11
11
|
const TOPIC_READ_CLASS = 'thredded--topic-read';
|
12
12
|
const POSTS_COUNT_SELECTOR = '.thredded--topics--posts-count';
|
13
|
-
const POSTS_PER_PAGE = 50;
|
14
13
|
|
15
14
|
function pageNumber(url) {
|
16
15
|
const match = url.match(/\/page-(\d)$/);
|
17
16
|
return match ? +match[1] : 1;
|
18
17
|
}
|
19
18
|
|
20
|
-
function totalPages(numPosts) {
|
21
|
-
return Math.ceil(numPosts /
|
19
|
+
function totalPages(numPosts, postsPerPage) {
|
20
|
+
return Math.ceil(numPosts / postsPerPage);
|
22
21
|
}
|
23
22
|
|
24
|
-
function
|
23
|
+
function getAncestorTag(node, ancestorTagName) {
|
25
24
|
do {
|
26
25
|
node = node.parentNode;
|
27
|
-
} while (node && node.tagName !==
|
26
|
+
} while (node && node.tagName !== ancestorTagName);
|
28
27
|
return node;
|
29
28
|
}
|
30
29
|
|
30
|
+
function getTopicNode(node) {
|
31
|
+
return getAncestorTag(node, 'ARTICLE');
|
32
|
+
}
|
33
|
+
|
34
|
+
function getUnreadNavItem(unreadFollowedCountElement) {
|
35
|
+
return getAncestorTag(unreadFollowedCountElement, 'LI');
|
36
|
+
}
|
37
|
+
|
31
38
|
function initTopicsList(topicsList) {
|
39
|
+
const postsPerPage = +topicsList.getAttribute('data-thredded-topic-posts-per-page') || 25;
|
40
|
+
const isPrivateTopics = topicsList.getAttribute('data-thredded-topics') === 'private';
|
41
|
+
const unreadFollowedCountElement = document.querySelector('[data-unread-followed-count]');
|
32
42
|
topicsList.addEventListener('click', (evt) => {
|
33
43
|
const link = evt.target;
|
34
44
|
if (link.tagName !== 'A' || link.parentNode.tagName !== 'H1') return;
|
35
45
|
const topic = getTopicNode(link);
|
36
|
-
if (pageNumber(link.href) === totalPages(+topic.querySelector(POSTS_COUNT_SELECTOR).textContent)) {
|
46
|
+
if (pageNumber(link.href) === totalPages(+topic.querySelector(POSTS_COUNT_SELECTOR).textContent, postsPerPage)) {
|
47
|
+
if (!isPrivateTopics && unreadFollowedCountElement &&
|
48
|
+
topic.hasAttribute('data-followed') && topic.hasAttribute('data-unread')) {
|
49
|
+
const count = (+unreadFollowedCountElement.textContent) - 1;
|
50
|
+
if (count === 0) {
|
51
|
+
const navItem = getUnreadNavItem(unreadFollowedCountElement);
|
52
|
+
navItem.parentElement.removeChild(navItem);
|
53
|
+
} else {
|
54
|
+
unreadFollowedCountElement.textContent = count.toLocaleString();
|
55
|
+
}
|
56
|
+
}
|
37
57
|
topic.classList.add(TOPIC_READ_CLASS);
|
38
58
|
topic.classList.remove(TOPIC_UNREAD_CLASS);
|
59
|
+
topic.removeAttribute('data-unread');
|
39
60
|
}
|
40
61
|
});
|
41
62
|
}
|
@@ -44,7 +44,7 @@
|
|
44
44
|
current.push(char);
|
45
45
|
}
|
46
46
|
}
|
47
|
-
if (current.length) result.
|
47
|
+
if (current.length) result.current = {name: current.join(''), index: currentIndex};
|
48
48
|
return result;
|
49
49
|
}
|
50
50
|
|
@@ -63,6 +63,9 @@
|
|
63
63
|
maxCount: Thredded.UsersSelect.DROPDOWN_MAX_COUNT,
|
64
64
|
},
|
65
65
|
});
|
66
|
+
textarea.addEventListener('blur', (evt) => {
|
67
|
+
textcomplete.hide();
|
68
|
+
});
|
66
69
|
|
67
70
|
const searchFn = Thredded.UserTextcomplete.searchFn({
|
68
71
|
url: textarea.getAttribute('data-autocomplete-url'),
|
@@ -77,8 +80,8 @@
|
|
77
80
|
index: 0,
|
78
81
|
match: (text) => {
|
79
82
|
const names = parseNames(text);
|
80
|
-
if (names.
|
81
|
-
const {name, index} = names
|
83
|
+
if (names.current) {
|
84
|
+
const {name, index} = names.current;
|
82
85
|
const matchData = [name];
|
83
86
|
matchData.index = index;
|
84
87
|
return matchData;
|
@@ -7,12 +7,15 @@ $thredded-grid-breakpoint-max-widths: (mobile: 34rem, tablet: 48rem) !default;
|
|
7
7
|
$thredded-content-breakout-min-width: 4rem !default;
|
8
8
|
|
9
9
|
// Typography
|
10
|
-
$thredded-base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif !default;
|
10
|
+
$thredded-base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
11
11
|
$thredded-base-font-size: 1rem !default; // 16px
|
12
12
|
$thredded-font-size-small: 0.875rem !default; // 14px
|
13
13
|
$thredded-base-line-height: 1.5 !default;
|
14
14
|
$thredded-heading-font-family: inherit !default;
|
15
15
|
$thredded-heading-line-height: 1.2 !default;
|
16
|
+
$thredded-messageboard-title-font-size: 1.125rem !default;
|
17
|
+
$thredded-topic-header-font-size: 1.25rem !default;
|
18
|
+
$thredded-topic-header-font-size-tablet-and-up: 1.5rem !default;
|
16
19
|
|
17
20
|
// Spacings
|
18
21
|
$thredded-large-spacing: $thredded-base-line-height * 2rem !default;
|
@@ -29,9 +29,9 @@
|
|
29
29
|
|
30
30
|
.thredded--messageboard--title {
|
31
31
|
@extend %thredded--heading;
|
32
|
+
font-size: $thredded-messageboard-title-font-size;
|
32
33
|
display: inline-block;
|
33
34
|
float: left;
|
34
|
-
font-size: 1.125rem; // 18px
|
35
35
|
line-height: 1.2;
|
36
36
|
vertical-align: baseline;
|
37
37
|
}
|
@@ -157,6 +157,11 @@
|
|
157
157
|
}
|
158
158
|
}
|
159
159
|
|
160
|
+
// A helper class for sizing incomplete rows with more than two missing items.
|
161
|
+
.thredded--grid-sizer {
|
162
|
+
@extend %thredded--messageboards-cell-flex;
|
163
|
+
}
|
164
|
+
|
160
165
|
.thredded--messageboard {
|
161
166
|
@extend %thredded--messageboards-cell-flex;
|
162
167
|
margin-top: $margin-y;
|
@@ -10,11 +10,11 @@
|
|
10
10
|
|
11
11
|
.thredded--topic-header--title {
|
12
12
|
@extend %thredded--heading;
|
13
|
-
font-size:
|
13
|
+
font-size: $thredded-topic-header-font-size;
|
14
14
|
line-height: 1.2;
|
15
15
|
margin-bottom: $thredded-small-spacing / 2;
|
16
16
|
@include thredded-media-tablet-and-up {
|
17
|
-
font-size:
|
17
|
+
font-size: $thredded-topic-header-font-size-tablet-and-up;
|
18
18
|
}
|
19
19
|
}
|
20
20
|
|
@@ -28,8 +28,10 @@ module Thredded
|
|
28
28
|
def users_by_prefix
|
29
29
|
query = params[:q].to_s.strip
|
30
30
|
if query.length >= Thredded.autocomplete_min_length
|
31
|
-
DbTextSearch::CaseInsensitive.new(users_scope, Thredded.user_name_column)
|
31
|
+
case_insensitive = DbTextSearch::CaseInsensitive.new(users_scope, Thredded.user_name_column)
|
32
|
+
case_insensitive.prefix(query)
|
32
33
|
.where.not(id: thredded_current_user.id)
|
34
|
+
.order(case_insensitive.column_for_order(:asc))
|
33
35
|
.limit(MAX_RESULTS)
|
34
36
|
else
|
35
37
|
[]
|
@@ -12,7 +12,7 @@ module Thredded
|
|
12
12
|
.pending_moderation
|
13
13
|
.order_oldest_first
|
14
14
|
.preload(:user, :postable)
|
15
|
-
.
|
15
|
+
.send(Kaminari.config.page_method_name, current_page)
|
16
16
|
)
|
17
17
|
maybe_set_last_moderated_record_flash
|
18
18
|
end
|
@@ -20,7 +20,7 @@ module Thredded
|
|
20
20
|
def history
|
21
21
|
@post_moderation_records = accessible_post_moderation_records
|
22
22
|
.order(created_at: :desc)
|
23
|
-
.
|
23
|
+
.send(Kaminari.config.page_method_name, current_page)
|
24
24
|
end
|
25
25
|
|
26
26
|
def activity
|
@@ -29,7 +29,7 @@ module Thredded
|
|
29
29
|
moderatable_posts
|
30
30
|
.order_newest_first
|
31
31
|
.preload(:user, :postable, :messageboard)
|
32
|
-
.
|
32
|
+
.send(Kaminari.config.page_method_name, current_page)
|
33
33
|
)
|
34
34
|
maybe_set_last_moderated_record_flash
|
35
35
|
end
|
@@ -63,7 +63,7 @@ module Thredded
|
|
63
63
|
)
|
64
64
|
@query = params[:q].to_s
|
65
65
|
@users = DbTextSearch::CaseInsensitive.new(@users, Thredded.user_name_column).prefix(@query) if @query.present?
|
66
|
-
@users = @users.
|
66
|
+
@users = @users.send(Kaminari.config.page_method_name, current_page)
|
67
67
|
end
|
68
68
|
|
69
69
|
def user
|
@@ -73,7 +73,7 @@ module Thredded
|
|
73
73
|
.where(messageboard_id: policy_scope(Messageboard.all).pluck(:id))
|
74
74
|
.order_newest_first
|
75
75
|
.includes(:postable)
|
76
|
-
.
|
76
|
+
.send(Kaminari.config.page_method_name, current_page)
|
77
77
|
@posts = Thredded::PostsPageView.new(thredded_current_user, posts_scope)
|
78
78
|
end
|
79
79
|
|
@@ -12,7 +12,7 @@ module Thredded
|
|
12
12
|
.distinct
|
13
13
|
.for_user(thredded_current_user)
|
14
14
|
.order_recently_posted_first
|
15
|
-
.
|
15
|
+
.send(Kaminari.config.page_method_name, params[:page])
|
16
16
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
17
17
|
@private_topics = Thredded::PrivateTopicsPageView.new(thredded_current_user, page_scope)
|
18
18
|
|
@@ -29,7 +29,7 @@ module Thredded
|
|
29
29
|
.posts
|
30
30
|
.includes(:user)
|
31
31
|
.order_oldest_first
|
32
|
-
.
|
32
|
+
.send(Kaminari.config.page_method_name, current_page)
|
33
33
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
34
34
|
@posts = Thredded::TopicPostsPageView.new(thredded_current_user, private_topic, page_scope)
|
35
35
|
Thredded::UserPrivateTopicReadState.touch!(thredded_current_user.id, page_scope.last) if thredded_signed_in?
|
@@ -15,11 +15,15 @@ module Thredded
|
|
15
15
|
Thredded::MessageboardView.new(Thredded::Messageboard.first(2)[-1], unread_topics_count: 2),
|
16
16
|
Thredded::MessageboardView.new(Thredded::Messageboard.first(3)[-1]),
|
17
17
|
]
|
18
|
-
@topics = Thredded::TopicsPageView.new(@user, @messageboard.topics
|
18
|
+
@topics = Thredded::TopicsPageView.new(@user, @messageboard.topics
|
19
|
+
.send(Kaminari.config.page_method_name, 1)
|
20
|
+
.limit(3))
|
19
21
|
@private_topics = Thredded::PrivateTopicsPageView.new(@user, @user.thredded_private_topics.page(1).limit(3))
|
20
22
|
topic = Thredded::Topic.new(messageboard: @messageboard, title: 'Hello', slug: 'hello', user: @user)
|
21
23
|
@topic = Thredded::TopicView.from_user(topic, @user)
|
22
|
-
@posts = Thredded::TopicPostsPageView.new(@user, topic, topic.posts
|
24
|
+
@posts = Thredded::TopicPostsPageView.new(@user, topic, topic.posts
|
25
|
+
.send(Kaminari.config.page_method_name, 1)
|
26
|
+
.limit(3))
|
23
27
|
@post = topic.posts.build(id: 1337, postable: topic, content: 'Hello world', user: @user)
|
24
28
|
@post_form = Thredded::PostForm.for_persisted(@post)
|
25
29
|
@new_post = Thredded::PostForm.new(user: @user, topic: topic)
|
@@ -27,7 +31,9 @@ module Thredded
|
|
27
31
|
@new_private_topic = Thredded::PrivateTopicForm.new(user: @user)
|
28
32
|
private_topic = Thredded::PrivateTopic.new(id: 17, title: 'Hello', user: @user, last_user: @user, users: [@user])
|
29
33
|
@private_topic = Thredded::PrivateTopicView.from_user(private_topic, @user)
|
30
|
-
@private_posts = Thredded::TopicPostsPageView.new(@user, private_topic, private_topic.posts
|
34
|
+
@private_posts = Thredded::TopicPostsPageView.new(@user, private_topic, private_topic.posts
|
35
|
+
.send(Kaminari.config.page_method_name, 1)
|
36
|
+
.limit(3))
|
31
37
|
@private_post = private_topic.posts.build(
|
32
38
|
id: 1337, postable: private_topic, content: 'A private hello world', user: @user
|
33
39
|
)
|
@@ -23,7 +23,7 @@ module Thredded
|
|
23
23
|
page_scope = policy_scope(messageboard.topics)
|
24
24
|
.order_sticky_first.order_recently_posted_first
|
25
25
|
.includes(:categories, :last_user, :user)
|
26
|
-
.
|
26
|
+
.send(Kaminari.config.page_method_name, current_page)
|
27
27
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
28
28
|
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
29
29
|
@new_topic = init_new_topic
|
@@ -34,7 +34,7 @@ module Thredded
|
|
34
34
|
.unread(thredded_current_user)
|
35
35
|
.order_followed_first(thredded_current_user).order_recently_posted_first
|
36
36
|
.includes(:categories, :last_user, :user)
|
37
|
-
.
|
37
|
+
.send(Kaminari.config.page_method_name, current_page)
|
38
38
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
39
39
|
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
40
40
|
@new_topic = init_new_topic
|
@@ -46,7 +46,7 @@ module Thredded
|
|
46
46
|
.search_query(@query)
|
47
47
|
.order_recently_posted_first
|
48
48
|
.includes(:categories, :last_user, :user)
|
49
|
-
.
|
49
|
+
.send(Kaminari.config.page_method_name, current_page)
|
50
50
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
51
51
|
@topics = Thredded::TopicsPageView.new(thredded_current_user, page_scope)
|
52
52
|
end
|
@@ -57,7 +57,7 @@ module Thredded
|
|
57
57
|
page_scope = policy_scope(topic.posts)
|
58
58
|
.order_oldest_first
|
59
59
|
.includes(:user, :messageboard)
|
60
|
-
.
|
60
|
+
.send(Kaminari.config.page_method_name, current_page)
|
61
61
|
return redirect_to(last_page_params(page_scope)) if page_beyond_last?(page_scope)
|
62
62
|
@posts = Thredded::TopicPostsPageView.new(thredded_current_user, topic, page_scope)
|
63
63
|
Thredded::UserTopicReadState.touch!(thredded_current_user.id, page_scope.last) if thredded_signed_in?
|
@@ -79,7 +79,7 @@ module Thredded
|
|
79
79
|
policy_scope(@category.topics)
|
80
80
|
.unstuck
|
81
81
|
.order_recently_posted_first
|
82
|
-
.
|
82
|
+
.send(Kaminari.config.page_method_name, current_page)
|
83
83
|
)
|
84
84
|
render :index
|
85
85
|
end
|
@@ -88,7 +88,7 @@ module Thredded
|
|
88
88
|
@new_topic = Thredded::TopicForm.new(new_topic_params)
|
89
89
|
authorize_creating @new_topic.topic
|
90
90
|
if @new_topic.save
|
91
|
-
redirect_to
|
91
|
+
redirect_to next_page_after_create(params[:next_page])
|
92
92
|
else
|
93
93
|
render :new
|
94
94
|
end
|
@@ -141,6 +141,19 @@ module Thredded
|
|
141
141
|
|
142
142
|
private
|
143
143
|
|
144
|
+
def next_page_after_create(next_page)
|
145
|
+
case next_page
|
146
|
+
when 'messageboard', '', nil
|
147
|
+
return messageboard_topics_path(messageboard)
|
148
|
+
when 'topic'
|
149
|
+
messageboard_topic_path(messageboard, @new_topic.topic)
|
150
|
+
when %r{\A/[^/]\S+\z}
|
151
|
+
next_page
|
152
|
+
else
|
153
|
+
fail "Unexpected value for next page: #{next_page.inspect}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
144
157
|
def in_messageboard?
|
145
158
|
params.key?(:messageboard_id)
|
146
159
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module IconHelper
|
5
|
+
def shared_inline_svg(filename, **args)
|
6
|
+
svg = content_tag :svg, **args do
|
7
|
+
content_tag :use, '', 'xlink:href' => "##{thredded_icon_id(filename)}"
|
8
|
+
end
|
9
|
+
if (definition = define_svg_icons(filename))
|
10
|
+
definition + svg
|
11
|
+
else
|
12
|
+
svg
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_svg_icons(*filenames)
|
17
|
+
return if filenames.blank?
|
18
|
+
sb = filenames.map do |filename|
|
19
|
+
inline_svg_once(filename, id: thredded_icon_id(filename))
|
20
|
+
end
|
21
|
+
return if sb.compact.blank?
|
22
|
+
content_tag :div, safe_join(sb), class: 'thredded--svg-definitions'
|
23
|
+
end
|
24
|
+
|
25
|
+
def inline_svg_once(filename, id:, **transform_params)
|
26
|
+
return if @already_inlined_svg_ids&.include?(id)
|
27
|
+
record_already_inlined_svg(filename, id)
|
28
|
+
inline_svg(filename, id: id, **transform_params)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def record_already_inlined_svg(filename, id)
|
34
|
+
if filename.is_a?(String) # in case it's an IO or other
|
35
|
+
fail "Please use id: #{thredded_icon_id(filename)}" unless id == thredded_icon_id(filename)
|
36
|
+
end
|
37
|
+
@already_inlined_svg_ids ||= []
|
38
|
+
@already_inlined_svg_ids << id
|
39
|
+
end
|
40
|
+
|
41
|
+
def thredded_icon_id(svg_filename)
|
42
|
+
"thredded-#{File.basename(svg_filename, '.svg').dasherize}-icon"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -35,7 +35,7 @@ module Thredded
|
|
35
35
|
|
36
36
|
# Content that the user can moderate.
|
37
37
|
if moderatable_messageboards != Thredded::Messageboard.none
|
38
|
-
result = result.or(messageboard_id: moderatable_messageboards)
|
38
|
+
result = result.or(where(messageboard_id: moderatable_messageboards))
|
39
39
|
end
|
40
40
|
end
|
41
41
|
result
|
@@ -69,17 +69,12 @@ module Thredded
|
|
69
69
|
Thredded::TopicCommon::CachingHash.from_relation(read_states)
|
70
70
|
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
# @
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
return current_scope.zip([null_read_state]) if user.thredded_anonymous?
|
79
|
-
read_states_by_postable = read_states_by_postable_hash(user)
|
80
|
-
current_scope.map do |postable|
|
81
|
-
[postable, read_states_by_postable[postable] || null_read_state]
|
82
|
-
end
|
72
|
+
# @param [Thredded.user_class] user
|
73
|
+
# @param [Array<Number>] topic_ids
|
74
|
+
# @return [Hash{topic ID => posts count}] Counts of posts visible to the given user in the given topics.
|
75
|
+
def post_counts_for_user_and_topics(user, topic_ids)
|
76
|
+
return {} if topic_ids.empty?
|
77
|
+
Pundit.policy_scope!(user, post_class.all).where(postable_id: topic_ids).group(:postable_id).count
|
83
78
|
end
|
84
79
|
end
|
85
80
|
|
@@ -21,6 +21,11 @@ module Thredded
|
|
21
21
|
post.created_at <= read_at
|
22
22
|
end
|
23
23
|
|
24
|
+
# @return [Number]
|
25
|
+
def posts_count
|
26
|
+
read_posts_count + unread_posts_count
|
27
|
+
end
|
28
|
+
|
24
29
|
def calculate_post_counts
|
25
30
|
unread_posts_count, read_posts_count =
|
26
31
|
self.class.visible_posts_scope(user)
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thredded
|
4
|
+
# A Thredded::NullUser stands in place of a real (mainapp supplied) User when:
|
5
|
+
#
|
6
|
+
# * user is not logged in (ie. the thredded_current_user)
|
7
|
+
# * a user that was hard-deleted
|
8
|
+
# (e.g. if a post was made by a user, and then that user is destroyed, the post's user ID is nullified).
|
4
9
|
class NullUser
|
5
10
|
include ::Thredded::UserPermissions::Read::All
|
6
11
|
include ::Thredded::UserPermissions::Write::None
|
@@ -109,6 +109,24 @@ module Thredded
|
|
109
109
|
def post_class
|
110
110
|
Thredded::PrivatePost
|
111
111
|
end
|
112
|
+
|
113
|
+
# @param [Thredded.user_class] user
|
114
|
+
# @return [Array<[PrivateTopic, PrivateUserTopicReadState]>]
|
115
|
+
def with_read_states(user)
|
116
|
+
if user.thredded_anonymous?
|
117
|
+
current_scope.map do |topic|
|
118
|
+
[topic, Thredded::NullUserTopicReadState.new(posts_count: topic.posts_count)]
|
119
|
+
end
|
120
|
+
else
|
121
|
+
read_states_by_postable = read_states_by_postable_hash(user)
|
122
|
+
current_scope.map do |topic|
|
123
|
+
[
|
124
|
+
topic,
|
125
|
+
read_states_by_postable[topic] || Thredded::NullUserTopicReadState.new(posts_count: topic.posts_count)
|
126
|
+
]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
112
130
|
end
|
113
131
|
end
|
114
132
|
end
|
@@ -122,12 +122,26 @@ module Thredded
|
|
122
122
|
# @param user [Thredded.user_class]
|
123
123
|
# @return [Array<[TopicCommon, UserTopicReadStateCommon, UserTopicFollow]>]
|
124
124
|
def with_read_and_follow_states(user)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
125
|
+
topics = current_scope.to_a
|
126
|
+
if user.thredded_anonymous?
|
127
|
+
post_counts = post_counts_for_user_and_topics(user, topics.map(&:id))
|
128
|
+
topics.map do |topic|
|
129
|
+
[topic, Thredded::NullUserTopicReadState.new(posts_count: post_counts[topic.id] || 0), nil]
|
130
|
+
end
|
131
|
+
else
|
132
|
+
read_states_by_topic = read_states_by_postable_hash(user)
|
133
|
+
post_counts = post_counts_for_user_and_topics(
|
134
|
+
user, topics.reject { |topic| read_states_by_topic.key?(topic) }.map(&:id)
|
135
|
+
)
|
136
|
+
follows_by_topic = follows_by_topic_hash(user)
|
137
|
+
current_scope.map do |topic|
|
138
|
+
[
|
139
|
+
topic,
|
140
|
+
read_states_by_topic[topic] ||
|
141
|
+
Thredded::NullUserTopicReadState.new(posts_count: post_counts[topic.id] || 0),
|
142
|
+
follows_by_topic[topic]
|
143
|
+
]
|
144
|
+
end
|
131
145
|
end
|
132
146
|
end
|
133
147
|
end
|
@@ -4,7 +4,6 @@ module Thredded
|
|
4
4
|
# A view model for TopicCommon.
|
5
5
|
class BaseTopicView
|
6
6
|
delegate :title,
|
7
|
-
:posts_count,
|
8
7
|
:last_post_at,
|
9
8
|
:created_at,
|
10
9
|
:user,
|
@@ -12,16 +11,16 @@ module Thredded
|
|
12
11
|
:to_model,
|
13
12
|
to: :@topic
|
14
13
|
|
15
|
-
delegate :read?, :post_read?,
|
14
|
+
delegate :read?, :post_read?, :posts_count,
|
16
15
|
to: :@read_state
|
17
16
|
|
18
|
-
# @param
|
19
|
-
# @param
|
20
|
-
# @param
|
17
|
+
# @param [TopicCommon] topic
|
18
|
+
# @param [UserTopicReadStateCommon, NullUserTopicReadState, nil] read_state
|
19
|
+
# @param [#destroy?] policy
|
21
20
|
def initialize(topic, read_state, policy)
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@policy
|
21
|
+
@topic = topic
|
22
|
+
@read_state = read_state || Thredded::NullUserTopicReadState.new(posts_count: @topic.posts_count)
|
23
|
+
@policy = policy
|
25
24
|
end
|
26
25
|
|
27
26
|
def states
|
@@ -10,22 +10,29 @@ module Thredded
|
|
10
10
|
# @param [Thredded.user_class] user The user viewing the messageboards.
|
11
11
|
# @param [Boolean] with_unread_topics_counts
|
12
12
|
# @return [Array<MessageboardGroupView>]
|
13
|
-
def self.grouped(
|
13
|
+
def self.grouped( # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
|
14
|
+
messageboards_scope, user: Thredded::NullUser.new, with_unread_topics_counts: !user.thredded_anonymous?
|
15
|
+
)
|
14
16
|
scope = messageboards_scope.preload(last_topic: [:last_user])
|
15
17
|
.eager_load(:group)
|
16
18
|
.order(Arel.sql('COALESCE(thredded_messageboard_groups.position, 0) ASC, thredded_messageboard_groups.id ASC'))
|
17
19
|
.ordered
|
20
|
+
topics_scope = Thredded::TopicPolicy::Scope.new(user, Thredded::Topic.all).resolve
|
18
21
|
if with_unread_topics_counts
|
19
|
-
topics_scope = Pundit.policy_scope!(user, Thredded::Topic)
|
20
22
|
unread_topics_counts = messageboards_scope.unread_topics_counts(user: user, topics_scope: topics_scope)
|
21
23
|
unread_followed_topics_counts = messageboards_scope.unread_topics_counts(
|
22
24
|
user: user, topics_scope: topics_scope.followed_by(user)
|
23
25
|
)
|
24
26
|
end
|
27
|
+
topic_counts = topics_scope.group(:messageboard_id).count
|
28
|
+
posts_scope = Thredded::PostPolicy::Scope.new(user, Thredded::Post.all).resolve
|
29
|
+
post_counts = posts_scope.group(:messageboard_id).count
|
25
30
|
scope.group_by(&:group).map do |(group, messageboards)|
|
26
31
|
MessageboardGroupView.new(group, messageboards.map do |messageboard|
|
27
32
|
MessageboardView.new(
|
28
33
|
messageboard,
|
34
|
+
topics_count: topic_counts[messageboard.id] || 0,
|
35
|
+
posts_count: post_counts[messageboard.id] || 0,
|
29
36
|
unread_topics_count: with_unread_topics_counts && unread_topics_counts[messageboard.id] || 0,
|
30
37
|
unread_followed_topics_count:
|
31
38
|
with_unread_topics_counts && unread_followed_topics_counts[messageboard.id] || 0
|
@@ -6,12 +6,16 @@ module Thredded
|
|
6
6
|
delegate :name,
|
7
7
|
:description,
|
8
8
|
:locked?,
|
9
|
-
:topics_count,
|
10
|
-
:posts_count,
|
11
9
|
:last_topic,
|
12
10
|
:last_user,
|
13
11
|
to: :@messageboard
|
14
12
|
|
13
|
+
# @return [Integer]
|
14
|
+
attr_reader :topics_count
|
15
|
+
|
16
|
+
# @return [Integer]
|
17
|
+
attr_reader :posts_count
|
18
|
+
|
15
19
|
# @return [Integer]
|
16
20
|
attr_reader :unread_topics_count
|
17
21
|
|
@@ -19,10 +23,20 @@ module Thredded
|
|
19
23
|
attr_reader :unread_followed_topics_count
|
20
24
|
|
21
25
|
# @param [Thredded::Messageboard] messageboard
|
26
|
+
# @param [Integer] topics_count
|
27
|
+
# @param [Integer] posts_count
|
22
28
|
# @param [Integer] unread_topics_count
|
23
29
|
# @param [Integer] unread_followed_topics_count
|
24
|
-
def initialize(
|
30
|
+
def initialize(
|
31
|
+
messageboard,
|
32
|
+
topics_count: messageboard.topics_count,
|
33
|
+
posts_count: messageboard.posts_count,
|
34
|
+
unread_topics_count: 0,
|
35
|
+
unread_followed_topics_count: 0
|
36
|
+
)
|
25
37
|
@messageboard = messageboard
|
38
|
+
@topics_count = topics_count
|
39
|
+
@posts_count = posts_count
|
26
40
|
@unread_topics_count = unread_topics_count
|
27
41
|
@unread_followed_topics_count = unread_followed_topics_count
|
28
42
|
end
|
@@ -7,9 +7,9 @@ module Thredded
|
|
7
7
|
:last_post, :messageboard_id, :messageboard_name,
|
8
8
|
to: :@topic
|
9
9
|
|
10
|
-
# @param
|
11
|
-
# @param
|
12
|
-
# @param
|
10
|
+
# @param [Topic] topic
|
11
|
+
# @param [UserTopicReadState, NullUserTopicReadState, nil] read_state
|
12
|
+
# @param [#destroy?] policy
|
13
13
|
def initialize(topic, read_state, follow, policy)
|
14
14
|
super(topic, read_state, policy)
|
15
15
|
@follow = follow
|
@@ -34,7 +34,7 @@ module Thredded
|
|
34
34
|
|
35
35
|
# @return [Boolean] whether the topic is followed by the current user.
|
36
36
|
def followed?
|
37
|
-
|
37
|
+
!!@follow # rubocop:disable Style/DoubleNegation
|
38
38
|
end
|
39
39
|
|
40
40
|
def follow_reason
|
@@ -2,10 +2,7 @@
|
|
2
2
|
<% content_for :thredded_page_id, 'thredded--messageboards-index' %>
|
3
3
|
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
|
4
4
|
<%= thredded_page do %>
|
5
|
-
|
6
|
-
<%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
|
7
|
-
<%= inline_svg 'thredded/lock.svg', id: 'thredded-lock-icon', title: nil %>
|
8
|
-
</div>
|
5
|
+
<%= define_svg_icons('thredded/follow.svg', 'thredded/lock.svg') %>
|
9
6
|
<%= view_hooks.messageboards_index.container.render self, groups: @groups do %>
|
10
7
|
<section class="thredded--main-section thredded--messageboards">
|
11
8
|
<%= view_hooks.messageboards_index.list.render self, groups: @groups do %>
|
@@ -18,6 +15,7 @@
|
|
18
15
|
<%= render partial: 'thredded/messageboards/messageboard',
|
19
16
|
collection: group.messageboards %>
|
20
17
|
<% end %>
|
18
|
+
<%= render partial: 'thredded/messageboards/grid_sizers' %>
|
21
19
|
</div>
|
22
20
|
<% end %>
|
23
21
|
<% end %>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% if messageboard.locked? %>
|
3
3
|
<span class="thredded--messageboard--meta--locked"
|
4
4
|
title="<%= t('thredded.messageboard.form.locked_notice') %>">
|
5
|
-
|
5
|
+
<%= shared_inline_svg "thredded/lock.svg", class:"thredded--messageboard--meta--icon", role: "img"%>
|
6
6
|
</span>
|
7
7
|
<% end %>
|
8
8
|
<h3 class="thredded--messageboard--meta--counts">
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% if messageboard.unread_followed_topics? %>
|
2
2
|
<span class="thredded--messageboard--unread-followed-topics-count">
|
3
|
-
|
3
|
+
<%= shared_inline_svg "thredded/follow.svg", class: "thredded--messageboard--unread-followed-icon", role: "img"%>
|
4
4
|
<%= number_with_delimiter messageboard.unread_followed_topics_count %>
|
5
5
|
</span>
|
6
6
|
<% end %>
|
@@ -4,8 +4,9 @@
|
|
4
4
|
|
5
5
|
<%= thredded_page do %>
|
6
6
|
<%= content_tag :section,
|
7
|
-
|
8
|
-
|
7
|
+
class: 'thredded--main-section thredded--private-topics',
|
8
|
+
'data-thredded-topics' => 'private',
|
9
|
+
'data-thredded-topic-posts-per-page' => Thredded.posts_per_page do %>
|
9
10
|
|
10
11
|
<% if @private_topics.empty? -%>
|
11
12
|
<%= render 'thredded/private_topics/no_private_topics' %>
|
@@ -2,10 +2,11 @@
|
|
2
2
|
<% if unread_topics_count > 0 || current %>
|
3
3
|
<li class="thredded--user-navigation--unread-topics thredded--user-navigation--item<%= ' thredded--is-current' if current %>">
|
4
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
5
|
<span class="thredded--nav-text"><%= t('thredded.nav.unread_topics') %></span>
|
7
6
|
<% if unread_followed_topics_count > 0 -%>
|
8
|
-
|
7
|
+
<%= define_svg_icons 'thredded/follow.svg' %>
|
8
|
+
<span class="thredded--user-navigation--unread-topics--followed-count"><%=shared_inline_svg "thredded/follow.svg", class: "thredded--unread-topics--followed-icon", role:"img" %>
|
9
|
+
<span data-unread-followed-count><%= unread_followed_topics_count %></span></span>
|
9
10
|
<% end -%>
|
10
11
|
<% end %>
|
11
12
|
</li>
|
@@ -9,10 +9,7 @@
|
|
9
9
|
<%= thredded_page do %>
|
10
10
|
<%= render 'section_title', label: 'messageboards#index', href: messageboards_path %>
|
11
11
|
<%= content_tag :section, class: 'thredded--thredded--main-section thredded--messageboards' do %>
|
12
|
-
|
13
|
-
<%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
|
14
|
-
<%= inline_svg 'thredded/lock.svg', id: 'thredded-lock-icon', title: nil %>
|
15
|
-
</div>
|
12
|
+
<%= define_svg_icons('thredded/follow.svg', 'thredded/lock.svg') %>
|
16
13
|
<div class="thredded--messageboards-group">
|
17
14
|
<%= render partial: 'thredded/messageboards/messageboard', collection: @messageboard_views %>
|
18
15
|
</div>
|
@@ -7,6 +7,8 @@
|
|
7
7
|
'data-autocomplete-min-length' => Thredded.autocomplete_min_length,
|
8
8
|
'data-thredded-submit-hotkey' => true,
|
9
9
|
} do |form| %>
|
10
|
+
<%= hidden_field_tag("next_page", params[:next_page]) %>
|
11
|
+
|
10
12
|
<ul class="thredded--form-list on-top">
|
11
13
|
<li class="title">
|
12
14
|
<%= form.label :title, t('thredded.topics.form.title_label') %>
|
@@ -1,17 +1,20 @@
|
|
1
1
|
<%= content_tag :article,
|
2
2
|
id: dom_id(topic),
|
3
3
|
class: ['thredded--topics--topic', topic_css_classes(topic)],
|
4
|
-
data: {
|
4
|
+
data: {
|
5
|
+
topic: topic.id,
|
6
|
+
messageboard: topic.messageboard_id,
|
7
|
+
unread: !topic.read? || nil,
|
8
|
+
followed: topic.followed? || nil
|
9
|
+
} do %>
|
5
10
|
<div class="thredded--topics--posts-count"><%= topic.posts_count %></div>
|
6
11
|
|
7
12
|
<div class="thredded--topics--follow-info" title="<%= topic_follow_reason_text topic.follow_reason %>">
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<% end %>
|
14
|
-
</svg>
|
13
|
+
<% if topic.followed? %>
|
14
|
+
<%= shared_inline_svg "thredded/follow.svg", class: "thredded--topics--follow-icon", role: "img" %>
|
15
|
+
<% else %>
|
16
|
+
<%= shared_inline_svg "thredded/unfollow.svg", class: "thredded--topics--follow-icon", role: "img" %>
|
17
|
+
<% end %>
|
15
18
|
</div>
|
16
19
|
|
17
20
|
<h1 class="thredded--topics--title">
|
@@ -3,12 +3,12 @@
|
|
3
3
|
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
|
4
4
|
|
5
5
|
<%= thredded_page do %>
|
6
|
-
|
7
|
-
<%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
|
8
|
-
<%= inline_svg 'thredded/unfollow.svg', id: 'thredded-unfollow-icon' %>
|
9
|
-
</div>
|
6
|
+
<%= define_svg_icons('thredded/follow.svg', 'thredded/unfollow.svg') %>
|
10
7
|
|
11
|
-
<%= content_tag :section,
|
8
|
+
<%= content_tag :section,
|
9
|
+
class: 'thredded--main-section thredded--topics',
|
10
|
+
'data-thredded-topics' => true,
|
11
|
+
'data-thredded-topic-posts-per-page' => Thredded.posts_per_page do %>
|
12
12
|
<%= render 'thredded/topics/form',
|
13
13
|
topic: @new_topic,
|
14
14
|
css_class: 'thredded--is-compact',
|
@@ -16,8 +16,8 @@
|
|
16
16
|
<%= render partial: 'thredded/topics/topic',
|
17
17
|
collection: @topics,
|
18
18
|
locals: {
|
19
|
-
|
20
|
-
|
19
|
+
sticky_topics_divider: true,
|
20
|
+
topics: @topics
|
21
21
|
} %>
|
22
22
|
<% end %>
|
23
23
|
|
@@ -7,11 +7,11 @@
|
|
7
7
|
|
8
8
|
<%= thredded_page do %>
|
9
9
|
<% if @topics.present? %>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
<%= define_svg_icons('thredded/follow.svg', 'thredded/unfollow.svg') %>
|
11
|
+
<%= content_tag :section,
|
12
|
+
class: 'thredded--main-section thredded--topics',
|
13
|
+
'data-thredded-topics' => true,
|
14
|
+
'data-thredded-topic-posts-per-page' => Thredded.posts_per_page do %>
|
15
15
|
<%= render 'thredded/topics/form',
|
16
16
|
topic: @new_topic,
|
17
17
|
css_class: 'thredded--is-compact',
|
@@ -85,7 +85,7 @@ class CreateThredded < Thredded::BaseMigration
|
|
85
85
|
|
86
86
|
create_table :thredded_private_topics do |t|
|
87
87
|
t.references :user, type: user_id_type, index: false
|
88
|
-
t.references :last_user, index: false
|
88
|
+
t.references :last_user, type: user_id_type, index: false
|
89
89
|
t.text :title, null: false
|
90
90
|
t.text :slug, null: false
|
91
91
|
t.integer :posts_count, default: 0
|
@@ -117,7 +117,7 @@ class CreateThredded < Thredded::BaseMigration
|
|
117
117
|
|
118
118
|
create_table :thredded_topics do |t|
|
119
119
|
t.references :user, type: user_id_type, index: false
|
120
|
-
t.references :last_user, index: false
|
120
|
+
t.references :last_user, type: user_id_type, index: false
|
121
121
|
t.text :title, null: false
|
122
122
|
t.text :slug, null: false
|
123
123
|
t.references :messageboard, null: false, index: false
|
@@ -128,9 +128,15 @@ Thredded.layout = 'thredded/application'
|
|
128
128
|
#
|
129
129
|
# Rails.application.config.to_prepare do
|
130
130
|
# Thredded::ApplicationController.module_eval do
|
131
|
+
# # Render sign in page:
|
131
132
|
# rescue_from Thredded::Errors::LoginRequired do |exception|
|
132
|
-
#
|
133
|
-
#
|
133
|
+
# flash.now[:notice] = exception.message
|
134
|
+
# controller = Users::SessionsController.new
|
135
|
+
# controller.request = request
|
136
|
+
# controller.request.env['devise.mapping'] = Devise.mappings[:user]
|
137
|
+
# controller.response = response
|
138
|
+
# controller.response_options = { status: :forbidden }
|
139
|
+
# controller.process(:new)
|
134
140
|
# end
|
135
141
|
# end
|
136
142
|
# end
|
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.16.
|
4
|
+
version: 0.16.1
|
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-10-
|
12
|
+
date: 2018-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: active_record_union
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.3.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.3.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: friendly_id
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -792,6 +792,7 @@ files:
|
|
792
792
|
- app/forms/thredded/topic_form.rb
|
793
793
|
- app/forms/thredded/user_preferences_form.rb
|
794
794
|
- app/helpers/thredded/application_helper.rb
|
795
|
+
- app/helpers/thredded/icon_helper.rb
|
795
796
|
- app/helpers/thredded/nav_helper.rb
|
796
797
|
- app/helpers/thredded/render_helper.rb
|
797
798
|
- app/helpers/thredded/urls_helper.rb
|
@@ -878,6 +879,7 @@ files:
|
|
878
879
|
- app/views/thredded/kaminari/_prev_page.html.erb
|
879
880
|
- app/views/thredded/messageboard_groups/new.html.erb
|
880
881
|
- app/views/thredded/messageboards/_form.html.erb
|
882
|
+
- app/views/thredded/messageboards/_grid_sizers.html.erb
|
881
883
|
- app/views/thredded/messageboards/_messageboard.html.erb
|
882
884
|
- app/views/thredded/messageboards/_messageboard_actions.html.erb
|
883
885
|
- app/views/thredded/messageboards/edit.html.erb
|