thredded 0.2.2 → 0.3.0

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.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.mkdn +63 -0
  3. data/Procfile +1 -0
  4. data/README.mkdn +42 -20
  5. data/app/assets/images/thredded/private-messages.svg +4 -0
  6. data/app/assets/images/thredded/settings.svg +4 -0
  7. data/app/assets/javascripts/thredded.es6 +2 -10
  8. data/app/assets/javascripts/thredded/{currently_online.es6 → components/currently_online.es6} +0 -0
  9. data/app/assets/javascripts/thredded/{post_form.es6 → components/post_form.es6} +0 -0
  10. data/app/assets/javascripts/thredded/{time_stamps.es6 → components/time_stamps.es6} +0 -0
  11. data/app/assets/javascripts/thredded/{topic_form.es6 → components/topic_form.es6} +1 -1
  12. data/app/assets/javascripts/thredded/components/topics.es6 +37 -0
  13. data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +45 -0
  14. data/app/assets/javascripts/thredded/components/users_select.es6 +56 -0
  15. data/app/assets/javascripts/thredded/dependencies.js +9 -0
  16. data/app/assets/javascripts/thredded/thredded.es6 +1 -0
  17. data/app/assets/stylesheets/thredded/_base.scss +3 -2
  18. data/app/assets/stylesheets/thredded/_thredded.scss +4 -1
  19. data/app/assets/stylesheets/thredded/base/_buttons.scss +2 -1
  20. data/app/assets/stylesheets/thredded/base/_forms.scss +23 -18
  21. data/app/assets/stylesheets/thredded/base/_grid.scss +1 -1
  22. data/app/assets/stylesheets/thredded/base/_nav.scss +21 -0
  23. data/app/assets/stylesheets/thredded/base/_tables.scss +5 -14
  24. data/app/assets/stylesheets/thredded/base/_typography.scss +9 -4
  25. data/app/assets/stylesheets/thredded/base/_variables.scss +28 -9
  26. data/app/assets/stylesheets/thredded/components/_alerts.scss +19 -0
  27. data/app/assets/stylesheets/thredded/components/_currently-online.scss +1 -1
  28. data/app/assets/stylesheets/thredded/components/_form-list.scss +2 -4
  29. data/app/assets/stylesheets/thredded/components/_icons.scss +3 -0
  30. data/app/assets/stylesheets/thredded/components/_messageboard.scss +4 -4
  31. data/app/assets/stylesheets/thredded/components/_pagination.scss +2 -2
  32. data/app/assets/stylesheets/thredded/components/_post-form.scss +3 -0
  33. data/app/assets/stylesheets/thredded/components/_post.scss +14 -4
  34. data/app/assets/stylesheets/thredded/components/_select2.scss +79 -9
  35. data/app/assets/stylesheets/thredded/components/_topic-header.scss +11 -1
  36. data/app/assets/stylesheets/thredded/components/_topics.scss +13 -11
  37. data/app/assets/stylesheets/thredded/layout/_main-container.scss +3 -3
  38. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +11 -17
  39. data/app/assets/stylesheets/thredded/layout/_navigation.scss +72 -0
  40. data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +66 -0
  41. data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +35 -61
  42. data/app/commands/thredded/at_notification_extractor.rb +1 -0
  43. data/app/commands/thredded/members_marked_notified.rb +1 -0
  44. data/app/commands/thredded/messageboard_destroyer.rb +7 -2
  45. data/app/commands/thredded/notify_mentioned_users.rb +8 -21
  46. data/app/commands/thredded/notify_private_topic_users.rb +3 -5
  47. data/app/controllers/thredded/application_controller.rb +76 -41
  48. data/app/controllers/thredded/autocomplete_users_controller.rb +46 -0
  49. data/app/controllers/thredded/messageboards_controller.rb +8 -5
  50. data/app/controllers/thredded/posts_controller.rb +20 -22
  51. data/app/controllers/thredded/preferences_controller.rb +19 -14
  52. data/app/controllers/thredded/private_topics_controller.rb +58 -23
  53. data/app/controllers/thredded/setups_controller.rb +1 -0
  54. data/app/controllers/thredded/theme_previews_controller.rb +24 -53
  55. data/app/controllers/thredded/topics_controller.rb +48 -77
  56. data/app/forms/thredded/private_topic_form.rb +1 -21
  57. data/app/forms/thredded/topic_form.rb +3 -7
  58. data/app/forms/thredded/user_preferences_form.rb +62 -0
  59. data/app/helpers/thredded/application_helper.rb +11 -12
  60. data/app/helpers/thredded/urls_helper.rb +103 -0
  61. data/app/jobs/thredded/activity_updater_job.rb +4 -3
  62. data/app/jobs/thredded/at_notifier_job.rb +1 -0
  63. data/app/jobs/thredded/notify_private_topic_users_job.rb +1 -0
  64. data/app/mailer_previews/thredded/base_mailer_preview.rb +101 -0
  65. data/app/mailer_previews/thredded/post_mailer_preview.rb +11 -0
  66. data/app/mailer_previews/thredded/private_post_mailer_preview.rb +11 -0
  67. data/app/mailer_previews/thredded/private_topic_mailer_preview.rb +15 -0
  68. data/app/mailers/thredded/base_mailer.rb +13 -0
  69. data/app/mailers/thredded/post_mailer.rb +4 -2
  70. data/app/mailers/thredded/private_post_mailer.rb +4 -2
  71. data/app/mailers/thredded/private_topic_mailer.rb +4 -2
  72. data/app/models/concerns/thredded/friendly_id_reserved_words_and_pagination.rb +16 -0
  73. data/app/models/concerns/thredded/post_common.rb +68 -63
  74. data/app/models/concerns/thredded/topic_common.rb +31 -8
  75. data/app/models/concerns/thredded/user_topic_read_state_common.rb +31 -0
  76. data/app/models/thredded/category.rb +1 -0
  77. data/app/models/thredded/messageboard.rb +24 -25
  78. data/app/models/thredded/messageboard_user.rb +1 -0
  79. data/app/models/thredded/null_preference.rb +1 -0
  80. data/app/models/thredded/null_user.rb +1 -6
  81. data/app/models/thredded/null_user_topic_read_state.rb +12 -0
  82. data/app/models/thredded/post.rb +6 -9
  83. data/app/models/thredded/post_notification.rb +1 -0
  84. data/app/models/thredded/private_post.rb +6 -2
  85. data/app/models/thredded/private_topic.rb +46 -32
  86. data/app/models/thredded/private_user.rb +3 -2
  87. data/app/models/thredded/stats.rb +1 -0
  88. data/app/models/thredded/topic.rb +40 -64
  89. data/app/models/thredded/topic_category.rb +1 -0
  90. data/app/models/thredded/user_detail.rb +2 -15
  91. data/app/models/thredded/user_extender.rb +29 -14
  92. data/app/models/thredded/user_messageboard_preference.rb +20 -0
  93. data/app/models/thredded/user_permissions/admin/if_admin_column_true.rb +1 -0
  94. data/app/models/thredded/user_permissions/admin/none.rb +1 -0
  95. data/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb +1 -0
  96. data/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb +1 -0
  97. data/app/models/thredded/user_permissions/moderate/none.rb +1 -0
  98. data/app/models/thredded/user_permissions/read/all.rb +1 -0
  99. data/app/models/thredded/user_permissions/write/all.rb +1 -0
  100. data/app/models/thredded/user_permissions/write/none.rb +1 -0
  101. data/app/models/thredded/user_preference.rb +7 -1
  102. data/app/models/thredded/user_private_topic_read_state.rb +12 -0
  103. data/app/models/thredded/user_topic_read_state.rb +12 -0
  104. data/app/policies/thredded/messageboard_policy.rb +27 -0
  105. data/app/policies/thredded/post_policy.rb +33 -0
  106. data/app/policies/thredded/private_post_policy.rb +29 -0
  107. data/app/policies/thredded/private_topic_policy.rb +23 -0
  108. data/app/policies/thredded/topic_policy.rb +32 -0
  109. data/app/view_models/thredded/base_topic_view.rb +56 -0
  110. data/app/view_models/thredded/post_view.rb +44 -0
  111. data/app/view_models/thredded/posts_page_view.rb +27 -0
  112. data/app/view_models/thredded/private_topic_view.rb +9 -0
  113. data/app/{decorators/thredded/topic_email_decorator.rb → view_models/thredded/topic_email_view.rb} +2 -1
  114. data/app/view_models/thredded/topic_view.rb +23 -0
  115. data/app/view_models/thredded/topics_page_view.rb +26 -0
  116. data/app/views/thredded/error_pages/forbidden.html.erb +6 -0
  117. data/app/views/thredded/error_pages/not_found.html.erb +6 -0
  118. data/app/views/thredded/messageboards/_messageboard.html.erb +13 -6
  119. data/app/views/thredded/messageboards/index.html.erb +2 -8
  120. data/app/views/thredded/messageboards/new.html.erb +8 -2
  121. data/app/views/thredded/post_mailer/at_notification.html.erb +3 -3
  122. data/app/views/thredded/post_mailer/at_notification.text.erb +1 -1
  123. data/app/views/thredded/posts/_content_field.html.erb +1 -1
  124. data/app/views/thredded/posts/_form.html.erb +5 -1
  125. data/app/views/thredded/posts/_post.html.erb +3 -1
  126. data/app/views/thredded/posts/edit.html.erb +7 -3
  127. data/app/views/thredded/posts_common/_form.html.erb +1 -1
  128. data/app/views/thredded/posts_common/_post.html.erb +14 -8
  129. data/app/views/thredded/preferences/_form.html.erb +37 -15
  130. data/app/views/thredded/preferences/_header.html.erb +1 -1
  131. data/app/views/thredded/preferences/edit.html.erb +4 -6
  132. data/app/views/thredded/private_post_mailer/at_notification.html.erb +6 -4
  133. data/app/views/thredded/private_posts/_form.html.erb +5 -1
  134. data/app/views/thredded/private_posts/_private_post.html.erb +3 -1
  135. data/app/views/thredded/private_topic_mailer/message_notification.html.erb +3 -7
  136. data/app/views/thredded/private_topic_mailer/message_notification.text.erb +1 -3
  137. data/app/views/thredded/private_topics/_breadcrumbs.html.erb +2 -2
  138. data/app/views/thredded/private_topics/_form.html.erb +15 -10
  139. data/app/views/thredded/private_topics/_header.html.erb +12 -0
  140. data/app/views/thredded/private_topics/_no_private_topics.html.erb +2 -2
  141. data/app/views/thredded/private_topics/_private_topic.html.erb +4 -6
  142. data/app/views/thredded/private_topics/edit.html.erb +32 -0
  143. data/app/views/thredded/private_topics/index.html.erb +5 -5
  144. data/app/views/thredded/private_topics/new.html.erb +1 -2
  145. data/app/views/thredded/private_topics/show.html.erb +12 -7
  146. data/app/views/thredded/search/_form.html.erb +9 -6
  147. data/app/views/thredded/shared/{_messageboard_topics_breadcrumbs.html.erb → _breadcrumbs.html.erb} +2 -2
  148. data/app/views/thredded/shared/_header.html.erb +2 -3
  149. data/app/views/thredded/shared/_nav.html.erb +20 -0
  150. data/app/views/thredded/shared/nav/_notification_preferences.html.erb +6 -0
  151. data/app/views/thredded/shared/nav/_private_topics.html.erb +11 -0
  152. data/app/views/thredded/shared/nav/_standalone.html.erb +12 -0
  153. data/app/views/thredded/theme_previews/_section_title.html.erb +2 -2
  154. data/app/views/thredded/theme_previews/show.html.erb +13 -17
  155. data/app/views/thredded/topics/_form.html.erb +8 -6
  156. data/app/views/thredded/topics/_header.html.erb +12 -0
  157. data/app/views/thredded/topics/_topic.html.erb +4 -8
  158. data/app/views/thredded/topics/_topic_form_admin_options.html.erb +1 -1
  159. data/app/views/thredded/topics/edit.html.erb +22 -18
  160. data/app/views/thredded/topics/index.html.erb +3 -3
  161. data/app/views/thredded/topics/new.html.erb +1 -1
  162. data/app/views/thredded/topics/search.html.erb +17 -5
  163. data/app/views/thredded/topics/show.html.erb +14 -11
  164. data/bin/rails +5 -0
  165. data/config.ru +3 -0
  166. data/config/i18n-tasks.yml +16 -0
  167. data/config/locales/en.yml +90 -0
  168. data/config/routes.rb +29 -15
  169. data/db/migrate/20160329231848_create_thredded.rb +29 -33
  170. data/db/seeds.rb +115 -0
  171. data/db/upgrade_migrations/20160410111522_upgrade_v0_2_to_v0_3.rb +59 -0
  172. data/heroku.gemfile +26 -0
  173. data/heroku.gemfile.lock +282 -0
  174. data/lib/generators/thredded/install/install_generator.rb +1 -0
  175. data/lib/generators/thredded/install/templates/initializer.rb +17 -0
  176. data/lib/html/pipeline/at_mention_filter.rb +2 -1
  177. data/lib/html/pipeline/bbcode_filter.rb +13 -4
  178. data/lib/tasks/thredded_tasks.rake +1 -0
  179. data/lib/thredded.rb +19 -17
  180. data/lib/thredded/at_users.rb +1 -0
  181. data/lib/thredded/engine.rb +14 -5
  182. data/lib/thredded/errors.rb +11 -11
  183. data/lib/thredded/main_app_route_delegator.rb +1 -0
  184. data/lib/thredded/search_parser.rb +2 -1
  185. data/lib/thredded/topics_search.rb +67 -0
  186. data/lib/thredded/version.rb +2 -1
  187. data/thredded.gemspec +12 -8
  188. metadata +146 -82
  189. data/app/assets/javascripts/thredded/users_select.es6 +0 -5
  190. data/app/assets/stylesheets/thredded/layout/_topic-navigation.scss +0 -53
  191. data/app/commands/thredded/user_reads_private_topic.rb +0 -22
  192. data/app/commands/thredded/user_resets_private_topic_to_unread.rb +0 -23
  193. data/app/decorators/thredded/base_topic_decorator.rb +0 -14
  194. data/app/decorators/thredded/base_user_topic_decorator.rb +0 -63
  195. data/app/decorators/thredded/messageboard_decorator.rb +0 -41
  196. data/app/decorators/thredded/post_decorator.rb +0 -40
  197. data/app/decorators/thredded/private_topic_decorator.rb +0 -23
  198. data/app/decorators/thredded/topic_decorator.rb +0 -25
  199. data/app/decorators/thredded/user_private_topic_decorator.rb +0 -13
  200. data/app/decorators/thredded/user_topic_decorator.rb +0 -37
  201. data/app/models/thredded/ability.rb +0 -60
  202. data/app/models/thredded/notification_preference.rb +0 -17
  203. data/app/models/thredded/null_topic.rb +0 -15
  204. data/app/models/thredded/null_topic_read.rb +0 -19
  205. data/app/models/thredded/user_topic_read.rb +0 -10
  206. data/app/views/thredded/shared/_notification_preferences.html.erb +0 -7
  207. data/app/views/thredded/shared/_top_nav.html.erb +0 -36
  208. data/app/views/thredded/shared/_topic_nav.html.erb +0 -22
  209. data/app/views/thredded/topics/_recent_topics_by_user.html.erb +0 -8
  210. data/app/views/thredded/topics/by_category.html.erb +0 -56
  211. data/app/views/thredded/topics_common/_header.html.erb +0 -6
  212. data/lib/thredded/messageboard_user_permissions.rb +0 -22
  213. data/lib/thredded/post_sql_builder.rb +0 -12
  214. data/lib/thredded/post_user_permissions.rb +0 -32
  215. data/lib/thredded/private_topic_user_permissions.rb +0 -26
  216. data/lib/thredded/search_sql_builder.rb +0 -21
  217. data/lib/thredded/seed_database.rb +0 -76
  218. data/lib/thredded/table_sql_builder.rb +0 -41
  219. data/lib/thredded/topic_sql_builder.rb +0 -11
  220. data/lib/thredded/topic_user_permissions.rb +0 -32
