thredded 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/thredded/application_controller.rb +9 -11
- data/app/controllers/thredded/emails_controller.rb +4 -0
- data/app/controllers/thredded/messageboards_controller.rb +1 -1
- data/app/controllers/thredded/posts_controller.rb +44 -48
- data/app/controllers/thredded/preferences_controller.rb +10 -2
- data/app/controllers/thredded/private_topics_controller.rb +18 -1
- data/app/controllers/thredded/setups_controller.rb +9 -4
- data/app/controllers/thredded/topics_controller.rb +47 -49
- data/app/decorators/thredded/post_decorator.rb +1 -1
- data/app/decorators/thredded/topic_decorator.rb +1 -9
- data/app/decorators/thredded/user_topic_decorator.rb +88 -0
- data/app/helpers/thredded/messageboard_helper.rb +1 -9
- data/app/helpers/thredded/topics_helper.rb +0 -17
- data/app/models/thredded/ability.rb +8 -0
- data/app/models/thredded/attachment.rb +0 -1
- data/app/models/thredded/category.rb +2 -3
- data/app/models/thredded/image.rb +0 -1
- data/app/models/thredded/messageboard.rb +15 -7
- data/app/models/thredded/messageboard_decorator.rb +2 -2
- data/app/models/thredded/messageboard_preference.rb +0 -1
- data/app/models/thredded/null_messageboard_preference.rb +7 -0
- data/app/models/thredded/null_preference.rb +8 -6
- data/app/models/thredded/null_topic_read.rb +15 -9
- data/app/models/thredded/null_user.rb +8 -0
- data/app/models/thredded/post.rb +13 -17
- data/app/models/thredded/post_notification.rb +0 -1
- data/app/models/thredded/private_topic.rb +11 -2
- data/app/models/thredded/private_user.rb +0 -1
- data/app/models/thredded/role.rb +0 -2
- data/app/models/thredded/topic.rb +27 -23
- data/app/models/thredded/topic_category.rb +0 -1
- data/app/models/thredded/user_extender.rb +2 -8
- data/app/models/thredded/user_topic_read.rb +5 -63
- data/app/views/thredded/attachments/_attachment.html.erb +7 -0
- data/app/views/thredded/messageboards/_messageboard.html.erb +1 -1
- data/app/views/thredded/post_mailer/at_notification.html.erb +1 -1
- data/app/views/thredded/post_mailer/at_notification.text.erb +1 -1
- data/app/views/thredded/posts/_post.html.erb +6 -2
- data/app/views/thredded/posts/index.html.erb +24 -37
- data/app/views/thredded/private_topics/_form.html.erb +15 -0
- data/app/views/thredded/private_topics/index.html.erb +33 -0
- data/app/views/thredded/private_topics/new.html.erb +24 -0
- data/app/views/thredded/shared/_currently_online.html.erb +2 -2
- data/app/views/thredded/shared/_topic_nav.html.erb +13 -10
- data/app/views/thredded/topic_mailer/message_notification.html.erb +1 -1
- data/app/views/thredded/topic_mailer/message_notification.text.erb +1 -1
- data/app/views/thredded/topics/_recent_topics_by_user.html.erb +8 -0
- data/app/views/thredded/topics/_topic_condensed.html.erb +6 -2
- data/app/views/thredded/topics/index.html.erb +5 -26
- data/app/views/thredded/topics/new.html.erb +1 -1
- data/app/views/thredded/topics/search.html.erb +6 -21
- data/config/initializers/griddler.rb +4 -0
- data/config/routes.rb +8 -5
- data/db/migrate/20131005032727_prevent_null_sticky_and_locked.rb +15 -0
- data/db/migrate/20131014014258_uniqs_on_user_topic_read.rb +9 -0
- data/db/migrate/20131019014258_index_necessary_columns.rb +24 -0
- data/lib/thredded.rb +3 -0
- data/lib/thredded/at_notifier.rb +4 -2
- data/lib/thredded/at_users.rb +2 -2
- data/lib/thredded/email_processor.rb +57 -55
- data/lib/thredded/engine.rb +1 -1
- data/lib/thredded/errors.rb +8 -0
- data/lib/thredded/post_sql_builder.rb +3 -3
- data/lib/thredded/post_user_permissions.rb +4 -0
- data/lib/thredded/private_topic_user_permissions.rb +7 -1
- data/lib/thredded/search_sql_builder.rb +1 -1
- data/lib/thredded/table_sql_builder.rb +1 -1
- data/lib/thredded/version.rb +1 -1
- metadata +21 -35
@@ -19,19 +19,11 @@ module Thredded
|
|
19
19
|
classes.join(' ')
|
20
20
|
end
|
21
21
|
|
22
|
-
def user_link
|
23
|
-
if user.nil?
|
24
|
-
'<a href="#">?</a>'.html_safe
|
25
|
-
else
|
26
|
-
"<a href='/users/#{user_name}'>#{user_name}</a>".html_safe
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
22
|
def last_user_link
|
31
23
|
if last_user.nil?
|
32
24
|
'Anonymous'
|
33
25
|
else
|
34
|
-
"<a href='/users/#{last_user
|
26
|
+
"<a href='/users/#{last_user}'>#{last_user}</a>".html_safe
|
35
27
|
end
|
36
28
|
end
|
37
29
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Thredded
|
2
|
+
class UserTopicDecorator
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
|
6
|
+
def initialize(user, topic)
|
7
|
+
@user = user || NullUser.new
|
8
|
+
@topic = topic
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(meth, *args)
|
12
|
+
if decorated_topic.respond_to?(meth)
|
13
|
+
decorated_topic.send(meth, *args)
|
14
|
+
else
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to?(meth)
|
20
|
+
decorated_topic.respond_to?(meth)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.decorate_all(user, topics)
|
24
|
+
topics.map do |topic|
|
25
|
+
new(user, topic)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.model_name
|
30
|
+
ActiveModel::Name.new(self, nil, "Topic")
|
31
|
+
end
|
32
|
+
|
33
|
+
def persisted?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def read?
|
38
|
+
topic.posts_count == read_status.posts_count
|
39
|
+
end
|
40
|
+
|
41
|
+
def farthest_page
|
42
|
+
read_status.page
|
43
|
+
end
|
44
|
+
|
45
|
+
def farthest_post
|
46
|
+
read_status.farthest_post
|
47
|
+
end
|
48
|
+
|
49
|
+
def css_class
|
50
|
+
if read?
|
51
|
+
"read #{decorated_topic.css_class}"
|
52
|
+
else
|
53
|
+
"unread #{decorated_topic.css_class}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def user_link
|
58
|
+
if user.valid?
|
59
|
+
"<a href='/users/#{topic.user_name}'>#{topic.user_name}</a>".html_safe
|
60
|
+
else
|
61
|
+
'<a href="#">?</a>'.html_safe
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def decorated_topic
|
67
|
+
@decorated_topic ||= TopicDecorator.new(topic)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :topic, :user
|
73
|
+
|
74
|
+
def read_status
|
75
|
+
if user.valid?
|
76
|
+
@read_status ||= topic.user_topic_reads.select do |reads|
|
77
|
+
reads.user_id == user.id
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if @read_status.blank?
|
82
|
+
NullTopicRead.new
|
83
|
+
else
|
84
|
+
@read_status.first
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -15,14 +15,6 @@ module Thredded
|
|
15
15
|
#{number_to_human posts} posts".downcase
|
16
16
|
end
|
17
17
|
|
18
|
-
def admin_link_for(messageboard)
|
19
|
-
if can? :manage, messageboard
|
20
|
-
'<p class="admin"><a href="#edit">Edit</a></p>'
|
21
|
-
else
|
22
|
-
''
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
18
|
def latest_thread_for(messageboard)
|
27
19
|
topic = messageboard.topics.first
|
28
20
|
|
@@ -43,7 +35,7 @@ module Thredded
|
|
43
35
|
|
44
36
|
def latest_user_for(messageboard)
|
45
37
|
if messageboard.topics.first.present? && messageboard.topics.first.user.present?
|
46
|
-
messageboard.topics.first.last_user.
|
38
|
+
messageboard.topics.first.last_user.to_s
|
47
39
|
else
|
48
40
|
''
|
49
41
|
end
|
@@ -1,21 +1,4 @@
|
|
1
1
|
module Thredded
|
2
2
|
module TopicsHelper
|
3
|
-
require 'digest/md5'
|
4
|
-
|
5
|
-
def md5(s)
|
6
|
-
Digest::MD5.hexdigest(s)
|
7
|
-
end
|
8
|
-
|
9
|
-
def already_read(topic, tracked_user_reads)
|
10
|
-
if tracked_user_reads
|
11
|
-
topic_status = tracked_user_reads.select{ |t| t.topic_id == topic.id }.first
|
12
|
-
|
13
|
-
if topic_status && topic_status.posts_count == topic.posts_count
|
14
|
-
'read'
|
15
|
-
else
|
16
|
-
'unread'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
3
|
end
|
21
4
|
end
|
@@ -26,6 +26,10 @@ module Thredded
|
|
26
26
|
|
27
27
|
cannot :manage, Thredded::PrivateTopic
|
28
28
|
|
29
|
+
can :list, Thredded::PrivateTopic do |private_topic|
|
30
|
+
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).listable?
|
31
|
+
end
|
32
|
+
|
29
33
|
can :manage, Thredded::PrivateTopic do |private_topic|
|
30
34
|
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).manageable?
|
31
35
|
end
|
@@ -38,6 +42,10 @@ module Thredded
|
|
38
42
|
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).readable?
|
39
43
|
end
|
40
44
|
|
45
|
+
can :edit, Thredded::Post do |post|
|
46
|
+
Thredded::PostUserPermissions.new(post, user, user_details).editable?
|
47
|
+
end
|
48
|
+
|
41
49
|
can :manage, Thredded::Post do |post|
|
42
50
|
Thredded::PostUserPermissions.new(post, user, user_details).manageable?
|
43
51
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module Thredded
|
2
2
|
class Category < ActiveRecord::Base
|
3
|
-
attr_accessible :description, :messageboard_id, :name
|
4
|
-
validates :name, presence: true
|
5
|
-
|
6
3
|
belongs_to :messageboard
|
7
4
|
has_many :topic_categories
|
8
5
|
has_many :topics, through: :topic_categories
|
6
|
+
|
7
|
+
validates :name, presence: true
|
9
8
|
end
|
10
9
|
end
|
@@ -6,13 +6,6 @@ module Thredded
|
|
6
6
|
extend FriendlyId
|
7
7
|
friendly_id :name
|
8
8
|
|
9
|
-
attr_accessible :description,
|
10
|
-
:name,
|
11
|
-
:posting_permission,
|
12
|
-
:security
|
13
|
-
|
14
|
-
default_scope where(closed: false).order('topics_count DESC')
|
15
|
-
|
16
9
|
validates_numericality_of :topics_count
|
17
10
|
validates_inclusion_of :security, in: SECURITY
|
18
11
|
validates_inclusion_of :posting_permission, in: PERMISSIONS
|
@@ -32,6 +25,15 @@ module Thredded
|
|
32
25
|
has_many :private_topics
|
33
26
|
has_many :users, through: :roles, class_name: Thredded.user_class
|
34
27
|
|
28
|
+
def self.default_scope
|
29
|
+
where(closed: false).order('topics_count DESC')
|
30
|
+
end
|
31
|
+
|
32
|
+
def preferences_for(user)
|
33
|
+
@preferences_for ||=
|
34
|
+
messageboard_preferences.where(user_id: user).first || NullMessageboardPreference.new
|
35
|
+
end
|
36
|
+
|
35
37
|
def active_users
|
36
38
|
Role
|
37
39
|
.joins(:user)
|
@@ -41,6 +43,12 @@ module Thredded
|
|
41
43
|
.map(&:user)
|
42
44
|
end
|
43
45
|
|
46
|
+
def update_activity_for!(user)
|
47
|
+
if role = roles.where(user_id: user).first
|
48
|
+
role.update_attribute(:last_seen, Time.now.utc)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
44
52
|
def decorate
|
45
53
|
MessageboardDecorator.new(self)
|
46
54
|
end
|
@@ -8,11 +8,11 @@ module Thredded
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def category_options
|
11
|
-
messageboard.categories.
|
11
|
+
messageboard.categories.map { |cat| [cat.name, cat.id] }
|
12
12
|
end
|
13
13
|
|
14
14
|
def users_options
|
15
|
-
messageboard.users.
|
15
|
+
messageboard.users.map { |user| [user.to_s, user.id] }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -1,13 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Thredded
|
2
|
+
class NullTopicRead
|
3
|
+
def page
|
4
|
+
1
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def post_id
|
8
|
+
0
|
9
|
+
end
|
10
|
+
|
11
|
+
def posts_count
|
12
|
+
0
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
def farthest_post
|
16
|
+
Post.new
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
@@ -4,6 +4,10 @@ module Thredded
|
|
4
4
|
false
|
5
5
|
end
|
6
6
|
|
7
|
+
def thredded_private_topics
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
7
11
|
def can_read_messageboard?(messageboard)
|
8
12
|
messageboard.public?
|
9
13
|
end
|
@@ -20,6 +24,10 @@ module Thredded
|
|
20
24
|
'Anonymous User'
|
21
25
|
end
|
22
26
|
|
27
|
+
def to_s
|
28
|
+
name
|
29
|
+
end
|
30
|
+
|
23
31
|
def valid?
|
24
32
|
false
|
25
33
|
end
|
data/app/models/thredded/post.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'thredded/at_notifier'
|
2
|
+
require 'gravtastic'
|
3
|
+
|
1
4
|
module Thredded
|
2
5
|
class Post < ActiveRecord::Base
|
3
|
-
require 'gravtastic'
|
4
6
|
include Gravtastic
|
5
7
|
include Thredded::Filter::Base
|
6
8
|
include Thredded::Filter::Textile
|
@@ -13,17 +15,6 @@ module Thredded
|
|
13
15
|
gravtastic :user_email
|
14
16
|
paginates_per 50
|
15
17
|
|
16
|
-
attr_accessible :attachments_attributes,
|
17
|
-
:content,
|
18
|
-
:filter,
|
19
|
-
:ip,
|
20
|
-
:messageboard,
|
21
|
-
:source,
|
22
|
-
:topic,
|
23
|
-
:user
|
24
|
-
|
25
|
-
default_scope order: 'id ASC'
|
26
|
-
|
27
18
|
belongs_to :messageboard, counter_cache: true
|
28
19
|
belongs_to :topic, counter_cache: true
|
29
20
|
belongs_to :user, class_name: Thredded.user_class
|
@@ -35,11 +26,11 @@ module Thredded
|
|
35
26
|
validates_presence_of :content, :messageboard_id
|
36
27
|
|
37
28
|
before_validation :set_user_email
|
38
|
-
|
29
|
+
after_save :notify_at_users
|
30
|
+
after_create :modify_parent_posts_counts
|
39
31
|
|
40
|
-
def
|
41
|
-
|
42
|
-
super
|
32
|
+
def self.default_scope
|
33
|
+
order('id ASC')
|
43
34
|
end
|
44
35
|
|
45
36
|
def created_date
|
@@ -60,7 +51,8 @@ module Thredded
|
|
60
51
|
|
61
52
|
private
|
62
53
|
|
63
|
-
def
|
54
|
+
def modify_parent_posts_counts
|
55
|
+
UserDetail.increment_counter(:posts_count, user_id)
|
64
56
|
topic.last_user = user
|
65
57
|
topic.touch
|
66
58
|
topic.save
|
@@ -71,5 +63,9 @@ module Thredded
|
|
71
63
|
self.user_email = user.email
|
72
64
|
end
|
73
65
|
end
|
66
|
+
|
67
|
+
def notify_at_users
|
68
|
+
AtNotifier.new(self).notifications_for_at_users
|
69
|
+
end
|
74
70
|
end
|
75
71
|
end
|
@@ -2,7 +2,16 @@ module Thredded
|
|
2
2
|
class PrivateTopic < Thredded::Topic
|
3
3
|
has_many :private_users
|
4
4
|
has_many :users, through: :private_users
|
5
|
-
|
5
|
+
|
6
|
+
def self.including_roles_for(user)
|
7
|
+
joins(messageboard: :roles)
|
8
|
+
.where(thredded_roles: {user_id: user.id})
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.for_user(user)
|
12
|
+
joins(:private_users)
|
13
|
+
.where(thredded_private_users: {user_id: user.id})
|
14
|
+
end
|
6
15
|
|
7
16
|
def add_user(user)
|
8
17
|
if String == user.class
|
@@ -27,7 +36,7 @@ module Thredded
|
|
27
36
|
end
|
28
37
|
|
29
38
|
def users_to_sentence
|
30
|
-
users.map{ |user| user.
|
39
|
+
users.map{ |user| user.to_s.capitalize }.to_sentence
|
31
40
|
end
|
32
41
|
end
|
33
42
|
end
|