thredded 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -5
- data/app/assets/javascripts/thredded/components/post_form.es6 +4 -4
- data/app/assets/javascripts/thredded/components/quote_post.es6 +45 -0
- data/app/assets/javascripts/thredded/components/topic_form.es6 +4 -4
- data/app/assets/javascripts/thredded/core/on_page_load.es6 +8 -0
- data/app/assets/javascripts/thredded/dependencies.js +1 -1
- data/app/assets/stylesheets/thredded/_email.scss +2 -3
- data/app/assets/stylesheets/thredded/components/_preferences.scss +17 -4
- data/app/controllers/concerns/thredded/new_post_params.rb +20 -0
- data/app/controllers/concerns/thredded/new_private_post_params.rb +20 -0
- data/app/controllers/thredded/posts_controller.rb +22 -13
- data/app/controllers/thredded/preferences_controller.rb +1 -0
- data/app/controllers/thredded/private_posts_controller.rb +24 -12
- data/app/controllers/thredded/private_topics_controller.rb +4 -1
- data/app/controllers/thredded/theme_previews_controller.rb +4 -2
- data/app/controllers/thredded/topics_controller.rb +13 -2
- data/app/forms/thredded/post_form.rb +52 -0
- data/app/forms/thredded/private_post_form.rb +48 -0
- data/app/forms/thredded/private_topic_form.rb +8 -0
- data/app/forms/thredded/topic_form.rb +8 -0
- data/app/forms/thredded/user_preferences_form.rb +7 -1
- data/app/helpers/thredded/urls_helper.rb +18 -0
- data/app/models/thredded/topic.rb +3 -3
- data/app/policies/thredded/private_topic_policy.rb +1 -1
- data/app/view_models/thredded/messageboard_group_view.rb +1 -1
- data/app/view_models/thredded/post_view.rb +19 -3
- data/app/view_models/thredded/private_topic_view.rb +0 -4
- data/app/view_models/thredded/topic_view.rb +0 -4
- data/app/views/thredded/posts/_form.html.erb +0 -2
- data/app/views/thredded/posts/edit.html.erb +2 -5
- data/app/views/thredded/posts/new.html.erb +15 -0
- data/app/views/thredded/posts_common/_actions.html.erb +3 -0
- data/app/views/thredded/posts_common/_form.html.erb +5 -3
- data/app/views/thredded/posts_common/_header.html.erb +3 -1
- data/app/views/thredded/posts_common/actions/_quote.html.erb +4 -0
- data/app/views/thredded/preferences/_form.html.erb +3 -5
- data/app/views/thredded/preferences/_messageboards_nav.html.erb +8 -0
- data/app/views/thredded/preferences/_messageboards_nav_item.html.erb +2 -0
- data/app/views/thredded/preferences/edit.html.erb +13 -3
- data/app/views/thredded/private_posts/_form.html.erb +0 -2
- data/app/views/thredded/private_posts/edit.html.erb +2 -4
- data/app/views/thredded/private_posts/new.html.erb +11 -0
- data/app/views/thredded/private_topics/_form.html.erb +2 -2
- data/app/views/thredded/private_topics/index.html.erb +1 -2
- data/app/views/thredded/private_topics/new.html.erb +0 -1
- data/app/views/thredded/private_topics/show.html.erb +5 -3
- data/app/views/thredded/shared/_nav.html.erb +1 -7
- data/app/views/thredded/shared/nav/_standalone.html.erb +3 -3
- data/app/views/thredded/shared/nav/_standalone_profile.html.erb +3 -0
- data/app/views/thredded/theme_previews/show.html.erb +3 -17
- data/app/views/thredded/topics/_form.html.erb +3 -2
- data/app/views/thredded/topics/index.html.erb +0 -2
- data/app/views/thredded/topics/new.html.erb +0 -2
- data/app/views/thredded/topics/show.html.erb +1 -3
- data/config/locales/en.yml +4 -3
- data/config/locales/es.yml +4 -3
- data/config/locales/pl.yml +4 -3
- data/config/locales/pt-BR.yml +4 -3
- data/config/locales/ru.yml +12 -7
- data/config/routes.rb +2 -0
- data/db/migrate/20160329231848_create_thredded.rb +1 -1
- data/db/upgrade_migrations/20170420163138_upgrade_thredded_v0_11_to_v0_12.rb +25 -0
- data/lib/thredded.rb +0 -1
- data/lib/thredded/content_formatter.rb +11 -0
- data/lib/thredded/version.rb +1 -1
- data/vendor/assets/javascripts/autosize.js +290 -0
- metadata +15 -17
- data/app/views/thredded/preferences/_header.html.erb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9da3f257731b6397128563a35788225046e8a589
|
4
|
+
data.tar.gz: fc0b9d0117acd6de8c6d21fa1d3ff629e3e463e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d811130638a892c28e07b2065f05b0c8e6edd8d2aabea59691dd0f5653424818978fd4bb2d0676875aa85110e9b58bacda911efc60c26ce4dd5bb53fefa306c6
|
7
|
+
data.tar.gz: b78b12a3e681153c4b82363b6334a5c09648e86910f17f8d997e4f53dac0cd84555a3141c83d7da20f885b4b532a385913703ad6ff8a36982cc7c4ecc91636d1
|
data/README.md
CHANGED
@@ -99,7 +99,7 @@ Then, see the rest of this Readme for more information about using and customizi
|
|
99
99
|
Add the gem to your Gemfile:
|
100
100
|
|
101
101
|
```ruby
|
102
|
-
gem 'thredded', '~> 0.
|
102
|
+
gem 'thredded', '~> 0.12.0'
|
103
103
|
```
|
104
104
|
|
105
105
|
Add the Thredded [initializer] to your parent app by running the install generator.
|
@@ -151,7 +151,7 @@ But then compare this with the previous version to decide what to keep.
|
|
151
151
|
2) To upgrade the database (in this example from v0.10 to v0.11):
|
152
152
|
|
153
153
|
```console
|
154
|
-
# Note that for guaranteed best results you will want to run this with the gem checked out with v0.
|
154
|
+
# Note that for guaranteed best results you will want to run this with the gem checked out with v0.11
|
155
155
|
cp `bundle show thredded`/db/upgrade_migrations/20170312131417_upgrade_thredded_v0_10_to_v0_11.rb db/migrate
|
156
156
|
rake db:migrate
|
157
157
|
```
|
@@ -193,9 +193,6 @@ In your layout you will probably have links to other paths in your app (e.g. nav
|
|
193
193
|
For any url helpers (like `users_path` or `projects_path` or whatever) will need to have `main_app.`
|
194
194
|
prefixed to them so that they can be found from thredded (`main_app.users_path` will work from both thredded and your app).
|
195
195
|
|
196
|
-
However if you don't want to update your layouts and partials, you can define methods automatically to delegate to the main_app's routes:
|
197
|
-
See https://gist.github.com/timdiggins/bf6d09b28828a392198562c93554ad07.
|
198
|
-
|
199
196
|
#### Add Thredded styles
|
200
197
|
|
201
198
|
In this case, you will also need to include Thredded styles and JavaScript into the application styles and JavaScript.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
//= require ./preview_area
|
2
2
|
|
3
|
-
((
|
3
|
+
(($, autosize) => {
|
4
4
|
const COMPONENT_SELECTOR = '[data-thredded-post-form]';
|
5
5
|
|
6
6
|
class ThreddedPostForm {
|
@@ -18,11 +18,11 @@
|
|
18
18
|
}
|
19
19
|
|
20
20
|
autosize($textarea) {
|
21
|
-
$textarea
|
21
|
+
autosize($textarea)
|
22
22
|
}
|
23
23
|
|
24
24
|
destroy($nodes) {
|
25
|
-
$nodes.find(this.textareaSelector)
|
25
|
+
autosize.destroy($nodes.find(this.textareaSelector));
|
26
26
|
}
|
27
27
|
}
|
28
28
|
|
@@ -39,4 +39,4 @@
|
|
39
39
|
new ThreddedPostForm().destroy($nodes);
|
40
40
|
}
|
41
41
|
});
|
42
|
-
})(jQuery);
|
42
|
+
})(jQuery, window.autosize);
|
@@ -0,0 +1,45 @@
|
|
1
|
+
(function() {
|
2
|
+
window.Thredded.onPageLoad(() => {
|
3
|
+
Array.prototype.forEach.call(document.querySelectorAll('[data-thredded-quote-post]'), (el) => {
|
4
|
+
el.addEventListener('click', onClick);
|
5
|
+
});
|
6
|
+
});
|
7
|
+
|
8
|
+
function onClick(evt) {
|
9
|
+
// Handle only left clicks with no modifier keys
|
10
|
+
if (evt.button !== 0 || evt.ctrlKey || evt.altKey || evt.metaKey || evt.shiftKey) return;
|
11
|
+
evt.preventDefault();
|
12
|
+
const target = document.getElementById('post_content');
|
13
|
+
target.scrollIntoView();
|
14
|
+
target.value = '...';
|
15
|
+
fetchReply(evt.target.getAttribute('data-thredded-quote-post'), (replyText) => {
|
16
|
+
if (!target.ownerDocument.body.contains(target)) return;
|
17
|
+
target.focus();
|
18
|
+
target.value = replyText;
|
19
|
+
|
20
|
+
const autosizeUpdateEvent = document.createEvent('Event');
|
21
|
+
autosizeUpdateEvent.initEvent('autosize:update', true, false);
|
22
|
+
target.dispatchEvent(autosizeUpdateEvent);
|
23
|
+
// Scroll into view again as the size might have changed.
|
24
|
+
target.scrollIntoView();
|
25
|
+
}, (errorMessage) => {
|
26
|
+
target.value = errorMessage;
|
27
|
+
});
|
28
|
+
}
|
29
|
+
|
30
|
+
function fetchReply(url, onSuccess, onError) {
|
31
|
+
const request = new XMLHttpRequest();
|
32
|
+
request.open('GET', url, /* async */ true);
|
33
|
+
request.onload = () => {
|
34
|
+
if (request.status >= 200 && request.status < 400) {
|
35
|
+
onSuccess(request.responseText);
|
36
|
+
} else {
|
37
|
+
onError(`Error (${request.status}): ${request.statusText} ${request.responseText}`);
|
38
|
+
}
|
39
|
+
};
|
40
|
+
request.onerror = () => {
|
41
|
+
onError('Network Error');
|
42
|
+
};
|
43
|
+
request.send();
|
44
|
+
}
|
45
|
+
})();
|
@@ -1,4 +1,4 @@
|
|
1
|
-
((
|
1
|
+
(($, autosize) => {
|
2
2
|
const COMPONENT_SELECTOR = '[data-thredded-topic-form]';
|
3
3
|
class ThreddedTopicForm {
|
4
4
|
constructor() {
|
@@ -15,7 +15,7 @@
|
|
15
15
|
}
|
16
16
|
|
17
17
|
init($nodes) {
|
18
|
-
$nodes.find(this.textareaSelector)
|
18
|
+
autosize($nodes.find(this.textareaSelector));
|
19
19
|
$nodes.each(function() {
|
20
20
|
new ThreddedPreviewArea($(this));
|
21
21
|
});
|
@@ -47,7 +47,7 @@
|
|
47
47
|
}
|
48
48
|
|
49
49
|
destroy($nodes) {
|
50
|
-
$nodes.find(this.textareaSelector)
|
50
|
+
autosize.destroy($nodes.find(this.textareaSelector));
|
51
51
|
}
|
52
52
|
}
|
53
53
|
|
@@ -64,6 +64,6 @@
|
|
64
64
|
new ThreddedTopicForm().destroy($nodes);
|
65
65
|
}
|
66
66
|
});
|
67
|
-
})(jQuery);
|
67
|
+
})(jQuery, window.autosize);
|
68
68
|
|
69
69
|
|
@@ -26,6 +26,14 @@
|
|
26
26
|
};
|
27
27
|
|
28
28
|
if (isTurbolinks5) {
|
29
|
+
// In Turbolinks 5.0.1, turbolinks:load may have already fired (before DOMContentLoaded).
|
30
|
+
// If so, add our own DOMContentLoaded listener:
|
31
|
+
// See: https://github.com/turbolinks/turbolinks/commit/69d353ea73d10ee6b25c2866fc5706879ba403e3
|
32
|
+
if (window.Turbolinks.controller.lastRenderedLocation) {
|
33
|
+
document.addEventListener('DOMContentLoaded', () => {
|
34
|
+
triggerOnPageLoad();
|
35
|
+
});
|
36
|
+
}
|
29
37
|
document.addEventListener('turbolinks:load', () => {
|
30
38
|
triggerOnPageLoad();
|
31
39
|
});
|
@@ -21,14 +21,13 @@
|
|
21
21
|
margin: 0;
|
22
22
|
|
23
23
|
&--author {
|
24
|
-
margin-bottom:
|
24
|
+
margin-bottom: 2px;
|
25
25
|
}
|
26
26
|
|
27
27
|
.thredded--post--content {
|
28
28
|
font-size: inherit;
|
29
|
-
border-left: solid 5px $thredded-blockquote-border-color;
|
30
29
|
margin: 0 0 0.75rem;
|
31
|
-
padding:
|
30
|
+
padding-left: 0;
|
32
31
|
|
33
32
|
.onebox-wrapper-table {
|
34
33
|
width: 100%;
|
@@ -1,6 +1,19 @@
|
|
1
|
-
.thredded--preferences
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
.thredded--preferences--title {
|
2
|
+
@extend %thredded--heading;
|
3
|
+
font-size: 1.5rem; // 24px
|
4
|
+
}
|
5
|
+
|
6
|
+
.thredded--preferences--form {
|
7
|
+
padding-bottom: $thredded-base-spacing;
|
8
|
+
}
|
9
|
+
|
10
|
+
.thredded--preferences--messageboards-nav {
|
11
|
+
border-top: $thredded-base-border;
|
12
|
+
padding-top: $thredded-base-spacing;
|
13
|
+
}
|
14
|
+
|
15
|
+
.thredded--preferences--messageboards-nav--item {
|
16
|
+
&.thredded--messageboard {
|
17
|
+
padding: $thredded-small-spacing;
|
5
18
|
}
|
6
19
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Thredded
|
3
|
+
# @api private
|
4
|
+
module NewPostParams
|
5
|
+
protected
|
6
|
+
|
7
|
+
def new_post_params
|
8
|
+
params.fetch(:post, {})
|
9
|
+
.permit(:content, :quote_post_id)
|
10
|
+
.merge(ip: request.remote_ip).tap do |p|
|
11
|
+
quote_id = p.delete(:quote_post_id)
|
12
|
+
if quote_id
|
13
|
+
post = Post.find(quote_id)
|
14
|
+
authorize_reading post
|
15
|
+
p[:quote_post] = post
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Thredded
|
3
|
+
# @api private
|
4
|
+
module NewPrivatePostParams
|
5
|
+
protected
|
6
|
+
|
7
|
+
def new_private_post_params
|
8
|
+
params.fetch(:post, {})
|
9
|
+
.permit(:content, :quote_private_post_id)
|
10
|
+
.merge(ip: request.remote_ip).tap do |p|
|
11
|
+
quote_id = p.delete(:quote_private_post_id)
|
12
|
+
if quote_id
|
13
|
+
post = PrivatePost.find(quote_id)
|
14
|
+
authorize_reading post
|
15
|
+
p[:quote_post] = post
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -3,29 +3,39 @@ module Thredded
|
|
3
3
|
# A controller for managing {Post}s.
|
4
4
|
class PostsController < Thredded::ApplicationController
|
5
5
|
include ActionView::RecordIdentifier
|
6
|
+
include Thredded::NewPostParams
|
6
7
|
|
7
8
|
helper_method :topic
|
8
9
|
after_action :update_user_activity
|
9
10
|
|
10
11
|
after_action :verify_authorized
|
11
12
|
|
12
|
-
def
|
13
|
-
|
14
|
-
authorize_creating post
|
15
|
-
|
13
|
+
def new
|
14
|
+
@post_form = PostForm.new(user: thredded_current_user, topic: parent_topic, post_params: new_post_params)
|
15
|
+
authorize_creating @post_form.post
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
+
def create
|
19
|
+
@post_form = PostForm.new(user: thredded_current_user, topic: parent_topic, post_params: new_post_params)
|
20
|
+
authorize_creating @post_form.post
|
21
|
+
|
22
|
+
if @post_form.save
|
23
|
+
redirect_to post_path(@post_form.post, user: thredded_current_user)
|
24
|
+
else
|
25
|
+
render :new
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
29
|
def edit
|
21
|
-
|
30
|
+
@post_form = PostForm.for_persisted(post)
|
31
|
+
authorize @post_form.post, :update?
|
22
32
|
return redirect_to(canonical_topic_params) unless params_match?(canonical_topic_params)
|
23
33
|
render
|
24
34
|
end
|
25
35
|
|
26
36
|
def update
|
27
37
|
authorize post, :update?
|
28
|
-
post.update_attributes(
|
38
|
+
post.update_attributes(new_post_params)
|
29
39
|
|
30
40
|
redirect_to post_path(post, user: thredded_current_user)
|
31
41
|
end
|
@@ -45,6 +55,11 @@ module Thredded
|
|
45
55
|
after_mark_as_unread # customization hook
|
46
56
|
end
|
47
57
|
|
58
|
+
def quote
|
59
|
+
authorize_reading post
|
60
|
+
render plain: Thredded::ContentFormatter.quote_content(post.content)
|
61
|
+
end
|
62
|
+
|
48
63
|
private
|
49
64
|
|
50
65
|
def canonical_topic_params
|
@@ -59,12 +74,6 @@ module Thredded
|
|
59
74
|
post.postable
|
60
75
|
end
|
61
76
|
|
62
|
-
def post_params
|
63
|
-
params.require(:post)
|
64
|
-
.permit(:content)
|
65
|
-
.merge(user: thredded_current_user, ip: request.remote_ip, messageboard: messageboard)
|
66
|
-
end
|
67
|
-
|
68
77
|
def parent_topic
|
69
78
|
Topic
|
70
79
|
.where(messageboard: messageboard)
|
@@ -3,22 +3,35 @@ module Thredded
|
|
3
3
|
# A controller for managing {PrivatePost}s.
|
4
4
|
class PrivatePostsController < Thredded::ApplicationController
|
5
5
|
include ActionView::RecordIdentifier
|
6
|
+
include NewPrivatePostParams
|
6
7
|
|
7
8
|
helper_method :topic
|
8
9
|
after_action :update_user_activity
|
9
10
|
|
10
11
|
after_action :verify_authorized
|
11
12
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def new
|
14
|
+
@post_form = PrivatePostForm.new(
|
15
|
+
user: thredded_current_user, topic: parent_topic, post_params: new_private_post_params
|
16
|
+
)
|
17
|
+
authorize_creating @post_form.post
|
18
|
+
end
|
16
19
|
|
17
|
-
|
20
|
+
def create
|
21
|
+
@post_form = PrivatePostForm.new(
|
22
|
+
user: thredded_current_user, topic: parent_topic, post_params: new_private_post_params
|
23
|
+
)
|
24
|
+
authorize_creating @post_form.post
|
25
|
+
if @post_form.save
|
26
|
+
redirect_to post_path(@post_form.post, user: thredded_current_user)
|
27
|
+
else
|
28
|
+
render :new
|
29
|
+
end
|
18
30
|
end
|
19
31
|
|
20
32
|
def edit
|
21
|
-
|
33
|
+
@post_form = PrivatePostForm.for_persisted(post)
|
34
|
+
authorize @post_form.post, :update?
|
22
35
|
return redirect_to(canonical_topic_params) unless params_match?(canonical_topic_params)
|
23
36
|
render
|
24
37
|
end
|
@@ -45,6 +58,11 @@ module Thredded
|
|
45
58
|
after_mark_as_unread # customization hook
|
46
59
|
end
|
47
60
|
|
61
|
+
def quote
|
62
|
+
authorize_reading post
|
63
|
+
render plain: Thredded::ContentFormatter.quote_content(post.content)
|
64
|
+
end
|
65
|
+
|
48
66
|
private
|
49
67
|
|
50
68
|
def canonical_topic_params
|
@@ -59,12 +77,6 @@ module Thredded
|
|
59
77
|
post.postable
|
60
78
|
end
|
61
79
|
|
62
|
-
def post_params
|
63
|
-
params.require(:post)
|
64
|
-
.permit(:content)
|
65
|
-
.merge(user: thredded_current_user, ip: request.remote_ip)
|
66
|
-
end
|
67
|
-
|
68
80
|
def parent_topic
|
69
81
|
PrivateTopic
|
70
82
|
.includes(:private_users)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
module Thredded
|
3
3
|
class PrivateTopicsController < Thredded::ApplicationController
|
4
4
|
include Thredded::NewPrivateTopicParams
|
5
|
+
include Thredded::NewPrivatePostParams
|
5
6
|
|
6
7
|
before_action :thredded_require_login!
|
7
8
|
|
@@ -37,7 +38,9 @@ module Thredded
|
|
37
38
|
)
|
38
39
|
end
|
39
40
|
|
40
|
-
@
|
41
|
+
@new_post = Thredded::PrivatePostForm.new(
|
42
|
+
user: thredded_current_user, topic: private_topic, post_params: new_private_post_params
|
43
|
+
)
|
41
44
|
end
|
42
45
|
|
43
46
|
def new
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Thredded
|
3
3
|
class ThemePreviewsController < Thredded::ApplicationController
|
4
|
-
def show
|
4
|
+
def show # rubocop:disable Metrics/MethodLength
|
5
5
|
@messageboard = Messageboard.first
|
6
6
|
fail Thredded::Errors::DatabaseEmpty unless @messageboard
|
7
7
|
@user = if thredded_current_user.thredded_anonymous?
|
@@ -16,7 +16,8 @@ module Thredded
|
|
16
16
|
@topic = TopicView.from_user(topic, @user)
|
17
17
|
@posts = TopicPostsPageView.new(@user, topic, topic.posts.page(1).limit(3))
|
18
18
|
@post = topic.posts.build(id: 1337, postable: topic, content: 'Hello world', user: @user)
|
19
|
-
@
|
19
|
+
@post_form = PostForm.for_persisted(@post)
|
20
|
+
@new_post = PostForm.new(user: @user, topic: topic)
|
20
21
|
@new_topic = TopicForm.new(user: @user, messageboard: @messageboard)
|
21
22
|
@new_private_topic = PrivateTopicForm.new(user: @user)
|
22
23
|
private_topic = PrivateTopic.new(id: 1337, title: 'Hello', user: @user, last_user: @user, users: [@user])
|
@@ -25,6 +26,7 @@ module Thredded
|
|
25
26
|
@private_post = private_topic.posts.build(
|
26
27
|
id: 1337, postable: private_topic, content: 'A private hello world', user: @user
|
27
28
|
)
|
29
|
+
@private_post_form = PrivatePostForm.for_persisted(@private_post)
|
28
30
|
@preferences = UserPreferencesForm.new(user: @user, messageboard: @messageboard)
|
29
31
|
end
|
30
32
|
end
|