@@ -1,26 +1,40 @@
1
+ # frozen_string_literal: true
1
2
  Thredded::Engine.routes.draw do
2
- constraints(->(req) { req.env['QUERY_STRING'].include? 'q=' }) do
3
- get '/:messageboard_id(.:format)' => 'topics#search', as: :messageboard_search
4
- end
3
+ resource :theme_preview, only: [:show], path: 'theme-preview' if %w(development test).include? Rails.env
5
4
 
6
- resource :theme_preview, only: [:show] if %w(development test).include? Rails.env
5
+ page_constraint = { page: /[1-9]\d*/ }
7
6
 
8
- resources :private_topics, path: 'private-topics' do
9
- resources :private_posts, path: '', except: [:index], controller: 'posts'
7
+ scope path: 'private-topics' do
8
+ resource :private_topic, only: [:new], path: ''
9
+ resources :private_topics, except: [:new, :show], path: '' do
10
+ member do
11
+ get '(page-:page)', action: :show, as: '', constraints: page_constraint
12
+ end
13
+ resources :private_posts, path: '', except: [:index, :show], controller: 'posts'
14
+ end
10
15
  end
11
16
 
12
- get '/messageboards/new' => 'messageboards#new', as: :new_messageboard
13
- get '/:messageboard_id/preferences/edit' => 'preferences#edit'
14
- get '/:messageboard_id/new(.:format)' => 'topics#new', as: :new_messageboard_topic
15
- get '/:messageboard_id/:id/edit(.:format)' => 'topics#edit', as: :edit_messageboard_topic
16
- get '/:messageboard_id/:id/page-:page(.:format)' => 'topics#show', as: :paged_messageboard_topic_posts, constraints: { page: /\d+/ }
17
- get '/:messageboard_id/category/:category_id' => 'topics#category', as: :messageboard_topics_categories
17
+ resources :autocomplete_users, only: [:index], path: 'autocomplete-users'
18
18
 
