threddedDANIEL 0.14.5

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 (367) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +744 -0
  4. data/app/assets/images/favicons/README.md +3 -0
  5. data/app/assets/images/favicons/amazon.png +0 -0
  6. data/app/assets/images/favicons/github.png +0 -0
  7. data/app/assets/images/favicons/google_branding/logo_calendar_128px.png +0 -0
  8. data/app/assets/images/favicons/google_branding/logo_docs_48px.png +0 -0
  9. data/app/assets/images/favicons/google_branding/logo_drive_48px.png +0 -0
  10. data/app/assets/images/favicons/google_branding/logo_forms_48px.png +0 -0
  11. data/app/assets/images/favicons/google_branding/logo_sheets_48px.png +0 -0
  12. data/app/assets/images/favicons/google_branding/logo_slides_48px.png +0 -0
  13. data/app/assets/images/favicons/stackexchange.png +0 -0
  14. data/app/assets/images/favicons/twitter.png +0 -0
  15. data/app/assets/images/favicons/wikipedia.png +0 -0
  16. data/app/assets/images/thredded/breadcrumb-chevron.svg +1 -0
  17. data/app/assets/images/thredded/follow.svg +1 -0
  18. data/app/assets/images/thredded/lock.svg +1 -0
  19. data/app/assets/images/thredded/moderation.svg +1 -0
  20. data/app/assets/images/thredded/private-messages.svg +1 -0
  21. data/app/assets/images/thredded/settings.svg +1 -0
  22. data/app/assets/images/thredded/three-dot-menu.svg +3 -0
  23. data/app/assets/images/thredded/unfollow.svg +1 -0
  24. data/app/assets/javascripts/thredded.es6 +2 -0
  25. data/app/assets/javascripts/thredded/components/currently_online.es6 +32 -0
  26. data/app/assets/javascripts/thredded/components/flash_messages.es6 +9 -0
  27. data/app/assets/javascripts/thredded/components/mention_autocompletion.es6 +40 -0
  28. data/app/assets/javascripts/thredded/components/post_form.es6 +37 -0
  29. data/app/assets/javascripts/thredded/components/preview_area.es6 +56 -0
  30. data/app/assets/javascripts/thredded/components/quote_post.es6 +49 -0
  31. data/app/assets/javascripts/thredded/components/time_stamps.es6 +25 -0
  32. data/app/assets/javascripts/thredded/components/topic_form.es6 +94 -0
  33. data/app/assets/javascripts/thredded/components/topics.es6 +46 -0
  34. data/app/assets/javascripts/thredded/components/turboforms.es6 +25 -0
  35. data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +66 -0
  36. data/app/assets/javascripts/thredded/components/user_textcomplete.es6 +50 -0
  37. data/app/assets/javascripts/thredded/components/users_select.es6 +122 -0
  38. data/app/assets/javascripts/thredded/core/csrf_tokens.es6 +9 -0
  39. data/app/assets/javascripts/thredded/core/debounce.es6 +32 -0
  40. data/app/assets/javascripts/thredded/core/escape_html.es6 +7 -0
  41. data/app/assets/javascripts/thredded/core/hide_soft_keyboard.es6 +7 -0
  42. data/app/assets/javascripts/thredded/core/on_page_load.es6 +54 -0
  43. data/app/assets/javascripts/thredded/core/serialize_form.es6 +9 -0
  44. data/app/assets/javascripts/thredded/core/thredded.es6 +1 -0
  45. data/app/assets/javascripts/thredded/dependencies.js +8 -0
  46. data/app/assets/javascripts/thredded/dependencies/autosize.js +1 -0
  47. data/app/assets/javascripts/thredded/dependencies/textcomplete.js +1 -0
  48. data/app/assets/javascripts/thredded/dependencies/timeago.js +1 -0
  49. data/app/assets/javascripts/thredded/dependencies/ujs.js +1 -0
  50. data/app/assets/javascripts/thredded/thredded.es6 +2 -0
  51. data/app/assets/stylesheets/thredded.scss +3 -0
  52. data/app/assets/stylesheets/thredded/_base.scss +13 -0
  53. data/app/assets/stylesheets/thredded/_dependencies.scss +0 -0
  54. data/app/assets/stylesheets/thredded/_email.scss +51 -0
  55. data/app/assets/stylesheets/thredded/_thredded.scss +33 -0
  56. data/app/assets/stylesheets/thredded/base/_alerts.scss +44 -0
  57. data/app/assets/stylesheets/thredded/base/_buttons.scss +73 -0
  58. data/app/assets/stylesheets/thredded/base/_dropdown-menu.scss +83 -0
  59. data/app/assets/stylesheets/thredded/base/_forms.scss +84 -0
  60. data/app/assets/stylesheets/thredded/base/_grid.scss +58 -0
  61. data/app/assets/stylesheets/thredded/base/_lists.scss +31 -0
  62. data/app/assets/stylesheets/thredded/base/_nav.scss +67 -0
  63. data/app/assets/stylesheets/thredded/base/_tables.scss +17 -0
  64. data/app/assets/stylesheets/thredded/base/_typography.scss +72 -0
  65. data/app/assets/stylesheets/thredded/base/_variables.scss +141 -0
  66. data/app/assets/stylesheets/thredded/components/_alerts.scss +19 -0
  67. data/app/assets/stylesheets/thredded/components/_base.scss +25 -0
  68. data/app/assets/stylesheets/thredded/components/_currently-online.scss +54 -0
  69. data/app/assets/stylesheets/thredded/components/_empty.scss +11 -0
  70. data/app/assets/stylesheets/thredded/components/_flash-message.scss +19 -0
  71. data/app/assets/stylesheets/thredded/components/_following.scss +14 -0
  72. data/app/assets/stylesheets/thredded/components/_form-list.scss +39 -0
  73. data/app/assets/stylesheets/thredded/components/_icons.scss +3 -0
  74. data/app/assets/stylesheets/thredded/components/_main-section.scss +9 -0
  75. data/app/assets/stylesheets/thredded/components/_mention-autocomplete.scss +57 -0
  76. data/app/assets/stylesheets/thredded/components/_messageboard.scss +155 -0
  77. data/app/assets/stylesheets/thredded/components/_onebox.scss +275 -0
  78. data/app/assets/stylesheets/thredded/components/_pagination.scss +35 -0
  79. data/app/assets/stylesheets/thredded/components/_post-form.scss +27 -0
  80. data/app/assets/stylesheets/thredded/components/_post.scss +138 -0
  81. data/app/assets/stylesheets/thredded/components/_preferences.scss +19 -0
  82. data/app/assets/stylesheets/thredded/components/_preview_area.scss +11 -0
  83. data/app/assets/stylesheets/thredded/components/_topic-delete.scss +8 -0
  84. data/app/assets/stylesheets/thredded/components/_topic-header.scss +111 -0
  85. data/app/assets/stylesheets/thredded/components/_topics.scss +186 -0
  86. data/app/assets/stylesheets/thredded/layout/_main-container.scss +16 -0
  87. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +79 -0
  88. data/app/assets/stylesheets/thredded/layout/_moderation.scss +97 -0
  89. data/app/assets/stylesheets/thredded/layout/_navigation.scss +87 -0
  90. data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +126 -0
  91. data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +20 -0
  92. data/app/assets/stylesheets/thredded/layout/_user.scss +10 -0
  93. data/app/assets/stylesheets/thredded/utilities/_is-compact.scss +26 -0
  94. data/app/assets/stylesheets/thredded/utilities/_is-expanded.scss +16 -0
  95. data/app/commands/thredded/at_notification_extractor.rb +23 -0
  96. data/app/commands/thredded/autofollow_users.rb +62 -0
  97. data/app/commands/thredded/create_messageboard.rb +42 -0
  98. data/app/commands/thredded/mark_all_read.rb +22 -0
  99. data/app/commands/thredded/moderate_post.rb +48 -0
  100. data/app/commands/thredded/notify_following_users.rb +78 -0
  101. data/app/commands/thredded/notify_private_topic_users.rb +34 -0
  102. data/app/controllers/concerns/thredded/new_post_params.rb +21 -0
  103. data/app/controllers/concerns/thredded/new_private_post_params.rb +21 -0
  104. data/app/controllers/concerns/thredded/new_private_topic_params.rb +25 -0
  105. data/app/controllers/concerns/thredded/new_topic_params.rb +19 -0
  106. data/app/controllers/concerns/thredded/render_preview.rb +16 -0
  107. data/app/controllers/thredded/application_controller.rb +145 -0
  108. data/app/controllers/thredded/autocomplete_users_controller.rb +52 -0
  109. data/app/controllers/thredded/messageboard_groups_controller.rb +31 -0
  110. data/app/controllers/thredded/messageboards_controller.rb +53 -0
  111. data/app/controllers/thredded/moderation_controller.rb +103 -0
  112. data/app/controllers/thredded/post_permalinks_controller.rb +11 -0
  113. data/app/controllers/thredded/post_previews_controller.rb +29 -0
  114. data/app/controllers/thredded/posts_controller.rb +97 -0
  115. data/app/controllers/thredded/preferences_controller.rb +42 -0
  116. data/app/controllers/thredded/private_post_permalinks_controller.rb +12 -0
  117. data/app/controllers/thredded/private_post_previews_controller.rb +29 -0
  118. data/app/controllers/thredded/private_posts_controller.rb +96 -0
  119. data/app/controllers/thredded/private_topic_previews_controller.rb +15 -0
  120. data/app/controllers/thredded/private_topics_controller.rb +102 -0
  121. data/app/controllers/thredded/read_states_controller.rb +13 -0
  122. data/app/controllers/thredded/theme_previews_controller.rb +34 -0
  123. data/app/controllers/thredded/topic_previews_controller.rb +15 -0
  124. data/app/controllers/thredded/topics_controller.rb +205 -0
  125. data/app/forms/thredded/edit_topic_form.rb +51 -0
  126. data/app/forms/thredded/post_form.rb +54 -0
  127. data/app/forms/thredded/private_post_form.rb +50 -0
  128. data/app/forms/thredded/private_topic_form.rb +160 -0
  129. data/app/forms/thredded/topic_form.rb +95 -0
  130. data/app/forms/thredded/user_preferences_form.rb +110 -0
  131. data/app/helpers/thredded/application_helper.rb +129 -0
  132. data/app/helpers/thredded/nav_helper.rb +42 -0
  133. data/app/helpers/thredded/render_helper.rb +15 -0
  134. data/app/helpers/thredded/urls_helper.rb +134 -0
  135. data/app/jobs/thredded/activity_updater_job.rb +21 -0
  136. data/app/jobs/thredded/auto_follow_and_notify_job.rb +14 -0
  137. data/app/jobs/thredded/notify_private_topic_users_job.rb +12 -0
  138. data/app/mailer_previews/thredded/base_mailer_preview.rb +118 -0
  139. data/app/mailer_previews/thredded/post_mailer_preview.rb +13 -0
  140. data/app/mailer_previews/thredded/private_topic_mailer_preview.rb +13 -0
  141. data/app/mailers/thredded/base_mailer.rb +18 -0
  142. data/app/mailers/thredded/post_mailer.rb +21 -0
  143. data/app/mailers/thredded/private_topic_mailer.rb +21 -0
  144. data/app/models/concerns/thredded/content_moderation_state.rb +67 -0
  145. data/app/models/concerns/thredded/friendly_id_reserved_words_and_pagination.rb +17 -0
  146. data/app/models/concerns/thredded/moderation_state.rb +14 -0
  147. data/app/models/concerns/thredded/notifier_preference.rb +19 -0
  148. data/app/models/concerns/thredded/post_common.rb +76 -0
  149. data/app/models/concerns/thredded/search_parser.rb +41 -0
  150. data/app/models/concerns/thredded/topic_common.rb +94 -0
  151. data/app/models/concerns/thredded/topics_search.rb +67 -0
  152. data/app/models/concerns/thredded/user_topic_read_state_common.rb +42 -0
  153. data/app/models/thredded/category.rb +18 -0
  154. data/app/models/thredded/messageboard.rb +120 -0
  155. data/app/models/thredded/messageboard_group.rb +19 -0
  156. data/app/models/thredded/messageboard_notifications_for_followed_topics.rb +30 -0
  157. data/app/models/thredded/messageboard_user.rb +14 -0
  158. data/app/models/thredded/notifications_for_followed_topics.rb +25 -0
  159. data/app/models/thredded/notifications_for_private_topics.rb +22 -0
  160. data/app/models/thredded/null_user.rb +51 -0
  161. data/app/models/thredded/null_user_topic_read_state.rb +17 -0
  162. data/app/models/thredded/post.rb +77 -0
  163. data/app/models/thredded/post_moderation_record.rb +56 -0
  164. data/app/models/thredded/private_post.rb +63 -0
  165. data/app/models/thredded/private_topic.rb +89 -0
  166. data/app/models/thredded/private_user.rb +8 -0
  167. data/app/models/thredded/stats.rb +25 -0
  168. data/app/models/thredded/topic.rb +179 -0
  169. data/app/models/thredded/topic_category.rb +8 -0
  170. data/app/models/thredded/user_detail.rb +27 -0
  171. data/app/models/thredded/user_extender.rb +75 -0
  172. data/app/models/thredded/user_messageboard_preference.rb +45 -0
  173. data/app/models/thredded/user_permissions/admin/if_admin_column_true.rb +14 -0
  174. data/app/models/thredded/user_permissions/admin/none.rb +14 -0
  175. data/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb +15 -0
  176. data/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb +16 -0
  177. data/app/models/thredded/user_permissions/moderate/none.rb +16 -0
  178. data/app/models/thredded/user_permissions/read/all.rb +27 -0
  179. data/app/models/thredded/user_permissions/write/all.rb +16 -0
  180. data/app/models/thredded/user_permissions/write/none.rb +16 -0
  181. data/app/models/thredded/user_post_notification.rb +29 -0
  182. data/app/models/thredded/user_preference.rb +26 -0
  183. data/app/models/thredded/user_private_topic_read_state.rb +13 -0
  184. data/app/models/thredded/user_topic_follow.rb +34 -0
  185. data/app/models/thredded/user_topic_read_state.rb +13 -0
  186. data/app/notifiers/thredded/email_notifier.rb +25 -0
  187. data/app/policies/thredded/messageboard_group_policy.rb +16 -0
  188. data/app/policies/thredded/messageboard_policy.rb +49 -0
  189. data/app/policies/thredded/post_policy.rb +64 -0
  190. data/app/policies/thredded/private_post_policy.rb +38 -0
  191. data/app/policies/thredded/private_topic_policy.rb +24 -0
  192. data/app/policies/thredded/topic_policy.rb +49 -0
  193. data/app/view_hooks/thredded/all_view_hooks.rb +125 -0
  194. data/app/view_models/thredded/base_topic_view.rb +43 -0
  195. data/app/view_models/thredded/messageboard_group_view.rb +27 -0
  196. data/app/view_models/thredded/post_view.rb +89 -0
  197. data/app/view_models/thredded/posts_page_view.rb +27 -0
  198. data/app/view_models/thredded/private_topic_view.rb +20 -0
  199. data/app/view_models/thredded/private_topics_page_view.rb +31 -0
  200. data/app/view_models/thredded/topic_email_view.rb +18 -0
  201. data/app/view_models/thredded/topic_posts_page_view.rb +17 -0
  202. data/app/view_models/thredded/topic_view.rb +68 -0
  203. data/app/view_models/thredded/topics_page_view.rb +38 -0
  204. data/app/views/layouts/thredded/application.html.erb +18 -0
  205. data/app/views/thredded/categories/_category.html.erb +1 -0
  206. data/app/views/thredded/error_pages/forbidden.html.erb +6 -0
  207. data/app/views/thredded/error_pages/not_found.html.erb +6 -0
  208. data/app/views/thredded/kaminari/_first_page.html.erb +11 -0
  209. data/app/views/thredded/kaminari/_gap.html.erb +8 -0
  210. data/app/views/thredded/kaminari/_last_page.html.erb +11 -0
  211. data/app/views/thredded/kaminari/_next_page.html.erb +11 -0
  212. data/app/views/thredded/kaminari/_page.html.erb +12 -0
  213. data/app/views/thredded/kaminari/_paginator.html.erb +23 -0
  214. data/app/views/thredded/kaminari/_prev_page.html.erb +11 -0
  215. data/app/views/thredded/messageboard_groups/new.html.erb +28 -0
  216. data/app/views/thredded/messageboards/_form.html.erb +30 -0
  217. data/app/views/thredded/messageboards/_messageboard.html.erb +20 -0
  218. data/app/views/thredded/messageboards/_messageboard_meta.html.erb +13 -0
  219. data/app/views/thredded/messageboards/edit.html.erb +15 -0
  220. data/app/views/thredded/messageboards/index.html.erb +34 -0
  221. data/app/views/thredded/messageboards/new.html.erb +15 -0
  222. data/app/views/thredded/moderation/_nav.html.erb +19 -0
  223. data/app/views/thredded/moderation/_post.html.erb +19 -0
  224. data/app/views/thredded/moderation/_post_moderation_actions.html.erb +12 -0
  225. data/app/views/thredded/moderation/_post_moderation_record.html.erb +46 -0
  226. data/app/views/thredded/moderation/_user_moderation_state.html.erb +3 -0
  227. data/app/views/thredded/moderation/_user_post.html.erb +12 -0
  228. data/app/views/thredded/moderation/_users_search_form.html.erb +13 -0
  229. data/app/views/thredded/moderation/activity.html.erb +20 -0
  230. data/app/views/thredded/moderation/history.html.erb +13 -0
  231. data/app/views/thredded/moderation/pending.html.erb +24 -0
  232. data/app/views/thredded/moderation/user.html.erb +54 -0
  233. data/app/views/thredded/moderation/users.html.erb +41 -0
  234. data/app/views/thredded/post_mailer/post_notification.html.erb +26 -0
  235. data/app/views/thredded/post_mailer/post_notification.text.erb +14 -0
  236. data/app/views/thredded/post_previews/preview.html.erb +1 -0
  237. data/app/views/thredded/post_previews/update.html.erb +1 -0
  238. data/app/views/thredded/posts/_content.html.erb +1 -0
  239. data/app/views/thredded/posts/_form.html.erb +5 -0
  240. data/app/views/thredded/posts/_post.html.erb +13 -0
  241. data/app/views/thredded/posts/_user.html.erb +3 -0
  242. data/app/views/thredded/posts/edit.html.erb +16 -0
  243. data/app/views/thredded/posts/new.html.erb +15 -0
  244. data/app/views/thredded/posts_common/_actions.html.erb +28 -0
  245. data/app/views/thredded/posts_common/_content.html.erb +3 -0
  246. data/app/views/thredded/posts_common/_form.html.erb +22 -0
  247. data/app/views/thredded/posts_common/_header.html.erb +8 -0
  248. data/app/views/thredded/posts_common/_header_with_topic.html.erb +15 -0
  249. data/app/views/thredded/posts_common/_header_with_user_and_topic.html.erb +18 -0
  250. data/app/views/thredded/posts_common/actions/_delete.html.erb +4 -0
  251. data/app/views/thredded/posts_common/actions/_edit.html.erb +3 -0
  252. data/app/views/thredded/posts_common/actions/_mark_as_unread.html.erb +2 -0
  253. data/app/views/thredded/posts_common/actions/_quote.html.erb +4 -0
  254. data/app/views/thredded/posts_common/form/_after_content.html.erb +8 -0
  255. data/app/views/thredded/posts_common/form/_before_content.html.erb +8 -0
  256. data/app/views/thredded/posts_common/form/_content.html.erb +7 -0
  257. data/app/views/thredded/posts_common/form/_content_field.html.erb +8 -0
  258. data/app/views/thredded/posts_common/form/_preview_area.html.erb +16 -0
  259. data/app/views/thredded/preferences/_form.html.erb +95 -0
  260. data/app/views/thredded/preferences/_messageboards_nav.html.erb +8 -0
  261. data/app/views/thredded/preferences/_messageboards_nav_item.html.erb +2 -0
  262. data/app/views/thredded/preferences/edit.html.erb +20 -0
  263. data/app/views/thredded/private_post_previews/preview.html.erb +1 -0
  264. data/app/views/thredded/private_post_previews/update.html.erb +1 -0
  265. data/app/views/thredded/private_posts/_content.html.erb +1 -0
  266. data/app/views/thredded/private_posts/_form.html.erb +6 -0
  267. data/app/views/thredded/private_posts/_private_post.html.erb +6 -0
  268. data/app/views/thredded/private_posts/edit.html.erb +16 -0
  269. data/app/views/thredded/private_posts/new.html.erb +11 -0
  270. data/app/views/thredded/private_topic_mailer/message_notification.html.erb +26 -0
  271. data/app/views/thredded/private_topic_mailer/message_notification.text.erb +15 -0
  272. data/app/views/thredded/private_topic_previews/preview.html.erb +1 -0
  273. data/app/views/thredded/private_topics/_breadcrumbs.html.erb +4 -0
  274. data/app/views/thredded/private_topics/_form.html.erb +39 -0
  275. data/app/views/thredded/private_topics/_header.html.erb +17 -0
  276. data/app/views/thredded/private_topics/_no_private_topics.html.erb +6 -0
  277. data/app/views/thredded/private_topics/_private_topic.html.erb +23 -0
  278. data/app/views/thredded/private_topics/edit.html.erb +35 -0
  279. data/app/views/thredded/private_topics/header/_participant.html.erb +1 -0
  280. data/app/views/thredded/private_topics/index.html.erb +32 -0
  281. data/app/views/thredded/private_topics/new.html.erb +11 -0
  282. data/app/views/thredded/private_topics/private_topic/_participant.html.erb +1 -0
  283. data/app/views/thredded/private_topics/show.html.erb +28 -0
  284. data/app/views/thredded/search/_form.html.erb +13 -0
  285. data/app/views/thredded/shared/_breadcrumbs.html.erb +6 -0
  286. data/app/views/thredded/shared/_content_moderation_blocked_state.html.erb +8 -0
  287. data/app/views/thredded/shared/_currently_online.html.erb +6 -0
  288. data/app/views/thredded/shared/_flash_messages.html.erb +7 -0
  289. data/app/views/thredded/shared/_header.html.erb +3 -0
  290. data/app/views/thredded/shared/_nav.html.erb +19 -0
  291. data/app/views/thredded/shared/_page.html.erb +15 -0
  292. data/app/views/thredded/shared/currently_online/_header.html.erb +5 -0
  293. data/app/views/thredded/shared/currently_online/_user_list.html.erb +3 -0
  294. data/app/views/thredded/shared/currently_online/_user_list_item.html.erb +6 -0
  295. data/app/views/thredded/shared/nav/_moderation.html.erb +14 -0
  296. data/app/views/thredded/shared/nav/_notification_preferences.html.erb +8 -0
  297. data/app/views/thredded/shared/nav/_private_topics.html.erb +12 -0
  298. data/app/views/thredded/shared/nav/_standalone.html.erb +12 -0
  299. data/app/views/thredded/shared/nav/_standalone_profile.html.erb +3 -0
  300. data/app/views/thredded/shared/preview.html.erb +10 -0
  301. data/app/views/thredded/theme_previews/_section_title.html.erb +3 -0
  302. data/app/views/thredded/theme_previews/show.html.erb +99 -0
  303. data/app/views/thredded/topic_previews/preview.html.erb +1 -0
  304. data/app/views/thredded/topics/_followers.html.erb +12 -0
  305. data/app/views/thredded/topics/_form.html.erb +32 -0
  306. data/app/views/thredded/topics/_header.html.erb +32 -0
  307. data/app/views/thredded/topics/_sticky_topics_divider.html.erb +1 -0
  308. data/app/views/thredded/topics/_topic.html.erb +47 -0
  309. data/app/views/thredded/topics/_topic_form_admin_options.html.erb +12 -0
  310. data/app/views/thredded/topics/edit.html.erb +50 -0
  311. data/app/views/thredded/topics/index.html.erb +35 -0
  312. data/app/views/thredded/topics/new.html.erb +12 -0
  313. data/app/views/thredded/topics/search.html.erb +39 -0
  314. data/app/views/thredded/topics/show.html.erb +46 -0
  315. data/app/views/thredded/users/_link.html.erb +14 -0
  316. data/app/views/thredded/users/_post.html.erb +6 -0
  317. data/app/views/thredded/users/_posts.html.erb +7 -0
  318. data/bin/rails +6 -0
  319. data/config/i18n-tasks.yml +16 -0
  320. data/config/locales/de.yml +257 -0
  321. data/config/locales/en.yml +253 -0
  322. data/config/locales/es.yml +257 -0
  323. data/config/locales/fr.yml +255 -0
  324. data/config/locales/it.yml +257 -0
  325. data/config/locales/pl.yml +257 -0
  326. data/config/locales/pt-BR.yml +258 -0
  327. data/config/locales/ru.yml +255 -0
  328. data/config/locales/zh-CN.yml +246 -0
  329. data/config/routes.rb +87 -0
  330. data/db/migrate/20160329231848_create_thredded.rb +257 -0
  331. data/db/seeds.rb +4 -0
  332. data/db/upgrade_migrations/20160611094616_upgrade_v0_5_to_v0_6.rb +28 -0
  333. data/db/upgrade_migrations/20160723012349_upgrade_v0_6_to_v0_7.rb +46 -0
  334. data/db/upgrade_migrations/20161019150201_upgrade_v0_7_to_v0_8.rb +34 -0
  335. data/db/upgrade_migrations/20161113161801_upgrade_v0_8_to_v0_9.rb +60 -0
  336. data/db/upgrade_migrations/20170125033319_upgrade_v0_9_to_v0_10.rb +36 -0
  337. data/db/upgrade_migrations/20170312131417_upgrade_thredded_v0_10_to_v0_11.rb +23 -0
  338. data/db/upgrade_migrations/20170420163138_upgrade_thredded_v0_11_to_v0_12.rb +28 -0
  339. data/db/upgrade_migrations/20170811090735_upgrade_thredded_v0_13_to_v_014.rb +21 -0
  340. data/lib/generators/thredded/install/USAGE +8 -0
  341. data/lib/generators/thredded/install/install_generator.rb +20 -0
  342. data/lib/generators/thredded/install/templates/initializer.rb +160 -0
  343. data/lib/tasks/thredded_tasks.rake +14 -0
  344. data/lib/thredded.rb +190 -0
  345. data/lib/thredded/base_migration.rb +14 -0
  346. data/lib/thredded/base_notifier.rb +28 -0
  347. data/lib/thredded/collection_to_strings_with_cache_renderer.rb +86 -0
  348. data/lib/thredded/content_formatter.rb +129 -0
  349. data/lib/thredded/database_seeder.rb +290 -0
  350. data/lib/thredded/db_tools.rb +103 -0
  351. data/lib/thredded/email_transformer.rb +22 -0
  352. data/lib/thredded/email_transformer/base.rb +47 -0
  353. data/lib/thredded/email_transformer/onebox.rb +21 -0
  354. data/lib/thredded/engine.rb +28 -0
  355. data/lib/thredded/errors.rb +68 -0
  356. data/lib/thredded/formatting_demo_content.rb +30 -0
  357. data/lib/thredded/html_pipeline/at_mention_filter.rb +78 -0
  358. data/lib/thredded/html_pipeline/autolink_filter.rb +15 -0
  359. data/lib/thredded/html_pipeline/kramdown_filter.rb +39 -0
  360. data/lib/thredded/html_pipeline/onebox_filter.rb +143 -0
  361. data/lib/thredded/html_pipeline/wrap_iframes_filter.rb +13 -0
  362. data/lib/thredded/version.rb +5 -0
  363. data/lib/thredded/view_hooks/config.rb +37 -0
  364. data/lib/thredded/view_hooks/renderer.rb +30 -0
  365. data/vendor/assets/javascripts/autosize.min.js +6 -0
  366. data/vendor/assets/javascripts/textcomplete.min.js +2 -0
  367. metadata +1035 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16f1b8486d30bfa018650e0e556afdbe2a01fe9e
