thredded 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bdc0bf6e1d3f247baed2faa7a7a4250f28d8f86a
4
- data.tar.gz: f0b738be8742980e4758c9f4514eb75439f77e2c
3
+ metadata.gz: 2c6816b0184d085f43b52bbccd55cb54423d3533
4
+ data.tar.gz: 8a454d07c634eb9fa25836a8722c4a340b1a078d
5
5
  SHA512:
6
- metadata.gz: 7e2d79cc9507fe73ce4fd3c373bb0517da2e4cd1147a347a16c2653453a903f4d7de8ae0ee4ea070cc3004afea220de682ae489a964ffe98669b351368fbf553
7
- data.tar.gz: 07cf1575cd4cf81cd5eb601a709ce556183cf0e54f3f03f67d58bfbe4b43a43fb2aa50eab19650fea02d8910237e2654759c5a7bd1fc5d3aa79fcff69bd939c0
6
+ metadata.gz: b81ea1816ea5cf2d24b45636336bd47565e7dd7197ed89f365ae845502b5050784b8ff02506ad6cc4a678fd2bf3c214cd689387233aa98aa575110a856a026f8
7
+ data.tar.gz: f5ff0cfccb540a68da5670085b0f380b988edc37b05aee2f3fc35099ff123cca1f88ea67dd91db391f77fc62bc938fa08851b9317ac6ce3e176d65b64a5541ce
@@ -1,5 +1,68 @@
1
1
  # MASTER
2
2
 