19
+ constraints(->(req) { req.env['QUERY_STRING'].include? 'q=' }) do
20
+ get '/' => 'topics#search', as: :messageboards_search
21
+ get '/:messageboard_id(.:format)' => 'topics#search', as: :messageboard_search
22
+ end
23
+
24
+ resource :preferences, only: [:edit, :update]
25
+ resource :messageboard, path: 'messageboards', only: [:new]
19
26
  resources :messageboards, only: [:index, :create], path: '' do
20
27
  resource :preferences, only: [:edit, :update]
21
-
22
- resources :topics, path: '' do
23
- resources :posts, path: '', except: [:index]
28
+ resource :topic, path: 'topics', only: [:new]
29
+ resources :topics, path: '', except: [:index, :new, :show] do
30
+ collection do
31
+ get '(page-:page)', action: :index, as: '', constraints: page_constraint
32
+ get '/category/:category_id', action: :category, as: :categories
33
+ end
34
+ member do
35
+ get '(page-:page)', action: :show, as: '', constraints: page_constraint
36
+ end
37
+ resources :posts, except: [:index, :show], path: ''
24
38
  end
25
39
  end
26
40
 
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  class CreateThredded < ActiveRecord::Migration
2
3
  def change
3
-
4
4
  unless table_exists?(:friendly_id_slugs)