4
+ data.tar.gz: 32350972b82d807bf879e0c4baa81a0ec4400d58
5
+ SHA512:
6
+ metadata.gz: 3f2693ed44fee4dc1de1299ae34e1730150d4ffb9069ce282ecac54ac407ae10532295cd003fc663a415b09c107b1f779c5d4f8d3354ceb24cfa1d7f63f4e2cf
7
+ data.tar.gz: a7cdb0cdfbf5d08a49fc78df67f8c4d944f2a7c991facdab1fe91a2f1521c19369524bf68779e59181d009409a5689ab72bd12576a6e4bb0c78c06b34955dca1
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,744 @@
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) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=master)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
2
+
3
+ _Thredded_ is a Rails 4.2+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
4
+
5
+ Some of the features currently in Thredded:
6
+
7
+ * Markdown (default) or BBCode post formatting.
8
+ * (Un)read posts tracking.
9
+ * Email notifications, topic subscriptions, @-mentions, per-messageboard notification settings.
10
+ * Private group messaging.
11
+ * Full-text search using the database.
12
+ * Pinned and locked topics.
13
+ * List of currently online users, for all forums and per-messageboard.
14
+ * Flexible permissions system.
15
+ * Basic moderation.
16
+ * Lightweight default theme configurable via Sass.
17
+
18
+ | ![Messageboards (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338810/1fbc4240-abd1-11e6-9cba-4ae2e654c4d4.png) | ![Topics (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338809/1fbb7dc4-abd1-11e6-9bc3-207b94018931.png) |
19
+ |:---:|:---:|
20
+ | ![Topic on iPhone 6 (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338433/0920debc-abcf-11e6-811c-8f29d10dfed7.png) | ![Messageboard Preferences on iPhone 6 (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338432/090e9c5c-abcf-11e6-8e7e-e287d31f6a54.png) |
21
+
22
+ Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. Thredded has no infrastructure
23
+ dependencies other than the database and, if configured in the parent application, the ActiveJob
24
+ backend dependency such as Redis. Currently only MRI Ruby 2.2+ is supported. We would love to
25
+ support JRuby and Rubinius as well.
26
+
27
+ If you're looking for variations on a theme - see [Discourse]. However, It is a full rails
28
+ application and not an engine like Thredded.
29
+
30
+ [Discourse]: http://www.discourse.org/
31
+
32
+ Table of Contents
33
+ =================
34
+
35
+ * [Installation](#installation)
36
+ * [Creating a new Rails app with Thredded](#creating-a-new-rails-app-with-thredded)
37
+ * [Adding Thredded to an existing Rails app](#adding-thredded-to-an-existing-rails-app)
38
+ * [Upgrading an existing install](#upgrading-an-existing-install)
39
+ * [Migrating from Forem](#migrating-from-forem)
40
+ * [Views and other assets](#views-and-other-assets)
41
+ * [Standalone layout](#standalone-layout)
42
+ * [Application layout](#application-layout)
43
+ * [Reference your paths so that Thredded can find them](#reference-your-paths-so-that-thredded-can-find-them)
44
+ * [Add Thredded styles](#add-thredded-styles)
45
+ * [Add Thredded JavaScripts](#add-thredded-javascripts)
46
+ * [User profile page](#user-profile-page)
47
+ * [Customizing views](#customizing-views)
48
+ * [View hooks](#view-hooks)
49
+ * [Theming](#theming)
50
+ * [Styles](#styles)
51
+ * [Email and other notifications](#email-and-other-notifications)
52
+ * [Enabling auto-follow](#enabling-auto-follow)
53
+ * [I18n](#i18n)
54
+ * [Permissions](#permissions)
55
+ * [Permission methods](#permission-methods)
56
+ * [Reading messageboards](#reading-messageboards)
57
+ * [Posting to messageboards](#posting-to-messageboards)
58
+ * [Messaging other users (posting to private topics)](#messaging-other-users-posting-to-private-topics)
59
+ * [Moderating messageboards](#moderating-messageboards)
60
+ * [Admin permissions](#admin-permissions)
61
+ * [Default permissions](#default-permissions)
62
+ * [Handling "Permission denied" and "Not found" errors](#handling-permission-denied-and-not-found-errors)
63
+ * [Moderation](#moderation)
64
+ * [Disabling moderation](#disabling-moderation)
65
+ * [Plugins](#plugins)
66
+ * [Development](#development)
67
+ * [Testing](#testing)
68
+ * [Ruby](#ruby)
69
+ * [JavaScript](#javascript)
70
+ * [Testing with all the databases and Rails versions locally.](#testing-with-all-the-databases-and-rails-versions-locally)
71
+ * [Developing and Testing with Docker Compose](#developing-and-testing-with-docker-compose)
72
+
73
+
74
+ ## Installation
75
+
76
+ ### Creating a new Rails app with Thredded
77
+
78
+ Thredded provides an app generator that will generate a Rails app with Thredded, Devise, SimpleForm, RSpec,
79
+ PostgreSQL, and a basic theme and navigation that is configured to work out of the box.
80
+
81
+ ```sh
82
+ gem install thredded_create_app
83
+ thredded_create_app path/to/myapp
84
+ ```
85
+
86
+ See `thredded_create_app --help` and the [thredded_create_app repo] to learn about the various options.
87
+
88
+ Then, see the rest of this Readme for more information about using and customizing Thredded.
89
+
90
+ [thredded_create_app repo]: https://github.com/thredded/thredded_create_app
91
+
92
+ ### Adding Thredded to an existing Rails app
93
+
94
+ Add the gem to your Gemfile:
95
+
96
+ ```ruby
97
+ gem 'thredded', '~> 0.14.5'
98
+ ```
99
+
100
+ Add the Thredded [initializer] to your parent app by running the install generator.
101
+
102
+ ```console
103
+ rails generate thredded:install
104
+ ```
105
+
106
+ Copy emoji images to your `public/emoji` directory.
107
+
108
+ ```console
109
+ rake thredded:install:emoji
110
+ ```
111
+
112
+ Thredded needs to know the base application User model name and certain columns on it. Configure
113
+ these in the initializer installed with the command above.
114
+
115
+ Then, copy the migrations over to your parent application and migrate:
116
+
117
+ ```console
118
+ rake thredded:install:migrations db:migrate db:test:prepare
119
+ ```
120
+
121
+ Mount the thredded engine in your routes file:
122
+
123
+ ```ruby
124
+ mount Thredded::Engine => '/forum'
125
+ ```
126
+
127
+ You also may want to add an index to the user name column in your users table.
128
+ Thredded uses it to find @-mentions and perform name prefix autocompletion on the private topic form.
129
+ Add the index in a migration like so:
130
+
131
+ ```ruby
132
+ DbTextSearch::CaseInsensitive.add_index(
133
+ connection, Thredded.user_class.table_name, Thredded.user_name_column, unique: true)
134
+ ```
135
+
136
+ ### Upgrading an existing install
137
+
138
+ 1) To upgrade the initializer:
139
+
140
+ ```console
141
+ rails g thredded:install
142
+ ```
143
+
144
+ But then compare this with the previous version to decide what to keep.
145
+
146
+ 2) To upgrade the database (in this example from v0.11 to v0.12):
147
+
148
+ ```console
149
+ # Note that for guaranteed best results you will want to run this with the thredded gem at v0.12
150
+ cp "$(bundle show thredded)"/db/upgrade_migrations/20170420163138_upgrade_thredded_v0_11_to_v0_12.rb db/migrate
151
+ rake db:migrate
152
+ ```
153
+
154
+ ### Migrating from Forem
155
+
156
+ Are you currently using [Forem]? Thredded provides [a migration][forem-to-thredded] to copy all of your existing data from Forem over
157
+ to Thredded.
158
+
159
+ [forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem
160
+ [Forem]: https://github.com/rubysherpas/forem
161
+
162
+ ## Views and other assets
163
+
164
+ ### Standalone layout
165
+
166
+ By default, thredded renders in its own (standalone) layout.
167
+
168
+ When using the standalone thredded layout, the log in / sign out links will be rendered in the navigation.
169
+ For these links (and only for these links), Thredded makes the assumption that you are using devise as your auth
170
+ library. If you are using something different you need to override the partial at
171
+ `app/views/thredded/shared/nav/_standalone.html.erb` and use the appropriate log in / sign out path URL helpers.
172
+
173
+ You can override the partial by copying it into your app:
174
+
175
+ ```bash
176
+ mkdir -p app/views/thredded/shared/nav && cp "$(bundle show thredded)/$_/_standalone.html.erb" "$_"
177
+ ```
178
+
179
+ ### Application layout
180
+
181
+ You can also use Thredded with your application (or other) layout by by setting `Thredded.layout` in the initializer.
182
+
183
+ In this case, you will need to reference your paths/routes carefully and pull in thredded assets (styles and javascript):
184
+
185
+ #### Reference your paths so that Thredded can find them
186
+
187
+ In your layout you will probably have links to other paths in your app (e.g. navigation links).
188
+ For any url helpers (like `users_path` or `projects_path` or whatever) will need to have `main_app.`
189
+ prefixed to them so that they can be found from thredded (`main_app.users_path` will work from both thredded and your app).
190
+
191
+ #### Add Thredded styles
192
+
193
+ In this case, you will also need to include Thredded styles and JavaScript into the application styles and JavaScript.
194
+
195
+ Add thredded styles to your `application.scss`:
196
+
197
+ ```scss
198
+ @import "thredded";
199
+ ```
200
+
201
+ Thredded wraps the views in a container element that has a `max-width` and paddings by default.
202
+ If your app layout already has a container element that handles these, you can remove the `max-width` and paddings
203
+ from the Thredded one by adding this Sass snippet after `@import "thredded";`:
204
+
205
+ ```scss
206
+ .thredded--main-container {
207
+ // The padding and max-width are handled by the app's container.
208
+ max-width: none;
209
+ padding: 0;
210
+ @include thredded-media-tablet-and-up {
211
+ padding: 0;
212
+ }
213
+ }
214
+ ```
215
+
216
+ See [below](#styles) for customizing the styles via Sass variables.
217
+
218
+ #### Add Thredded JavaScripts
219
+
220
+ Include thredded JavaScripts in your `application.js`:
221
+
222
+ ```js
223
+ //= require thredded
224
+ ```
225
+
226
+ Thredded is fully compatible with deferred and async script loading.
227
+
228
+ ##### Alternative JavaScript dependencies
229
+
230
+ <details><summary><b>Rails UJS version</b></summary>
231
+
232
+ By default, thredded loads `rails-ujs`. If you're using Rails before v5.1, you need to add `rails-ujs` to
233
+ your Gemfile.
234
+
235
+ If you'd like it to use `jquery_ujs` instead, run this command from your app directory:
236
+
237
+ ```bash
238
+ mkdir -p app/assets/javascripts/thredded/dependencies/
239
+ printf '//= require jquery3\n//= require jquery_ujs\n' > app/assets/javascripts/thredded/dependencies/ujs.js
240
+ ```
241
+ </details>
242
+
243
+ <details><summary><b>Timeago version</b></summary>
244
+
245
+ By default, thredded loads `timeago.js`.
246
+
247
+ If you'd like to use `jquery.timeago` or `rails-timeago` instead, run this command from your app directory:
248
+
249
+ ```bash
250
+ mkdir -p app/assets/javascripts/thredded/dependencies/
251
+ echo '//= require jquery.timeago' > app/assets/javascripts/thredded/dependencies/timeago.js
252
+ ```
253
+
254
+ You will also need to adjust the `//= require` statements for timeago locales if your site is translated into multiple
255
+ languages. For `jquery.timeago`, these need to be require after `thredded/dependencies` but before `thredded/thredded`.
256
+ E.g. for Brazilian Portuguese with jquery.timeago:
257
+
258
+ ```js
259
+ //= require thredded/dependencies
260
+ //= require locales/jquery.timeago.pt-br
261
+ //= require thredded/thredded
262
+ ```
263
+ </details>
264
+
265
+ #### Thredded page title and ID
266
+
267
+ Thredded views also provide two `content_tag`s available to yield - `:thredded_page_title` and `:thredded_page_id`.
268
+ The views within Thredded pass those up through to your layout if you would like to use them.
269
+
270
+ ### User profile page
271
+
272
+ Thredded does not provide a user's profile page, but it provides a partial for rendering the user's recent posts
273
+ in your app's user profile page. Here is how you can render it in your app:
274
+
275
+ ```erb
276
+ <%= Thredded::ApplicationController.render partial: 'thredded/users/posts', locals: {
277
+ posts: Thredded.posts_page_view(scope: user.thredded_posts.order_newest_first.limit(5),
278
+ current_user: current_user) } %>
279
+ ```
280
+
281
+ The `user` above is the user whose posts are rendered, and `current_user` is the user viewing the posts or `nil`.
282
+ The policy scopes that limit the posts to the ones `current_user` can see are applied automatically.
283
+
284
+ The code above uses the `ApplicationController.render` method introduced in Rails 5. If you're using Rails 4,
285
+ you will need to add the [`backport_new_renderer`](https://github.com/brainopia/backport_new_renderer) gem to use it.
286
+
287
+ ### Customizing views
288
+
289
+ You can also override any views and assets by placing them in the same path in your application as they are in the gem.
290
+ This uses the [standard Rails mechanism](http://guides.rubyonrails.org/engines.html#overriding-views) for overriding
291
+ engine views. For example, to copy the post view for customization:
292
+
293
+ ```bash
294
+ # Copy the post view into the application to customize it:
295
+ mkdir -p app/views/thredded/posts && cp "$(bundle show thredded)/$_/_post.html.erb" "$_"
296
+ ```
297
+
298
+ **NB:** Overriding the views like this means that on every update of the thredded gem you have to check that your
299
+ customizations are still compatible with the new version of thredded. This is difficult and error-prone.
300
+ Whenever possible, use the styles and i18n to customize Thredded to your needs.
301
+
302
+ #### View hooks
303
+
304
+ Thredded provides view hooks to customize the UI before/after/replacing individual components.
305
+
306
+ View hooks allow you to render anything in the thredded view context.
307
+ For example, to render a partial after the post content textarea, add the snippet below to
308
+ the `config/initializers/thredded.rb` initializer:
309
+
310
+ ```ruby
311
+ Rails.application.config.to_prepare do
312
+ Thredded.view_hooks.post_form.content_text_area.config.before do |form:, **args|
313
+ # This is render in the Thredded view context, so all Thredded helpers and URLs are accessible here directly.
314
+ render 'my/partial', form: form
315
+ end
316
+ end
317
+ ```
318
+
319
+ You can use the post content textarea hook to add things like wysiwyg/wymean editors, buttons, help links, help copy,
320
+ further customization for the textarea, etc.
321
+
322
+ To see the complete list of view hooks and their arguments, run:
323
+
324
+ ```bash
325
+ grep view_hooks -R --include '*.html.erb' "$(bundle show thredded)"
326
+ ```
327
+
328
+ ### Theming
329
+
330
+ The engine comes by default with a light and effective implementation of the
331
+ views, styles, and javascript. Once you mount the engine you will be presented
332
+ with a "themed" version of thredded.
333
+
334
+ #### Styles
335
+
336
+ Thredded comes with a light Sass theme controlled by a handful of variables that can be found here:
337
+ https://github.com/thredded/thredded/blob/master/app/assets/stylesheets/thredded/base/_variables.scss.
338
+
339
+ To override the styles, override the variables *before* importing Thredded styles, e.g.:
340
+
341
+ ```scss
342
+ // application.scss
343
+ $thredded-brand: #9c27b0;
344
+ @import "thredded";
345
+ ```
346
+
347
+ If you are writing a Thredded plugin, import the [`thredded/base`][thredded-scss-base] Sass package instead.
348
+ The `base` package only defines variables, mixins, and %-placeholders, so it can be imported safely without producing
349
+ any duplicate CSS.
350
+
351
+ [thredded-scss-dependencies]: https://github.com/thredded/thredded/blob/master/app/assets/stylesheets/thredded/_dependencies.scss
352
+ [thredded-scss-base]: https://github.com/thredded/thredded/blob/master/app/assets/stylesheets/thredded/_base.scss
353
+
354
+ ### Email and other notifications
355
+
356
+ Thredded sends several notification emails to the users. You can override in the same way as the views.
357
+ See [this page](https://github.com/thredded/thredded/wiki/Styling-email-content) on how to style the emails.
358
+
359
+ If you use [Rails Email Preview], you can include Thredded emails into the list of previews by adding
360
+ `Thredded::BaseMailerPreview.preview_classes` to the [Rails Email Preview] `preview_classes` config option.
361
+
362
+ [Rails Email Preview]: https://github.com/glebm/rails_email_preview
363
+
364
+ You can also turn off the email notifier totally, or add other notifiers (e.g. Pushover, possibly Slack) by adjusting
365
+ the `Thredded.notifiers` configuration in your initializer. See the default initializer for examples.
366
+
367
+ ### Enabling auto-follow
368
+
369
+ In some cases, you'll want all users to auto-follow new messageboard topics by default. This might be useful
370
+ for a team messageboard or a company announcements board, for example. To enable user auto-follow of new topics,
371
+ run the following migration(s):
372
+
373
+ ```ruby
374
+ change_column_default :thredded_user_preferences, :auto_follow_topics, 1
375
+ ```
376
+
377
+ ## I18n
378
+
379
+ Thredded is mostly internationalized. It is currently available in English, Brazilian Portuguese, Chinese (Simplified),
380
+ German, Polish, Italian, Russian, French, and Spanish.
381
+ We welcome PRs adding support for new languages.
382
+
383
+ Here are the steps to ensure the best support for your language if it isn't English:
384
+
385
+ 1. Add `rails-i18n` and `kaminari-i18n` to your Gemfile.
386
+
387
+ 2. Require the translations for timeago.js in your JavaScript. E.g. for Brazilian Portuguese:
388
+
389
+ ```js
390
+ //= require thredded/dependencies/timeago
391
+ //= require timeago/locales/pt_BR
392
+ //= require thredded
393
+ ```
394
+
395
+ Note that it is important that timeago and its locales are required *before* `//= require thredded`.
396
+
397
+ 3. To generate URL slugs for messageboards, categories, and topics with support for more language than English,
398
+ you can use a gem like [babosa](https://github.com/norman/babosa).
399
+ Add babosa to your Gemfile and uncomment the `Thredded.slugifier` proc for babosa in the initializer.
400
+
401
+ ## Permissions
402
+
403
+ Thredded comes with a flexible permissions system that can be configured per messageboard/user.
404
+ It calls a handful of methods on the application `User` model to determine permissions for logged in users, and calls
405
+ the same methods on `Thredded:NullUser` to determine permissions for non-logged in users.
406
+
407
+ ### Permission methods
408
+
409
+ The methods used by Thredded for determining the permissions are described below.
410
+
411
+ * To customize permissions for logged in users, override any of the methods below on your `User` model.
412
+ * To customize permissions for non-logged in users, override these methods on `Thredded::NullUser`.
413
+
414
+ #### Reading messageboards
415
+
416
+ 1. A list of messageboards that a given user can read:
417
+
418
+ ```ruby
419
+ # @return [ActiveRecord::Relation] messageboards that the user can read
420
+ thredded_can_read_messageboards
421
+ ```
422
+ 2. A list of users that can read a given list of messageboards:
423
+
424
+ ```ruby
425
+ # @param messageboards [Array<Thredded::Messageboard>]
426
+ # @return [ActiveRecord::Relation] users that can read the given messageboards
427
+ self.thredded_messageboards_readers(messageboards)
428
+ ```
429
+
430
+ #### Posting to messageboards
431
+
432
+ A list of messageboards that a given user can post in.
433
+
434
+ ```ruby
435
+ # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can post in
436
+ thredded_can_write_messageboards
437
+ ```
438
+
439
+ #### Messaging other users (posting to private topics)
440
+
441
+ A list of users a given user can message:
442
+
443
+ ```ruby
444
+ # @return [ActiveRecord::Relation] the users this user can include in a private topic
445
+ thredded_can_message_users
446
+ ```
447
+
448
+ #### Moderating messageboards
449
+
450
+ A list of messageboards that a given user can moderate:
451
+
452
+ ```ruby
453
+ # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can moderate
454
+ thredded_can_moderate_messageboards
455
+ ```
456
+
457
+ #### Admin permissions
458
+
459
+ Includes all of the above for all messageboards:
460
+
461
+ ```ruby
462
+ # @return [boolean] Whether this user has full admin rights on Thredded
463
+ thredded_admin?
464
+ ```
465
+
466
+ ### Default permissions
467
+
468
+ Below is an overview of the default permissions, with links to the implementations:
469
+
470
+ <table>
471
+ <thead>
472
+ <tr>
473
+ <th align="center"></th>
474
+ <th align="center">Read</th>
475
+ <th align="center">Post</th>
476
+ <th align="center">Message</th>
477
+ <th align="center">Moderate</th>
478
+ <th align="center">Administrate</th>
479
+ </tr>
480
+ </thead>
481
+ <tbody>
482
+ <tr>
483
+ <th align="center">Logged in</th>
484
+ <td align="center" rowspan="2"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/read/all.rb">
485
+ ✅ All
486
+ </a></td>
487
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/write/all.rb">
488
+ ✅ All
489
+ </a></td>
490
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb">
491
+ Readers of the messageboards<br>the user can post in
492
+ </a></td>
493
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb">
494
+ <code>moderator_column</code>
495
+ </a></td>
496
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/admin/if_admin_column_true.rb">
497
+ <code>admin_column</code>
498
+ </a></td>
499
+ </tr>
500
+ <tr>
501
+ <th align="center">Not logged in</th>
502
+ <!-- rowspan -->
503
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/write/none.rb">
504
+ ❌ No
505
+ </a></td>
506
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb">
507
+ ❌ No
508
+ </a></td>
509
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/moderate/none.rb">
510
+ ❌ No
511
+ </a></td>
512
+ <td align="center"><a href="https://github.com/thredded/thredded/blob/master/app/models/thredded/user_permissions/admin/none.rb">
513
+ ❌ No
514
+ </a></td>
515
+ </tr>
516
+ </tbody>
517
+ </table>
518
+
519
+ ### Handling "Permission denied" and "Not found" errors
520
+
521
+ Thredded defines a number of Exception classes for not found / permission denied errors.
522
+ The complete list can be found [here](https://github.com/thredded/thredded/blob/master/app/controllers/thredded/application_controller.rb#L18-L40).
523
+
524
+ Currently, the default behaviour is to render an error message with an appropriate response code within the Thredded
525
+ layout. You may want to override the handling for `Thredded::Errors::LoginRequired` to render a login form instead.
526
+ For an example of how to do this, see the initializer.
527
+
528
+ ## Moderation
529
+
530
+ Thredded comes with two options for the moderation system:
531
+
532
+ 1. Reactive moderation, where posts from first-time users are published immediately but enter the moderation queue
533
+ (default).
534
+ 2. Pre-emptive moderation, where posts from first-time users are not published until they have been approved.
535
+
536
+ This is controlled by the `Thredded.content_visible_while_pending_moderation` setting.
537
+
538
+ Users, topics, and posts can be in one of three moderation states: `pending_moderation`, `approved`, and `blocked`.
539
+ By default, new users are `pending_moderation`, and new posts and topics inherit their default moderation_state from
540
+ the user's.
541
+
542
+ When you approve a new user's post, all of their later posts will be approved automatically.
543
+
544
+ Additionally, users always see their own posts regardless of the moderation state. For blocked users, this means
545
+ they might not realize they have been blocked right away.
546
+
547
+ Blocked users cannot send private messages.
548
+
549
+ ### Disabling moderation
550
+
551
+ To disable moderation, e.g. if you run internal forums that do not need moderation, run the following migration:
552
+
553
+ ```ruby
554
+ change_column_default :thredded_user_details, :moderation_state, 1 # approved
555
+ ```
556
+
557
+ ### Requiring authentication to access Thredded
558
+
559
+ To require users to be authenticated to access any part of Thredded, add the following to your initializer:
560
+
561
+ ```ruby
562
+ # config/initializers/thredded.rb
563
+ Rails.application.config.to_prepare do
564
+ Thredded::ApplicationController.module_eval do
565
+ # Require authentication to access the forums:
566
+ before_action :thredded_require_login!
567
+
568
+ # You may also want to render a login form after the
569
+ # "Please sign in first" message:
570
+ rescue_from Thredded::Errors::LoginRequired do |exception|
571
+ # Place the code for rendering the login form here, for example:
572
+ @message = exception.message
573
+ render template: 'sessions/new', status: :forbidden
574
+ end
575
+ end
576
+ end
577
+ ```
578
+
579
+ ## Plugins
580
+
581
+ The following official plugins are available for Thredded:
582
+
583
+ * [BBCode](https://github.com/thredded/thredded-bbcode) formatting for posts, e.g. `[b]for bold[/b]`. Can be used alongside Markdown.
584
+ * [Code Syntax Highlighting in Markdown](https://github.com/thredded/thredded-markdown_coderay) using Coderay.
585
+ * [TeX math via KaTeX in Markdown](https://github.com/thredded/thredded-markdown_katex), fast, accessible, JS-free math rendering.
586
+
587
+ Thredded is built for extensibility, and writing plugins for it is easy. If you plan on extending Thredded functionality
588
+ in a way others may benefit from, please consider making it a plugin.
589
+
590
+ ## Development
591
+
592
+ To be more clear - this is the for when you are working on *this* gem.
593
+ Not for when you are implementing it into your Rails app.
594
+
595
+ First, to get started, migrate and seed the database (SQLite by default):
596
+
597
+ ```bash
598
+ bundle
599
+ # Create, migrate, and seed the development database with fake forum users, topics, and posts:
600
+ rake db:create db:migrate db:seed
601
+ ```
602
+
603
+ Then, start the dummy app server:
604
+
605
+ ```bash
606
+ rake dev:server
607
+ ```
608
+
609
+ ### Testing
610
+
611
+ To run the tests, just run `rspec`. The test suite will re-create the test database on every run, so there is no need to
612
+ run tasks that maintain the test database.
613
+
614
+ By default, SQLite is used in development and test. On Travis, the tests will run using SQLite, PostgreSQL, MySQL,
615
+ and all the supported Rails versions.
616
+
617
+ The test suite requires Chromium v59+ and its WebDriver installed:
618
+
619
+ On Ubuntu, run:
620
+
621
+ ```bash
622
+ sudo apt-get install chromium-chromedriver
623
+ ```
624
+
625
+ On Mac, run:
626
+
627
+ ```bash
628
+ brew cask install chromium
629
+ brew install chromedriver
630
+ ```
631
+
632
+ ### Ruby
633
+
634
+ Thredded Ruby code formatting is ensured by [Rubocop](https://github.com/bbatsov/rubocop). Run `rubocop -a` to ensure a
635
+ consistent code style across the codebase.
636
+
637
+ Thredded is documented with [YARD](http://yardoc.org/) and you can use the
638
+ [inch gem](https://github.com/rrrene/inch) or the [Inch CI](http://inch-ci.org/github/thredded/thredded) to find code
639
+ that lacks documentation.
640
+
641
+ ### JavaScript
642
+
643
+ Currently, Thredded JavaScript is written in the subset of ES6 that does not
644
+ require Babel polyfills. We're waiting for the ES6/7 support on Rails to improve
645
+ before updating this to full Babel.
646
+
647
+ All Thredded JavaScript is compatible with the following Turbolinks options:
648
+
649
+ * No Turbolinks.
650
+ * Tubrolinks 5.
651
+ * Turbolinks Classic.
652
+ * Turbolinks Classic + jquery-turbolinks.
653
+
654
+ Thredded JavaScript is also compatible with being loaded from script elements with
655
+ `[async]` and/or `[defer]` attributes.
656
+
657
+ To achieve the above, all the Thredded code must register onload via
658
+ `Thredded.onPageLoad`, e.g.:
659
+
660
+ ```js
661
+ window.Thredded.onPageLoad(() => {
662
+ // Initialize widgets
663
+ autosize('textarea');
664
+ });
665
+ ```
666
+
667
+ Additionally, all the thredded views must be wrapped in a `<%= thredded_page do %>` block.
668
+
669
+ On Turbolinks 5 onPageLoad will run on the same DOM when the page is restored
670
+ from history (because Turbolinks 5 caches a *clone* of the body node, so
671
+ the events are lost).
672
+
673
+ This means that all DOM modifications on `window.Thredded.onPageLoad` must be
674
+ idempotent, or they must be reverted on the `turbolinks:before-cache` event,
675
+ e.g.:
676
+
677
+ ```js
678
+ document.addEventListener('turbolinks:before-cache', () => {
679
+ // Destroy widgets
680
+ autosize.destroy('textarea');
681
+ });
682
+ ```
683
+
684
+ ### Testing with all the databases and Rails versions locally.
685
+
686
+ You can also test the gem with all the supported databases and Rails versions locally.
687
+
688
+ First install PostgreSQL and MySQL, and run:
689
+
690
+ ```bash
691
+ script/create-db-users
692
+ ```
693
+
694
+ Then, to test with all the databases and the default Rails version (as defined in `Gemfile`), run:
695
+
696
+ ```bash
697
+ rake test_all_dbs
698
+ ```
699
+
700
+ To test with a specific database and all the Rails versions, run:
701
+
702
+ ```bash
703
+ # Test with SQLite3:
704
+ rake test_all_gemfiles
705
+ # Test with MySQL:
706
+ DB=mysql2 rake test_all_gemfiles
707
+ # Test with PostgreSQL:
708
+ DB=postgresql rake test_all_gemfiles
709
+ ```
710
+
711
+ To test all combinations of supported databases and Rails versions, run:
712
+
713
+ ```bash
714
+ rake test_all
715
+ ```
716
+
717
+ ### Developing and Testing with [Docker Compose](http://docs.docker.com/compose/)
718
+
719
+ To quickly try out _Thredded_ with the included dummy app, clone the source and
720
+ start the included docker-compose.yml file with:
721
+
722
+ ```console
723
+ docker-compose build
724
+ docker-compose up -d
725
+ ```
726
+
727
+ The above will build and run everything, daemonized, resulting in a running
728
+ instance on port 9292. Running `docker-compose logs` will let you know when
729
+ everything is up and running. Editing the source on your host machine will
730
+ be reflected in the running docker'ized application.
731
+
732
+ Note that when using [boot2docker](https://github.com/boot2docker/boot2docker)
733
+ on a Mac make sure you visit the boot2docker host ip at
734
+ `http://$(boot2docker ip):9292`.
735
+
736
+ After booting up the containers you can run the test suite with the following:
737
+
738
+ ```console
739
+ docker-compose run web bundle exec rake
740
+ ```
741
+
742
+ The docker container uses PostgreSQL.
743
+
744
+ [initializer]: https://github.com/thredded/thredded/blob/master/lib/generators/thredded/install/templates/initializer.rb