3
+ ## Fixed
4
+
5
+ * TBD
6
+
7
+ ## Added
8
+
9
+ * TBD
10
+
11
+ ## Changed
12
+
13
+ * TBD
14
+
15
+
16
+ # 0.3.0 - 2016-04-22
17
+
18
+ Thredded now supports Rails 4.2+ only.
19
+
20
+ Thredded now also fully supports the latest Rails 5 beta, but currently this requires using master versions of certain
21
+ gems. See [rails_5_0.gemfile](https://github.com/thredded/thredded/blob/master/spec/gemfiles/rails_5_0.gemfile)
22
+ for more information.
23
+
24
+ ## Fixed
25
+
26
+ * (Private)Topic slugs re-generate at appropriate time
27
+ [28c09f4](https://github.com/thredded/thredded/commit/28c09f40804d3a71bbc12c56819a8acab3c94f2d)
28
+ * Editing topics and private message subjects. [#235](https://github.com/thredded/thredded/pull/235)
29
+ * Require login for `PrivateTopicsController`.
30
+ [5739f5](https://github.com/thredded/thredded/commit/5739f50a513377392205a41958b5a2d3ca25dc10)
31
+ * Current user method now configurable via initializer.
32
+ [#234](https://github.com/thredded/thredded/pull/234)
33
+ * Pagination and possible route conflicts throughout. [#202](https://github.com/thredded/thredded/pull/202)
34
+ * Redirects to the correct page after posting a reply. [#205](https://github.com/thredded/thredded/pull/205)
35
+ * Search with special `by:user` and `in:category` qualifiers. [#206](https://github.com/thredded/thredded/pull/206)
36
+ * Private topics now validate presence of at least one user other than the creator. [#207](https://github.com/thredded/thredded/pull/207)
37
+ * "Not found" and "Permission denied" errors now render with the correct response codes. [#208](https://github.com/thredded/thredded/pull/208)
38
+ * Thredded user associations are now correctly nullified / destroyed when a user is destroyed in the parent app.
39
+
40
+ ## Added
41
+
42
+ * Dummy App renamed to "Thredded Demo" and demo deployed to Heroku
43
+ * Added vimeo and youtube auto-embed support. [#216](https://github.com/thredded/thredded/pull/216)
44
+ * Ability to delete posts. [#214](https://github.com/thredded/thredded/pull/214)
45
+ * Global search across all messageboards. [#215](https://github.com/thredded/thredded/pull/215)
46
+ * Global notification settings, message notification settings. [#210](https://github.com/thredded/thredded/pull/210)
47
+ * Private topic user select now looks prettier and loads the user via AJAX, instead of generating a huge select with all
48
+ the users. [#199](https://github.com/thredded/thredded/pull/199).
49
+ * The theme is now more customizable thanks to a number of fixes and new variables. [#197](https://github.com/thredded/thredded/pull/197)
50
+ * The topic read state is now visually updated on click. [#198](https://github.com/thredded/thredded/pull/198)
51
+ * Email preview classes are now provided. [#196](https://github.com/thredded/thredded/pull/196).
52
+ * I18n'd a *bunch* of static copy. (Thanks @glebm!)
53
+
54
+ ## Changed
55
+
56
+ * Navigation layout/design updated [ec699fd](https://github.com/thredded/thredded/commit/ec699fd)
57
+ * Changed from using Bbcode OR Markdown to *both*, simultaneously.
58
+ [#221](https://github.com/thredded/thredded/pull/221)
59
+ * Removed Timecop in favor of built-in rails `travel_to` helper.
60
+ [#226](https://github.com/thredded/thredded/pull/226)
61
+ * Moved from CanCanCan to Pundit. [#228](https://github.com/thredded/thredded/pull/228)
62
+ * Renamed "Private Topics" to "Private Messages"
63
+ * Renamed `$thredded-base-font-color` to `$thredded-text-color`.
64
+ * Renamed `$thredded-base-background-color` to `$thredded-background-color`.
65
+
3
66
  # 0.2.2 - 2016-04-04
4
67
 
5
68
  ## Fixed
@@ -0,0 +1 @@
1
+ web: bundle exec puma -C ./spec/dummy/config/puma.heroku.rb
@@ -1,6 +1,6 @@
1
- # Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=master)](https://travis-ci.org/thredded/thredded/) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1
+ # Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=master)](https://travis-ci.org/thredded/thredded/) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Stories in Ready](https://badge.waffle.io/thredded/thredded.svg?label=ready&title=waffle.io)](http://waffle.io/thredded/thredded)
2
2
 
3
- _Thredded_ is a Rails 4.1+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
3
+ _Thredded_ is a Rails 4.2+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
4
4
 
5
5
  Some of the features currently in Thredded:
6
6
 
@@ -22,8 +22,15 @@ Planned features:
22
22
 
23
23
  <img src="http://emoji.fileformat.info/gemoji/point_up.png" width="24"> If you are so inclined, donating to the project will help aid in its development
24
24
 
25
- [Discourse]: http://www.discourse.org/
26
- [Forem]: https://www.github.com/radar/forem
25
+
26
+ | ![screenshot-messageboards] | ![screenshot-topics] |
27
+ |----------------------------|----------------------------|
28
+ | ![screenshot-topic] | ![screenshot-new-private-topic-dark] |
29
+
30
+ [screenshot-messageboards]: https://cloud.githubusercontent.com/assets/216339/14379803/d608d782-fd73-11e5-9d8e-1f282ea66fab.png
31
+ [screenshot-topics]: https://cloud.githubusercontent.com/assets/216339/14379804/d77db060-fd73-11e5-9a4a-9376ca409756.png
32
+ [screenshot-topic]: https://cloud.githubusercontent.com/assets/216339/14379805/d8ecf32a-fd73-11e5-8734-b7faa8b264ee.png
33
+ [screenshot-new-private-topic-dark]: https://cloud.githubusercontent.com/assets/216339/14379806/da716a1e-fd73-11e5-90f1-6dbdb708d3d5.png
27
34
 
28
35
  Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. Thredded has no infrastructure
29
36
  dependencies other than the database and, if configured in the parent application, the ActiveJob
@@ -33,6 +40,9 @@ support JRuby and Rubinius as well.
33
40
  If you're looking for variations on a theme - see [Forem] and [Discourse]. Forem is also an engine,
34
41
  while Discourse is a full app.
35
42
 
43
+ [Discourse]: http://www.discourse.org/
44
+ [Forem]: https://github.com/rubysherpas/forem
45
+
36
46
  ## Installation
37
47
 
38
48
  Add the gem to your Gemfile:
@@ -80,8 +90,24 @@ Include thredded JavaScripts in your `application.js`:
80
90
  //= require thredded
81
91
  ```
82
92
 
93
+ You also may want to add an index to the user name column in your users table.
94
+ Thredded uses it to find @-mentions and perform name prefix autocompletion on the private topic form.
95
+ Add the index in a migration like so:
96
+
97
+ ```ruby
98
+ DbTextSearch::CaseInsensitive.add_index(
99
+ connection, Thredded.user_class.table_name, Thredded.user_name_column, unique: true)
100
+ ```
101
+
83
102
  [initializer]: https://github.com/thredded/thredded/blob/master/lib/generators/thredded/install/templates/initializer.rb
84
103
 
104
+ ### Migrating from Forem
105
+
106
+ Using [Forem]? Thredded provides [a migration][forem-to-thredded] to copy all your existing forums from Forem over
107
+ to Thredded.
108
+
109
+ [forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem
110
+
85
111
  ## Theming
86
112
 
87
113
  The engine comes by default with a light and effective implementation of the
@@ -139,6 +165,14 @@ Whenever possible, use the styles and i18n to customize Thredded to your needs.
139
165
  Thredded views also provide two content_tags available to yield - `:thredded_page_title` and `:thredded_page_id`.
140
166
  The views within Thredded pass those up through to your layout if you would like to use them.
141
167
 
168
+ ### Emails
169
+
170
+ Thredded sends several notification emails to the users. You can override in the same way as the views.
171
+ If you use [Rails Email Preview], you can include Thredded emails into the list of previews by adding
172
+ `Thredded::BaseMailerPreview.preview_classes` to the [Rails Email Preview] `preview_classes` config option.
173
+
174
+ [Rails Email Preview]: https://github.com/glebm/rails_email_preview
175
+
142
176
  ## Permissions
143
177
 
144
178
  Thredded comes with a flexible permissions system that can be configured per messageboard/user.
@@ -259,7 +293,7 @@ Below is an overview of the default permissions, with links to the implementatio
259
293
  <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/write/none.rb">
260
294
  ❌ No
261
295
  </a></td>
262
- <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/message/none.rb">
296
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb">
263
297
  ❌ No
264
298
  </a></td>
265
299
  <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/moderate/none.rb">
@@ -274,7 +308,7 @@ Below is an overview of the default permissions, with links to the implementatio
274
308
 
275
309
  ### Handling "Permission denied"
276
310
 
277
- Thredded defines a number of Exception classes that you can `[rescue_from]` in your `ApplicationController`
311
+ Thredded defines a number of Exception classes that you can [`rescue_from`][rescue_from] in your `ApplicationController`
278
312
  to handle permission denied errors.
279
313
 
280
314
  These are:
@@ -290,17 +324,6 @@ Currently, the default behaviour is to redirect to the forums root page with a f
290
324
 
291
325
  [rescue_from]: http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html
292
326
 
293
- ## Rails 4.1 and ActiveJob Support
294
-
295
- If you're currently using Rails 4.1 make sure to add ...
296
-
297
- ```ruby
298
- gem 'activejob_backport'
299
- ```
300
-
301
- ... to your Gemfile. ActiveJob is now the main background job abstraction layer in Thredded.
302
- It was not introduced to rails until 4.2 so you'll need the backport to provide the support for it.
303
-
304
327
  ## Development
305
328
 
306
329
  To be more clear - this is the for when you are working on *this* gem.
@@ -310,9 +333,8 @@ First, to get started, migrate and seed the database (SQLite by default):
310
333
 
311
334
  ```bash
312
335
  bundle
313
- rake db:migrate
314
- # Seed the development database with fake forum users, topics, and posts:
315
- rake dev:seed
336
+ # Create, migrate, and seed the development database with fake forum users, topics, and posts:
337
+ rake db:create db:migrate db:seed
316
338
  ```
317
339
 
318
340
  Then, start the dummy app server:
@@ -0,0 +1,4 @@
1
+ <svg height="32" viewBox="0 0 24 24" width="32" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M0 0h24v24H0z" fill="none"/>
3
+ <path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8l8 5 8-5v10zm-8-7L4 6h16l-8 5z"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg height="48" viewBox="0 0 24 24" width="32" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M0 0h24v24H0z" fill="none"/>
3
+ <path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/>
4
+ </svg>
@@ -1,10 +1,2 @@
1
- // We are not currently using any features that require the Babel polyfill
2
- // Enable this if we do:
3
- //- require babel/polyfill
4
-
5
- //= require jquery
6
- //= require jquery_ujs
7
- //= require jquery.autosize
8
- //= require rails-timeago
9
- //= require select2
10
- //= require_tree ./thredded
1
+ //= require thredded/dependencies
2
+ //= require thredded/thredded
@@ -2,7 +2,7 @@
2
2
  const COMPONENT_SELECTOR = '[data-thredded-topic-form]';
3
3
  class ThreddedTopicForm {
4
4
  constructor() {
5
- this.titleSelector = '[data-thredded-topic-form-title]';
5
+ this.titleSelector = '[name$="topic[title]"]';
6
6
  this.textareaSelector = 'textarea';
7
7
  this.compactSelector = 'form.thredded--is-compact';
8
8
  this.expandedSelector = 'form.thredded--is-expanded';
@@ -0,0 +1,37 @@
1
+ (function($) {
2
+ const COMPONENT_SELECTOR = '[data-thredded-topics]';
3
+
4
+ const TOPIC_SELECTOR = 'article';
5
+ const TOPIC_LINK_SELECTOR = 'h1 a';
6
+ const TOPIC_UNREAD_CLASS = 'thredded--topic-unread';
7
+ const TOPIC_READ_CLASS = 'thredded--topic-read';
8
+ const POSTS_COUNT_SELECTOR = '.thredded--topics--posts-count';
9
+ const POSTS_PER_PAGE = 50;
10
+
11
+ function pageNumber(url) {
12
+ const match = url.match(/\/page-(\d)$/);
13
+ return match ? +match[1] : 1;
14
+ }
15
+
16
+ function totalPages(numPosts) {
17
+ return Math.ceil(numPosts / POSTS_PER_PAGE);
18
+ }
19
+
20
+ class ThreddedTopics {
21
+ init($nodes) {
22
+ $nodes.on('click', TOPIC_LINK_SELECTOR, (evt) => {
23
+ const $topic = $(evt.target).closest(TOPIC_SELECTOR);
24
+ if (pageNumber($topic.find('a').prop('href')) == totalPages(+$topic.find(POSTS_COUNT_SELECTOR).text())) {
25
+ $topic.addClass(TOPIC_READ_CLASS).removeClass(TOPIC_UNREAD_CLASS);
26
+ }
27
+ });
28
+ }
29
+ }
30
+
31
+ $(function() {
32
+ var $nodes = $(COMPONENT_SELECTOR);
33
+ if ($nodes.length) {
34
+ new ThreddedTopics().init($nodes);
35
+ }
36
+ });
37
+ })(jQuery);
@@ -0,0 +1,45 @@
1
+ (function($) {
2
+ const COMPONENT_SELECTOR = '[data-thredded-user-preferences-form]';
3
+ const NOTIFY_ON_MENTION_SELECTOR = ':checkbox[name="user_preferences_form[notify_on_mention]"]';
4
+ const MESSAGEBOARD_NOTIFY_ON_MENTION_SELECTOR = '[name="user_preferences_form[messageboard_notify_on_mention]"]';
5
+
6
+ class UserPreferencesForm {
7
+ constructor(form) {
8
+ this.$form = $(form);
9
+ this.$notifyOnMention = this.$form.find(NOTIFY_ON_MENTION_SELECTOR);
10
+ this.$messageboardNotifyOnMention = this.$form.find(MESSAGEBOARD_NOTIFY_ON_MENTION_SELECTOR);
11
+
12
+ this.messageboardNotifyOnMentionCheckedWas = this.$messageboardNotifyOnMention.prop('checked');
13
+ this.$messageboardNotifyOnMention.on('change', () => {
14
+ this.rememberMessageboardNotifyOnMentionChecked();
15
+ });
16
+ this.rememberMessageboardNotifyOnMentionChecked();
17
+
18
+ this.$notifyOnMention.on('change', () => {
19
+ this.updateMessageboardNotifyOnMention();
20
+ });
21
+ this.updateMessageboardNotifyOnMention();
22
+ }
23
+
24
+ rememberMessageboardNotifyOnMentionChecked() {
25
+ this.messageboardNotifyOnMentionCheckedWas =
26
+ this.$messageboardNotifyOnMention.filter(':checkbox').prop('checked');
27
+ }
28
+
29
+ updateMessageboardNotifyOnMention() {
30
+ const enabled = this.$notifyOnMention.prop('checked');
31
+ this.$messageboardNotifyOnMention
32
+ .prop('disabled', !enabled)
33
+ .filter(':checkbox').prop('checked', enabled ? this.messageboardNotifyOnMentionCheckedWas : false);
34
+ }
35
+ }
36
+
37
+ $(function() {
38
+ const $forms = $(COMPONENT_SELECTOR);
39
+ if ($forms.length) {
40
+ $forms.each(function() {
41
+ new UserPreferencesForm(this);
42
+ });
43
+ }
44
+ });
45
+ })(jQuery);
@@ -0,0 +1,56 @@
1
+ ($ => {
2
+ const COMPONENT_SELECTOR = '[data-thredded-users-select]';
3
+
4
+
5
+ let formatUser = (user, container, query, escapeHtml) => {
6
+ if (user.loading) return user.text;
7
+ return "<div class='thredded--select2-user-result'>" +
8
+ `<img class='thredded--select2-user-result__avatar' src='${escapeHtml(user.avatar_url)}' >` +
9
+ `<span class='thredded--select2-user-result__name'>${escapeHtml(user.name)}</span>` +
10
+ '</div>';
11
+ };
12
+
13
+ let formatUserSelection = (user, container, escapeHtml) => {
14
+ return `<span class='thredded--select2-user-selection'>` +
15
+ `<img class='thredded--select2-user-selection__avatar' src='${escapeHtml(user.avatar_url)}' >` +
16
+ `<span class='thredded--select2-user-selection__name'>${escapeHtml(user.name)}</span>` +
17
+ '</span>';
18
+ };
19
+
20
+ let initSelection = ($el, callback) => {
21
+ let ids = ($el.val() || '').split(',');
22
+ if (ids.length && ids[0] != '') {
23
+ $.ajax(`${$el.data('autocompleteUrl')}?ids=${ids.join(',')}`, {dataType: 'json'}).done(data => callback(data.results));
24
+ } else {
25
+ callback([]);
26
+ }
27
+ };
28
+
29
+ let init = $el => {
30
+ $el.select2({
31
+ ajax: {
32
+ cache: true,
33
+ data: query => ({q: query}),
34
+ results: data => data,
35
+ dataType: 'json',
36
+ url: $el.data('autocompleteUrl')
37
+ },
38
+ containerCssClass: 'thredded--select2-container',
39
+ dropdownCssClass: 'thredded--select2-drop',
40
+ initSelection: initSelection,
41
+ minimumInputLength: 2,
42
+ multiple: true,
43
+ formatResult: formatUser,
44
+ formatSelection: formatUserSelection
45
+ });
46
+ };
47
+
48
+ $(function() {
49
+ var $nodes = $(COMPONENT_SELECTOR);
50
+ if ($nodes.length) {
51
+ $nodes.each(function() {
52
+ init($(this));
53
+ });
54
+ }
55
+ });
56
+ })(jQuery);
@@ -0,0 +1,9 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require jquery.autosize
4
+ //= require rails-timeago
5
+ //= require select2
6
+
7
+ // We are not currently using any features that require the Babel polyfill
8
+ // Enable this if we do:
9
+ //- require babel/polyfill
@@ -0,0 +1 @@
1
+ //= require_tree ./components
@@ -3,9 +3,10 @@
3
3
  @import "base/variables";
4
4
 
5
5
  @import "base/alerts";
6
- @import "base/grid";
7
- @import "base/typography";
8
6
  @import "base/buttons";
9
7
  @import "base/forms";
8
+ @import "base/grid";
10
9
  @import "base/lists";
10
+ @import "base/nav";
11
11
  @import "base/tables";
12
+ @import "base/typography";
@@ -6,10 +6,13 @@
6
6
 
7
7
  @import "layout/main-container";
8
8
  @import "layout/main-navigation";
9
- @import "layout/topic-navigation";
9
+ @import "layout/search-navigation";
10
10
  @import "layout/user-navigation";
11
+ @import "layout/navigation";
11
12
 
12
13
  @import "components/base";
14
+ @import "components/alerts";
15
+ @import "components/icons";
13
16
  @import "components/currently-online";
14
17
  @import "components/empty";
15
18
  @import "components/flash-message";
@@ -20,7 +20,8 @@
20
20
  &:hover,
21
21
  &:focus {
22
22
  background-color: $thredded-button-hover-background;
23
- color: #fff;
23
+ color: $thredded-button-hover-color;
24
+ text-decoration: none;
24
25
  }
25
26
 
26
27
  &:focus {
@@ -1,6 +1,27 @@
1
+ %thredded--form--input {
2
+ background: $thredded-form-background;
3
+ border: $thredded-form-border;
4
+ box-shadow: $thredded-form-box-shadow;
5
+ color: $thredded-form-color;
6
+ font-family: $thredded-base-font-family;
7
+ font-size: $thredded-base-font-size;
8
+ padding: $thredded-small-spacing;
9
+ transition: border-color;
10
+
11
+ &:hover {
12
+ border-color: $thredded-form-border-hover-color;
13
+ }
14
+
15
+ &:focus {
16
+ border-color: $thredded-form-border-focus-color;
17
+ box-shadow: $thredded-form-box-shadow, 0 0 3px $thredded-action-color;
18
+ outline: none;
19
+ }
20
+ }
21
+
1
22
  %thredded--form {
2
23
  fieldset {
3
- background-color: lighten($thredded-base-border-color, 10%);
24
+ background-color: $thredded-background-color;
4
25
  border: $thredded-base-border;
5
26
  margin: 0 0 $thredded-small-spacing;
6
27
  padding: $thredded-base-spacing;
@@ -30,25 +51,9 @@
30
51
  [type='color'], [type='date'], [type='datetime'], [type='datetime-local'], [type='email'], [type='month'],
31
52
  [type='number'], [type='password'], [type='search'], [type='tel'], [type='text'], [type='time'], [type='url'],
32
53
  [type='week'], input:not([type]), textarea, select[multiple=multiple] {
33
- background-color: $thredded-base-background-color;
34
- border: $thredded-form-border;
35
- box-shadow: $thredded-form-box-shadow;
54
+ @extend %thredded--form--input;
36
55
  box-sizing: border-box;
37
- font-family: $thredded-base-font-family;
38
- font-size: $thredded-base-font-size;
39
- padding: $thredded-small-spacing;
40
- transition: border-color;
41
56
  width: 100%;
42
-
43
- &:hover {
44
- border-color: darken($thredded-base-border-color, 10%);
45
- }
46
-
47
- &:focus {
48
- border-color: $thredded-action-color;
49
- box-shadow: $thredded-form-box-shadow, 0 0 3px $thredded-action-color;
50
- outline: none;
51
- }
52
57
  }
53
58
 
54
59
  textarea {