5
5
  # The user might have installed FriendlyId separately already.
6
6
  create_table :friendly_id_slugs do |t|
7
- t.string :slug, limit: 255, null: false
7
+ t.string :slug, limit: 191, null: false
8
8
  t.integer :sluggable_id, null: false
9
9
  t.string :sluggable_type, limit: 50
10
10
  t.string :scope, limit: 191
@@ -18,14 +18,14 @@ class CreateThredded < ActiveRecord::Migration
18
18
 
19
19
  create_table :thredded_categories do |t|
20
20
  t.integer :messageboard_id, null: false
21
- t.string :name, limit: 255, null: false
21
+ t.string :name, limit: 191, null: false
22
22
  t.string :description, limit: 255
23
23
  t.timestamps null: false
24
24
  t.string :slug, limit: 191, null: false
25
25
  end
26
26
  add_index :thredded_categories, [:messageboard_id, :slug], name: :index_thredded_categories_on_messageboard_id_and_slug, unique: true
27
27
  add_index :thredded_categories, [:messageboard_id], name: :index_thredded_categories_on_messageboard_id
28
- DbTextSearch::CaseInsensitiveEq.add_index connection, :thredded_categories, :name, name: :thredded_categories_name_ci
28
+ DbTextSearch::CaseInsensitive.add_index connection, :thredded_categories, :name, name: :thredded_categories_name_ci
29
29
 
30
30
  create_table :thredded_messageboards do |t|
31
31
  t.string :name, limit: 255, null: false
@@ -35,34 +35,22 @@ class CreateThredded < ActiveRecord::Migration
35
35
  t.integer :posts_count, default: 0
36
36
  t.boolean :closed, default: false, null: false
37
37
  t.timestamps null: false
38
- t.string :filter, limit: 255, default: 'markdown', null: false
39
38
  end
40
39
  add_index :thredded_messageboards, [:closed], name: :index_thredded_messageboards_on_closed
41
40
  add_index :thredded_messageboards, [:slug], name: :index_thredded_messageboards_on_slug
42
41
 
43
- create_table :thredded_notification_preferences do |t|
44
- t.boolean :notify_on_mention, default: true
45
- t.boolean :notify_on_message, default: true
46
- t.integer :user_id, null: false
47
- t.integer :messageboard_id, null: false
48
- t.timestamps null: false
49
- end
50
- add_index :thredded_notification_preferences, [:messageboard_id], name: :index_thredded_notification_preferences_on_messageboard_id
51
- add_index :thredded_notification_preferences, [:user_id], name: :index_thredded_notification_preferences_on_user_id
52
-
53
42
  create_table :thredded_post_notifications do |t|
54
- t.string :email, limit: 255, null: false
43
+ t.string :email, limit: 191, null: false
55
44
  t.integer :post_id, null: false
56
45
  t.timestamps null: false
57
- t.string :post_type, limit: 255
46
+ t.string :post_type, limit: 191
58
47
  end
59
48
  add_index :thredded_post_notifications, [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
60
49
 
61
50
  create_table :thredded_posts do |t|
62
51
  t.integer :user_id, limit: 4
63
- t.text :content, limit: 65535
52
+ t.text :content, limit: 65_535
64
53
  t.string :ip, limit: 255
65
- t.string :filter, limit: 255, default: 'markdown'
66
54
  t.string :source, limit: 255, default: 'web'
67
55
  t.integer :postable_id, limit: 4
68
56
  t.integer :messageboard_id, null: false
@@ -72,13 +60,12 @@ class CreateThredded < ActiveRecord::Migration
72
60
  add_index :thredded_posts, [:postable_id], name: :index_thredded_posts_on_postable_id
73
61
  add_index :thredded_posts, [:postable_id], name: :index_thredded_posts_on_postable_id_and_postable_type
74
62
  add_index :thredded_posts, [:user_id], name: :index_thredded_posts_on_user_id
75
- DbTextSearch::FullTextSearch.add_index connection, :thredded_posts, :content, name: :thredded_posts_content_fts
63
+ DbTextSearch::FullText.add_index connection, :thredded_posts, :content, name: :thredded_posts_content_fts
76
64
 
77
65
  create_table :thredded_private_posts do |t|
78
66
  t.integer :user_id, limit: 4
79
- t.text :content, limit: 65535
67
+ t.text :content, limit: 65_535
80
68
  t.string :ip, limit: 255
81
- t.string :filter, limit: 255, default: 'markdown'
82
69
  t.integer :postable_id, null: false
83
70
  t.timestamps null: false
84
71
  end
@@ -99,10 +86,8 @@ class CreateThredded < ActiveRecord::Migration
99
86
  t.integer :private_topic_id, limit: 4
100
87
  t.integer :user_id, limit: 4
101
88
  t.timestamps null: false
102
- t.boolean :read, default: false
103
89
  end
104
90
  add_index :thredded_private_users, [:private_topic_id], name: :index_thredded_private_users_on_private_topic_id
105
- add_index :thredded_private_users, [:read], name: :index_thredded_private_users_on_read
106
91
  add_index :thredded_private_users, [:user_id], name: :index_thredded_private_users_on_user_id
107
92
 
108
93
  create_table :thredded_topic_categories do |t|
@@ -129,7 +114,7 @@ class CreateThredded < ActiveRecord::Migration
129
114
  add_index :thredded_topics, [:messageboard_id, :slug], name: :index_thredded_topics_on_messageboard_id_and_slug, unique: true
130
115
  add_index :thredded_topics, [:messageboard_id], name: :index_thredded_topics_on_messageboard_id
131
116
  add_index :thredded_topics, [:user_id], name: :index_thredded_topics_on_user_id
132
- DbTextSearch::FullTextSearch.add_index connection, :thredded_topics, :title, name: :thredded_topics_title_fts
117
+ DbTextSearch::FullText.add_index connection, :thredded_topics, :title, name: :thredded_topics_title_fts
133
118
 
134
119
  create_table :thredded_user_details do |t|
135
120
  t.integer :user_id, null: false
@@ -154,20 +139,31 @@ class CreateThredded < ActiveRecord::Migration
154
139
 
155
140
  create_table :thredded_user_preferences do |t|
156
141
  t.integer :user_id, null: false
157
- t.string :time_zone, limit: 191, default: 'Eastern Time (US & Canada)'
142
+ t.boolean :notify_on_mention, default: true, null: false
143
+ t.boolean :notify_on_message, default: true, null: false
158
144
  t.timestamps null: false
159
145
  end
160
146
  add_index :thredded_user_preferences, [:user_id], name: :index_thredded_user_preferences_on_user_id
161
147
 
162
- create_table :thredded_user_topic_reads do |t|
148
+ create_table :thredded_user_messageboard_preferences do |t|
163
149
  t.integer :user_id, null: false
164
- t.integer :topic_id, null: false
165
- t.integer :post_id, null: false
166
- t.integer :posts_count, default: 0, null: false
167
- t.integer :page, default: 1, null: false
150
+ t.integer :messageboard_id, null: false
151
+ t.boolean :notify_on_mention, default: true, null: false
168
152
  t.timestamps null: false
169
153
  end
170
- add_index :thredded_user_topic_reads, [:topic_id], name: :index_thredded_user_topic_reads_on_topic_id
171
- add_index :thredded_user_topic_reads, [:user_id, :topic_id], name: :index_thredded_user_topic_reads_on_user_id_and_topic_id, unique: true
154
+ add_index :thredded_user_messageboard_preferences, [:user_id, :messageboard_id],
155
+ unique: true,
156
+ name: :thredded_user_messageboard_preferences_user_id_messageboard_id
157
+
158
+ %i(topic private_topic).each do |topics_table|
159
+ table_name = :"thredded_user_#{topics_table}_read_states"
160
+ create_table table_name do |t|
161
+ t.integer :user_id, null: false
162
+ t.integer :postable_id, null: false
163
+ t.integer :page, default: 1, null: false
164
+ t.timestamp :read_at, null: false
165
+ end
166
+ add_index table_name, [:user_id, :postable_id], name: :"#{table_name}_user_postable", unique: true
167
+ end
172
168
  end
173
169
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+ require 'factory_girl_rails'
3
+
4
+ # rubocop:disable HandleExceptions
5
+ begin
6
+ if FactoryGirl.factories.instance_variable_get(:@items).none?
7
+ require_relative '../spec/factories'
8
+ end
9
+ rescue NameError
10
+ end
11
+ # rubocop:enable HandleExceptions
12
+
13
+ module Thredded
14
+ class SeedDatabase
15
+ attr_reader :user, :users, :messageboard, :topics, :private_topics, :posts
16
+
17
+ SKIP_CALLBACKS = [
18
+ [Thredded::Post, :commit, :after, :notify_at_users],
19
+ [Thredded::PrivatePost, :commit, :after, :notify_at_users],
20
+ ].freeze
21
+
22
+ def self.run(users: 200, topics: 55, posts: (1..60))
23
+ STDERR.puts 'Seeding the database...'
24
+ # Disable callbacks to avoid creating notifications and performing unnecessary updates
25
+ SKIP_CALLBACKS.each { |(klass, *args)| klass.skip_callback(*args) }
26
+ s = new
27
+ Messageboard.transaction do
28
+ s.create_first_user
29
+ s.create_users(count: users)
30
+ s.create_messageboard
31
+ s.create_topics(count: topics)
32
+ s.create_posts(count: posts)
33
+ s.create_private_posts(count: posts)
34
+ s.create_additional_messageboards
35
+ s.log 'Running after_commit callbacks'
36
+ end
37
+ ensure
38
+ # Re-enable callbacks
39
+ SKIP_CALLBACKS.each { |(klass, *args)| klass.set_callback(*args) }
40
+ end
41
+
42
+ def log(message)
43
+ STDERR.puts "- #{message}"
44
+ end
45
+
46
+ def create_first_user
47
+ @user ||= begin
48
+ ::User.first ||
49
+ ::User.create(name: 'Joe', email: 'joe@example.com')
50
+ end
51
+ end
52
+
53
+ def create_users(count: 5)
54
+ log "Creating #{count} users..."
55
+ @users = [user] + FactoryGirl.create_list(:user, count)
56
+ end
57
+
58
+ def create_messageboard
59
+ log 'Creating a messageboard...'
60
+ @messageboard = FactoryGirl.create(
61
+ :messageboard,
62
+ name: 'Main Board',
63
+ slug: 'main-board',
64
+ description: 'A board is not a board without some posts'
65
+ )
66
+ end
67
+
68
+ def create_additional_messageboards
69
+ additional_messageboards = [
70
+ ['Off-Topic', "Talk about whatever here, it's all good."],
71
+ ['Meta', 'Need help using the forum? Want to report a bug or make a suggestion? This is the place.']
72
+ ]
73
+ log "Creating #{additional_messageboards.length} additional messageboards..."
74
+ additional_messageboards.each do |(name, description)|
75
+ messageboard = Messageboard.create!(name: name, description: description)
76
+ FactoryGirl.create_list(:topic, 1 + rand(3), messageboard: messageboard, with_posts: 1)
77
+ end
78
+ end
79
+
80
+ def create_topics(count: 26, messageboard: self.messageboard)
81
+ log "Creating #{count} topics in #{messageboard.name}..."
82
+ @topics = FactoryGirl.create_list(
83
+ :topic, count,
84
+ messageboard: messageboard,
85
+ user: users.sample,
86
+ last_user: users.sample)
87
+
88
+ @private_topics = FactoryGirl.create_list(
89
+ :private_topic, count,
90
+ user: users.sample,
91
+ last_user: users.sample,
92
+ users: [user])
93
+ end
94
+
95
+ def create_posts(count: (1..30))
96
+ log "Creating #{count} additional posts in each topic..."
97
+ @posts = topics.flat_map do |topic|
98
+ (count.min + rand(count.max + 1)).times do
99
+ FactoryGirl.create(:post, postable: topic, messageboard: messageboard, user: users.sample)
100
+ end
101
+ end
102
+ end
103
+
104
+ def create_private_posts(count: (1..30))
105
+ log "Creating #{count} additional posts in each private topic..."
106
+ @private_posts = private_topics.flat_map do |topic|
107
+ (count.min + rand(count.max + 1)).times do
108
+ FactoryGirl.create(:private_post, postable: topic, user: users.sample)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ Thredded::SeedDatabase.run
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ class UpgradeV02ToV03 < ActiveRecord::Migration
3
+ def up
4
+ remove_index :thredded_notification_preferences, name: :index_thredded_notification_preferences_on_messageboard_id
5
+ remove_index :thredded_notification_preferences, name: :index_thredded_notification_preferences_on_user_id
6
+ rename_table :thredded_notification_preferences, :thredded_user_messageboard_preferences
7
+ remove_column :thredded_user_messageboard_preferences, :notify_on_message
8
+ change_column_null :thredded_user_messageboard_preferences, :notify_on_mention, false
9
+ add_column :thredded_user_preferences, :notify_on_mention, :boolean, default: true, null: false
10
+ add_column :thredded_user_preferences, :notify_on_message, :boolean, default: true, null: false
11
+ add_index :thredded_user_messageboard_preferences, [:user_id, :messageboard_id], unique: true, name: :thredded_user_messageboard_preferences_user_id_messageboard_id
12
+ remove_column :thredded_user_preferences, :time_zone
13
+ remove_column :thredded_messageboards, :filter
14
+ remove_column :thredded_posts, :filter
15
+ remove_column :thredded_private_posts, :filter
16
+ drop_table :thredded_user_topic_reads
17
+ %i(topic private_topic).each do |topics_table|
18
+ table_name = :"thredded_user_#{topics_table}_read_states"
19
+ create_table table_name do |t|
20
+ t.integer :user_id, null: false
21
+ t.integer :postable_id, null: false
22
+ t.integer :page, default: 1, null: false
23
+ t.timestamp :read_at, null: false
24
+ end
25
+ add_index table_name, [:user_id, :postable_id], name: :"#{table_name}_user_postable", unique: true
26
+ end
27
+ remove_column :thredded_private_users, :read
28
+ remove_index :thredded_private_users, name: :index_thredded_private_users_on_read
29
+ end
30
+
31
+ def down
32
+ add_column :thredded_private_users, :read, :boolean, default: false
33
+ add_index :thredded_private_users, :read, name: :index_thredded_private_users_on_read
34
+ drop_table :thredded_user_topic_read_states
35
+ drop_table :thredded_user_private_topic_read_states
36
+ create_table :thredded_user_topic_reads do |t|
37
+ t.integer :user_id, null: false
38
+ t.integer :topic_id, null: false
39
+ t.integer :post_id, null: false
40
+ t.integer :posts_count, default: 0, null: false
41
+ t.integer :page, default: 1, null: false
42
+ t.timestamps null: false
43
+ end
44
+ add_index :thredded_user_topic_reads, [:topic_id], name: :index_thredded_user_topic_reads_on_topic_id
45
+ add_index :thredded_user_topic_reads, [:user_id, :topic_id], name: :index_thredded_user_topic_reads_on_user_id_and_topic_id, unique: true
46
+ add_column :thredded_private_posts, :filter, :string, default: 'markdown', null: false
47
+ add_column :thredded_posts, :filter, :string, default: 'markdown', null: false
48
+ add_column :thredded_messageboards, :filter, :string, default: 'markdown', null: false
49
+ add_column :thredded_user_preferences, :time_zone, :string, limit: 191, default: 'Eastern Time (US & Canada)'
50
+ change_column_null :thredded_user_messageboard_preferences, :notify_on_mention, true
51
+ remove_index :thredded_user_messageboard_preferences, name: :thredded_user_messageboard_preferences_user_id_messageboard_id
52
+ rename_table :thredded_user_messageboard_preferences, :thredded_notification_preferences
53
+ add_index :thredded_notification_preferences, [:messageboard_id], name: :index_thredded_notification_preferences_on_messageboard_id
54
+ add_index :thredded_notification_preferences, [:user_id], name: :index_thredded_notification_preferences_on_user_id
55
+ add_column :thredded_notification_preferences, :notify_on_message, :boolean, default: true
56
+ remove_column :thredded_user_preferences, :notify_on_mention
57
+ remove_column :thredded_user_preferences, :notify_on_message
58
+ end
59
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ source 'https://rubygems.org'
3
+ ruby '2.3.0'
4
+
5
+ gem 'thredded', path: File.dirname(__FILE__)
6
+
7
+ # Rails 5
8
+ gem 'rails', git: 'https://github.com/rails/rails'
9
+ gem 'kaminari', git: 'https://github.com/amatsuda/kaminari'
10
+ gem 'active_record_union', git: 'https://github.com/glebm/active_record_union', branch: 'rails-5-test-harness'
11
+
12
+ # Make these gems available in production
13
+ gem 'puma'
14
+ gem 'pg'
15
+ gem 'rails_email_preview', '>= 1.0.3'
16
+ gem 'jquery-turbolinks'
17
+ gem 'turbolinks'
18
+ gem 'factory_girl_rails'
19
+ gem 'faker', '>= 1.6.2'
20
+
21
+ # Heroku-specific gems
22
+ gem 'newrelic_rpm'
23
+ gem 'rollbar'
24
+ gem 'therubyracer'
25
+ gem 'rack-canonical-host'
26
+ gem 'dalli'
@@ -0,0 +1,282 @@
1
+ GIT
2
+ remote: https://github.com/amatsuda/kaminari
3
+ revision: 772de7ccea717ad74524163fa6ae9601efc87c2f
4
+ specs:
5
+ kaminari (1.0.0.alpha)
6
+ actionpack (>= 3.0.0)
7
+ activesupport (>= 3.0.0)
8
+
9
+ GIT
10
+ remote: https://github.com/glebm/active_record_union
11
+ revision: fde21fb8fe7d5d3cc24f1dc5d6627d92c30f10e5
12
+ branch: rails-5-test-harness
13
+ specs:
14
+ active_record_union (1.1.1)
15
+ activerecord (>= 4.0)
16
+
17
+ GIT
18
+ remote: https://github.com/rails/rails
19
+ revision: 597fa0b42f90bbef6a8c7628d4e08fb132fba887
20
+ specs:
21
+ actioncable (5.0.0.beta3)
22
+ actionpack (= 5.0.0.beta3)
23
+ nio4r (~> 1.2)
24
+ websocket-driver (~> 0.6.1)
25
+ actionmailer (5.0.0.beta3)
26
+ actionpack (= 5.0.0.beta3)
27
+ actionview (= 5.0.0.beta3)
28
+ activejob (= 5.0.0.beta3)
29
+ mail (~> 2.5, >= 2.5.4)
30
+ rails-dom-testing (~> 1.0, >= 1.0.5)
31
+ actionpack (5.0.0.beta3)
32
+ actionview (= 5.0.0.beta3)
33
+ activesupport (= 5.0.0.beta3)
34
+ rack (~> 2.x)
35
+ rack-test (~> 0.6.3)
36
+ rails-dom-testing (~> 1.0, >= 1.0.5)
37
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
38
+ actionview (5.0.0.beta3)
39
+ activesupport (= 5.0.0.beta3)
40
+ builder (~> 3.1)
41
+ erubis (~> 2.7.0)
42
+ rails-dom-testing (~> 1.0, >= 1.0.5)
43
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
44
+ activejob (5.0.0.beta3)
45
+ activesupport (= 5.0.0.beta3)
46
+ globalid (>= 0.3.6)
47
+ activemodel (5.0.0.beta3)
48
+ activesupport (= 5.0.0.beta3)
49
+ activerecord (5.0.0.beta3)
50
+ activemodel (= 5.0.0.beta3)
51
+ activesupport (= 5.0.0.beta3)
52
+ arel (~> 7.0)
53
+ activesupport (5.0.0.beta3)
54
+ concurrent-ruby (~> 1.0)
55
+ i18n (~> 0.7)
56
+ minitest (~> 5.1)
57
+ tzinfo (~> 1.1)
58
+ rails (5.0.0.beta3)
59
+ actioncable (= 5.0.0.beta3)
60
+ actionmailer (= 5.0.0.beta3)
61
+ actionpack (= 5.0.0.beta3)
62
+ actionview (= 5.0.0.beta3)
63
+ activejob (= 5.0.0.beta3)
64
+ activemodel (= 5.0.0.beta3)
65
+ activerecord (= 5.0.0.beta3)
66
+ activesupport (= 5.0.0.beta3)
67
+ bundler (>= 1.3.0, < 2.0)
68
+ railties (= 5.0.0.beta3)
69
+ sprockets-rails (>= 2.0.0)
70
+ railties (5.0.0.beta3)
71
+ actionpack (= 5.0.0.beta3)
72
+ activesupport (= 5.0.0.beta3)
73
+ method_source
74
+ rake (>= 0.8.7)
75
+ thor (>= 0.18.1, < 2.0)
76
+
77
+ PATH
78
+ remote: .
79
+ specs:
80
+ thredded (0.2.2)
81
+ active_record_union (>= 1.1.1)
82
+ autoprefixer-rails
83
+ autosize-rails
84
+ bbcoder (~> 1.0)
85
+ db_text_search (~> 0.2.0)
86
+ friendly_id
87
+ gemoji
88
+ github-markdown
89
+ html-pipeline
90
+ html-pipeline-vimeo
91
+ html-pipeline-youtube
92
+ htmlentities
93
+ inline_svg
94
+ jquery-rails
95
+ kaminari
96
+ nokogiri
97
+ pundit (>= 1.1.0)
98
+ rails (>= 4.2.0)
99
+ rails-timeago
100
+ rb-gravatar
101
+ rinku
102
+ sanitize
103
+ sass (>= 3.4.21)
104
+ select2-rails (~> 3.5)
105
+ sprockets-es6
106
+
107
+ GEM
108
+ remote: https://rubygems.org/
109
+ specs:
110
+ addressable (2.4.0)
111
+ arel (7.0.0)
112
+ autoprefixer-rails (6.3.6)
113
+ execjs
114
+ autosize-rails (1.18.17)
115
+ rails (>= 3.1)
116
+ babel-source (5.8.35)
117
+ babel-transpiler (0.7.0)
118
+ babel-source (>= 4.0, < 6)
119
+ execjs (~> 2.0)
120
+ bbcoder (1.1.1)
121
+ builder (3.2.2)
122
+ coffee-rails (4.1.1)
123
+ coffee-script (>= 2.2.0)
124
+ railties (>= 4.0.0, < 5.1.x)
125
+ coffee-script (2.4.1)
126
+ coffee-script-source
127
+ execjs
128
+ coffee-script-source (1.10.0)
129
+ concurrent-ruby (1.0.1)
130
+ crass (1.0.2)
131
+ dalli (2.7.6)
132
+ db_text_search (0.2.0)
133
+ activerecord (>= 4.1.15, < 6.0)
134
+ erubis (2.7.0)
135
+ execjs (2.6.0)
136
+ factory_girl (4.7.0)
137
+ activesupport (>= 3.0.0)
138
+ factory_girl_rails (4.7.0)
139
+ factory_girl (~> 4.7.0)
140
+ railties (>= 3.0.0)
141
+ faker (1.6.3)
142
+ i18n (~> 0.5)
143
+ friendly_id (5.1.0)
144
+ activerecord (>= 4.0.0)
145
+ gemoji (2.1.0)
146
+ github-markdown (0.6.9)
147
+ globalid (0.3.6)
148
+ activesupport (>= 4.1.0)
149
+ html-pipeline (2.4.0)
150
+ activesupport (>= 2, < 5)
151
+ nokogiri (>= 1.4)
152
+ html-pipeline-vimeo (0.1.1)
153
+ html-pipeline (~> 2.0)
154
+ html-pipeline-youtube (0.1.2)
155
+ html-pipeline (~> 2.0)
156
+ htmlentities (4.3.4)
157
+ i18n (0.7.0)
158
+ inline_svg (0.6.3)
159
+ activesupport (>= 4.0.4)
160
+ loofah (>= 2.0)
161
+ nokogiri (~> 1.6)
162
+ jquery-rails (4.1.1)
163
+ rails-dom-testing (>= 1, < 3)
164
+ railties (>= 4.2.0)
165
+ thor (>= 0.14, < 2.0)
166
+ jquery-turbolinks (2.1.0)
167
+ railties (>= 3.1.0)
168
+ turbolinks
169
+ json (1.8.3)
170
+ libv8 (3.16.14.13)
171
+ loofah (2.0.3)
172
+ nokogiri (>= 1.5.9)
173
+ mail (2.6.4)
174
+ mime-types (>= 1.16, < 4)
175
+ method_source (0.8.2)
176
+ mime-types (3.0)
177
+ mime-types-data (~> 3.2015)
178
+ mime-types-data (3.2016.0221)
179
+ mini_portile2 (2.0.0)
180
+ minitest (5.8.4)
181
+ multi_json (1.11.2)
182
+ newrelic_rpm (3.15.1.316)
183
+ nio4r (1.2.1)
184
+ nokogiri (1.6.7.2)
185
+ mini_portile2 (~> 2.0.0.rc2)
186
+ nokogumbo (1.4.7)
187
+ nokogiri
188
+ pg (0.18.4)
189
+ puma (3.4.0)
190
+ pundit (1.1.0)
191
+ activesupport (>= 3.0.0)
192
+ rack (2.0.0.alpha)
193
+ json
194
+ rack-canonical-host (0.2.1)
195
+ addressable (> 0, < 3)
196
+ rack (>= 1.0.0, < 3)
197
+ rack-test (0.6.3)
198
+ rack (>= 1.0)
199
+ rails-deprecated_sanitizer (1.0.3)
200
+ activesupport (>= 4.2.0.alpha)
201
+ rails-dom-testing (1.0.7)
202
+ activesupport (>= 4.2.0.beta, < 5.0)
203
+ nokogiri (~> 1.6.0)
204
+ rails-deprecated_sanitizer (>= 1.0.1)
205
+ rails-html-sanitizer (1.0.3)
206
+ loofah (~> 2.0)
207
+ rails-timeago (2.13.0)
208
+ actionpack (>= 3.1)
209
+ activesupport (>= 3.1)
210
+ rails_email_preview (1.0.3)
211
+ rails (>= 3.2)
212
+ request_store
213
+ sass-rails
214
+ turbolinks
215
+ rake (11.1.2)
216
+ rb-gravatar (1.0.5)
217
+ ref (2.0.0)
218
+ request_store (1.3.1)
219
+ rinku (1.7.3)
220
+ rollbar (2.9.1)
221
+ multi_json
222
+ sanitize (4.0.1)
223
+ crass (~> 1.0.2)
224
+ nokogiri (>= 1.4.4)
225
+ nokogumbo (~> 1.4.1)
226
+ sass (3.4.22)
227
+ sass-rails (5.0.4)
228
+ railties (>= 4.0.0, < 5.0)
229
+ sass (~> 3.1)
230
+ sprockets (>= 2.8, < 4.0)
231
+ sprockets-rails (>= 2.0, < 4.0)
232
+ tilt (>= 1.1, < 3)
233
+ select2-rails (3.5.10)
234
+ thor (~> 0.14)
235
+ sprockets (3.6.0)
236
+ concurrent-ruby (~> 1.0)
237
+ rack (> 1, < 3)
238
+ sprockets-es6 (0.9.0)
239
+ babel-source (>= 5.8.11)
240
+ babel-transpiler
241
+ sprockets (>= 3.0.0)
242
+ sprockets-rails (3.0.4)
243
+ actionpack (>= 4.0)
244
+ activesupport (>= 4.0)
245
+ sprockets (>= 3.0.0)
246
+ therubyracer (0.12.2)
247
+ libv8 (~> 3.16.14.0)
248
+ ref
249
+ thor (0.19.1)
250
+ thread_safe (0.3.5)
251
+ tilt (2.0.2)
252
+ turbolinks (2.5.3)
253
+ coffee-rails
254
+ tzinfo (1.2.2)
255
+ thread_safe (~> 0.1)
256
+ websocket-driver (0.6.3)
257
+ websocket-extensions (>= 0.1.0)
258
+ websocket-extensions (0.1.2)
259
+
260
+ PLATFORMS
261
+ ruby
262
+
263
+ DEPENDENCIES
264
+ active_record_union!
265
+ dalli
266
+ factory_girl_rails
267
+ faker (>= 1.6.2)
268
+ jquery-turbolinks
269
+ kaminari!
270
+ newrelic_rpm
271
+ pg
272
+ puma
273
+ rack-canonical-host
274
+ rails!
275
+ rails_email_preview (>= 1.0.3)
276
+ rollbar
277
+ therubyracer
278
+ thredded!
279
+ turbolinks
280
+
281
+ BUNDLED WITH
282
+ 1.11.2