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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +744 -0
- data/app/assets/images/favicons/README.md +3 -0
- data/app/assets/images/favicons/amazon.png +0 -0
- data/app/assets/images/favicons/github.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_calendar_128px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_docs_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_drive_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_forms_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_sheets_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_slides_48px.png +0 -0
- data/app/assets/images/favicons/stackexchange.png +0 -0
- data/app/assets/images/favicons/twitter.png +0 -0
- data/app/assets/images/favicons/wikipedia.png +0 -0
- data/app/assets/images/thredded/breadcrumb-chevron.svg +1 -0
- data/app/assets/images/thredded/follow.svg +1 -0
- data/app/assets/images/thredded/lock.svg +1 -0
- data/app/assets/images/thredded/moderation.svg +1 -0
- data/app/assets/images/thredded/private-messages.svg +1 -0
- data/app/assets/images/thredded/settings.svg +1 -0
- data/app/assets/images/thredded/three-dot-menu.svg +3 -0
- data/app/assets/images/thredded/unfollow.svg +1 -0
- data/app/assets/javascripts/thredded.es6 +2 -0
- data/app/assets/javascripts/thredded/components/currently_online.es6 +32 -0
- data/app/assets/javascripts/thredded/components/flash_messages.es6 +9 -0
- data/app/assets/javascripts/thredded/components/mention_autocompletion.es6 +40 -0
- data/app/assets/javascripts/thredded/components/post_form.es6 +37 -0
- data/app/assets/javascripts/thredded/components/preview_area.es6 +56 -0
- data/app/assets/javascripts/thredded/components/quote_post.es6 +49 -0
- data/app/assets/javascripts/thredded/components/time_stamps.es6 +25 -0
- data/app/assets/javascripts/thredded/components/topic_form.es6 +94 -0
- data/app/assets/javascripts/thredded/components/topics.es6 +46 -0
- data/app/assets/javascripts/thredded/components/turboforms.es6 +25 -0
- data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +66 -0
- data/app/assets/javascripts/thredded/components/user_textcomplete.es6 +50 -0
- data/app/assets/javascripts/thredded/components/users_select.es6 +122 -0
- data/app/assets/javascripts/thredded/core/csrf_tokens.es6 +9 -0
- data/app/assets/javascripts/thredded/core/debounce.es6 +32 -0
- data/app/assets/javascripts/thredded/core/escape_html.es6 +7 -0
- data/app/assets/javascripts/thredded/core/hide_soft_keyboard.es6 +7 -0
- data/app/assets/javascripts/thredded/core/on_page_load.es6 +54 -0
- data/app/assets/javascripts/thredded/core/serialize_form.es6 +9 -0
- data/app/assets/javascripts/thredded/core/thredded.es6 +1 -0
- data/app/assets/javascripts/thredded/dependencies.js +8 -0
- data/app/assets/javascripts/thredded/dependencies/autosize.js +1 -0
- data/app/assets/javascripts/thredded/dependencies/textcomplete.js +1 -0
- data/app/assets/javascripts/thredded/dependencies/timeago.js +1 -0
- data/app/assets/javascripts/thredded/dependencies/ujs.js +1 -0
- data/app/assets/javascripts/thredded/thredded.es6 +2 -0
- data/app/assets/stylesheets/thredded.scss +3 -0
- data/app/assets/stylesheets/thredded/_base.scss +13 -0
- data/app/assets/stylesheets/thredded/_dependencies.scss +0 -0
- data/app/assets/stylesheets/thredded/_email.scss +51 -0
- data/app/assets/stylesheets/thredded/_thredded.scss +33 -0
- data/app/assets/stylesheets/thredded/base/_alerts.scss +44 -0
- data/app/assets/stylesheets/thredded/base/_buttons.scss +73 -0
- data/app/assets/stylesheets/thredded/base/_dropdown-menu.scss +83 -0
- data/app/assets/stylesheets/thredded/base/_forms.scss +84 -0
- data/app/assets/stylesheets/thredded/base/_grid.scss +58 -0
- data/app/assets/stylesheets/thredded/base/_lists.scss +31 -0
- data/app/assets/stylesheets/thredded/base/_nav.scss +67 -0
- data/app/assets/stylesheets/thredded/base/_tables.scss +17 -0
- data/app/assets/stylesheets/thredded/base/_typography.scss +72 -0
- data/app/assets/stylesheets/thredded/base/_variables.scss +141 -0
- data/app/assets/stylesheets/thredded/components/_alerts.scss +19 -0
- data/app/assets/stylesheets/thredded/components/_base.scss +25 -0
- data/app/assets/stylesheets/thredded/components/_currently-online.scss +54 -0
- data/app/assets/stylesheets/thredded/components/_empty.scss +11 -0
- data/app/assets/stylesheets/thredded/components/_flash-message.scss +19 -0
- data/app/assets/stylesheets/thredded/components/_following.scss +14 -0
- data/app/assets/stylesheets/thredded/components/_form-list.scss +39 -0
- data/app/assets/stylesheets/thredded/components/_icons.scss +3 -0
- data/app/assets/stylesheets/thredded/components/_main-section.scss +9 -0
- data/app/assets/stylesheets/thredded/components/_mention-autocomplete.scss +57 -0
- data/app/assets/stylesheets/thredded/components/_messageboard.scss +155 -0
- data/app/assets/stylesheets/thredded/components/_onebox.scss +275 -0
- data/app/assets/stylesheets/thredded/components/_pagination.scss +35 -0
- data/app/assets/stylesheets/thredded/components/_post-form.scss +27 -0
- data/app/assets/stylesheets/thredded/components/_post.scss +138 -0
- data/app/assets/stylesheets/thredded/components/_preferences.scss +19 -0
- data/app/assets/stylesheets/thredded/components/_preview_area.scss +11 -0
- data/app/assets/stylesheets/thredded/components/_topic-delete.scss +8 -0
- data/app/assets/stylesheets/thredded/components/_topic-header.scss +111 -0
- data/app/assets/stylesheets/thredded/components/_topics.scss +186 -0
- data/app/assets/stylesheets/thredded/layout/_main-container.scss +16 -0
- data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +79 -0
- data/app/assets/stylesheets/thredded/layout/_moderation.scss +97 -0
- data/app/assets/stylesheets/thredded/layout/_navigation.scss +87 -0
- data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +126 -0
- data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +20 -0
- data/app/assets/stylesheets/thredded/layout/_user.scss +10 -0
- data/app/assets/stylesheets/thredded/utilities/_is-compact.scss +26 -0
- data/app/assets/stylesheets/thredded/utilities/_is-expanded.scss +16 -0
- data/app/commands/thredded/at_notification_extractor.rb +23 -0
- data/app/commands/thredded/autofollow_users.rb +62 -0
- data/app/commands/thredded/create_messageboard.rb +42 -0
- data/app/commands/thredded/mark_all_read.rb +22 -0
- data/app/commands/thredded/moderate_post.rb +48 -0
- data/app/commands/thredded/notify_following_users.rb +78 -0
- data/app/commands/thredded/notify_private_topic_users.rb +34 -0
- data/app/controllers/concerns/thredded/new_post_params.rb +21 -0
- data/app/controllers/concerns/thredded/new_private_post_params.rb +21 -0
- data/app/controllers/concerns/thredded/new_private_topic_params.rb +25 -0
- data/app/controllers/concerns/thredded/new_topic_params.rb +19 -0
- data/app/controllers/concerns/thredded/render_preview.rb +16 -0
- data/app/controllers/thredded/application_controller.rb +145 -0
- data/app/controllers/thredded/autocomplete_users_controller.rb +52 -0
- data/app/controllers/thredded/messageboard_groups_controller.rb +31 -0
- data/app/controllers/thredded/messageboards_controller.rb +53 -0
- data/app/controllers/thredded/moderation_controller.rb +103 -0
- data/app/controllers/thredded/post_permalinks_controller.rb +11 -0
- data/app/controllers/thredded/post_previews_controller.rb +29 -0
- data/app/controllers/thredded/posts_controller.rb +97 -0
- data/app/controllers/thredded/preferences_controller.rb +42 -0
- data/app/controllers/thredded/private_post_permalinks_controller.rb +12 -0
- data/app/controllers/thredded/private_post_previews_controller.rb +29 -0
- data/app/controllers/thredded/private_posts_controller.rb +96 -0
- data/app/controllers/thredded/private_topic_previews_controller.rb +15 -0
- data/app/controllers/thredded/private_topics_controller.rb +102 -0
- data/app/controllers/thredded/read_states_controller.rb +13 -0
- data/app/controllers/thredded/theme_previews_controller.rb +34 -0
- data/app/controllers/thredded/topic_previews_controller.rb +15 -0
- data/app/controllers/thredded/topics_controller.rb +205 -0
- data/app/forms/thredded/edit_topic_form.rb +51 -0
- data/app/forms/thredded/post_form.rb +54 -0
- data/app/forms/thredded/private_post_form.rb +50 -0
- data/app/forms/thredded/private_topic_form.rb +160 -0
- data/app/forms/thredded/topic_form.rb +95 -0
- data/app/forms/thredded/user_preferences_form.rb +110 -0
- data/app/helpers/thredded/application_helper.rb +129 -0
- data/app/helpers/thredded/nav_helper.rb +42 -0
- data/app/helpers/thredded/render_helper.rb +15 -0
- data/app/helpers/thredded/urls_helper.rb +134 -0
- data/app/jobs/thredded/activity_updater_job.rb +21 -0
- data/app/jobs/thredded/auto_follow_and_notify_job.rb +14 -0
- data/app/jobs/thredded/notify_private_topic_users_job.rb +12 -0
- data/app/mailer_previews/thredded/base_mailer_preview.rb +118 -0
- data/app/mailer_previews/thredded/post_mailer_preview.rb +13 -0
- data/app/mailer_previews/thredded/private_topic_mailer_preview.rb +13 -0
- data/app/mailers/thredded/base_mailer.rb +18 -0
- data/app/mailers/thredded/post_mailer.rb +21 -0
- data/app/mailers/thredded/private_topic_mailer.rb +21 -0
- data/app/models/concerns/thredded/content_moderation_state.rb +67 -0
- data/app/models/concerns/thredded/friendly_id_reserved_words_and_pagination.rb +17 -0
- data/app/models/concerns/thredded/moderation_state.rb +14 -0
- data/app/models/concerns/thredded/notifier_preference.rb +19 -0
- data/app/models/concerns/thredded/post_common.rb +76 -0
- data/app/models/concerns/thredded/search_parser.rb +41 -0
- data/app/models/concerns/thredded/topic_common.rb +94 -0
- data/app/models/concerns/thredded/topics_search.rb +67 -0
- data/app/models/concerns/thredded/user_topic_read_state_common.rb +42 -0
- data/app/models/thredded/category.rb +18 -0
- data/app/models/thredded/messageboard.rb +120 -0
- data/app/models/thredded/messageboard_group.rb +19 -0
- data/app/models/thredded/messageboard_notifications_for_followed_topics.rb +30 -0
- data/app/models/thredded/messageboard_user.rb +14 -0
- data/app/models/thredded/notifications_for_followed_topics.rb +25 -0
- data/app/models/thredded/notifications_for_private_topics.rb +22 -0
- data/app/models/thredded/null_user.rb +51 -0
- data/app/models/thredded/null_user_topic_read_state.rb +17 -0
- data/app/models/thredded/post.rb +77 -0
- data/app/models/thredded/post_moderation_record.rb +56 -0
- data/app/models/thredded/private_post.rb +63 -0
- data/app/models/thredded/private_topic.rb +89 -0
- data/app/models/thredded/private_user.rb +8 -0
- data/app/models/thredded/stats.rb +25 -0
- data/app/models/thredded/topic.rb +179 -0
- data/app/models/thredded/topic_category.rb +8 -0
- data/app/models/thredded/user_detail.rb +27 -0
- data/app/models/thredded/user_extender.rb +75 -0
- data/app/models/thredded/user_messageboard_preference.rb +45 -0
- data/app/models/thredded/user_permissions/admin/if_admin_column_true.rb +14 -0
- data/app/models/thredded/user_permissions/admin/none.rb +14 -0
- data/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb +15 -0
- data/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb +16 -0
- data/app/models/thredded/user_permissions/moderate/none.rb +16 -0
- data/app/models/thredded/user_permissions/read/all.rb +27 -0
- data/app/models/thredded/user_permissions/write/all.rb +16 -0
- data/app/models/thredded/user_permissions/write/none.rb +16 -0
- data/app/models/thredded/user_post_notification.rb +29 -0
- data/app/models/thredded/user_preference.rb +26 -0
- data/app/models/thredded/user_private_topic_read_state.rb +13 -0
- data/app/models/thredded/user_topic_follow.rb +34 -0
- data/app/models/thredded/user_topic_read_state.rb +13 -0
- data/app/notifiers/thredded/email_notifier.rb +25 -0
- data/app/policies/thredded/messageboard_group_policy.rb +16 -0
- data/app/policies/thredded/messageboard_policy.rb +49 -0
- data/app/policies/thredded/post_policy.rb +64 -0
- data/app/policies/thredded/private_post_policy.rb +38 -0
- data/app/policies/thredded/private_topic_policy.rb +24 -0
- data/app/policies/thredded/topic_policy.rb +49 -0
- data/app/view_hooks/thredded/all_view_hooks.rb +125 -0
- data/app/view_models/thredded/base_topic_view.rb +43 -0
- data/app/view_models/thredded/messageboard_group_view.rb +27 -0
- data/app/view_models/thredded/post_view.rb +89 -0
- data/app/view_models/thredded/posts_page_view.rb +27 -0
- data/app/view_models/thredded/private_topic_view.rb +20 -0
- data/app/view_models/thredded/private_topics_page_view.rb +31 -0
- data/app/view_models/thredded/topic_email_view.rb +18 -0
- data/app/view_models/thredded/topic_posts_page_view.rb +17 -0
- data/app/view_models/thredded/topic_view.rb +68 -0
- data/app/view_models/thredded/topics_page_view.rb +38 -0
- data/app/views/layouts/thredded/application.html.erb +18 -0
- data/app/views/thredded/categories/_category.html.erb +1 -0
- data/app/views/thredded/error_pages/forbidden.html.erb +6 -0
- data/app/views/thredded/error_pages/not_found.html.erb +6 -0
- data/app/views/thredded/kaminari/_first_page.html.erb +11 -0
- data/app/views/thredded/kaminari/_gap.html.erb +8 -0
- data/app/views/thredded/kaminari/_last_page.html.erb +11 -0
- data/app/views/thredded/kaminari/_next_page.html.erb +11 -0
- data/app/views/thredded/kaminari/_page.html.erb +12 -0
- data/app/views/thredded/kaminari/_paginator.html.erb +23 -0
- data/app/views/thredded/kaminari/_prev_page.html.erb +11 -0
- data/app/views/thredded/messageboard_groups/new.html.erb +28 -0
- data/app/views/thredded/messageboards/_form.html.erb +30 -0
- data/app/views/thredded/messageboards/_messageboard.html.erb +20 -0
- data/app/views/thredded/messageboards/_messageboard_meta.html.erb +13 -0
- data/app/views/thredded/messageboards/edit.html.erb +15 -0
- data/app/views/thredded/messageboards/index.html.erb +34 -0
- data/app/views/thredded/messageboards/new.html.erb +15 -0
- data/app/views/thredded/moderation/_nav.html.erb +19 -0
- data/app/views/thredded/moderation/_post.html.erb +19 -0
- data/app/views/thredded/moderation/_post_moderation_actions.html.erb +12 -0
- data/app/views/thredded/moderation/_post_moderation_record.html.erb +46 -0
- data/app/views/thredded/moderation/_user_moderation_state.html.erb +3 -0
- data/app/views/thredded/moderation/_user_post.html.erb +12 -0
- data/app/views/thredded/moderation/_users_search_form.html.erb +13 -0
- data/app/views/thredded/moderation/activity.html.erb +20 -0
- data/app/views/thredded/moderation/history.html.erb +13 -0
- data/app/views/thredded/moderation/pending.html.erb +24 -0
- data/app/views/thredded/moderation/user.html.erb +54 -0
- data/app/views/thredded/moderation/users.html.erb +41 -0
- data/app/views/thredded/post_mailer/post_notification.html.erb +26 -0
- data/app/views/thredded/post_mailer/post_notification.text.erb +14 -0
- data/app/views/thredded/post_previews/preview.html.erb +1 -0
- data/app/views/thredded/post_previews/update.html.erb +1 -0
- data/app/views/thredded/posts/_content.html.erb +1 -0
- data/app/views/thredded/posts/_form.html.erb +5 -0
- data/app/views/thredded/posts/_post.html.erb +13 -0
- data/app/views/thredded/posts/_user.html.erb +3 -0
- data/app/views/thredded/posts/edit.html.erb +16 -0
- data/app/views/thredded/posts/new.html.erb +15 -0
- data/app/views/thredded/posts_common/_actions.html.erb +28 -0
- data/app/views/thredded/posts_common/_content.html.erb +3 -0
- data/app/views/thredded/posts_common/_form.html.erb +22 -0
- data/app/views/thredded/posts_common/_header.html.erb +8 -0
- data/app/views/thredded/posts_common/_header_with_topic.html.erb +15 -0
- data/app/views/thredded/posts_common/_header_with_user_and_topic.html.erb +18 -0
- data/app/views/thredded/posts_common/actions/_delete.html.erb +4 -0
- data/app/views/thredded/posts_common/actions/_edit.html.erb +3 -0
- data/app/views/thredded/posts_common/actions/_mark_as_unread.html.erb +2 -0
- data/app/views/thredded/posts_common/actions/_quote.html.erb +4 -0
- data/app/views/thredded/posts_common/form/_after_content.html.erb +8 -0
- data/app/views/thredded/posts_common/form/_before_content.html.erb +8 -0
- data/app/views/thredded/posts_common/form/_content.html.erb +7 -0
- data/app/views/thredded/posts_common/form/_content_field.html.erb +8 -0
- data/app/views/thredded/posts_common/form/_preview_area.html.erb +16 -0
- data/app/views/thredded/preferences/_form.html.erb +95 -0
- data/app/views/thredded/preferences/_messageboards_nav.html.erb +8 -0
- data/app/views/thredded/preferences/_messageboards_nav_item.html.erb +2 -0
- data/app/views/thredded/preferences/edit.html.erb +20 -0
- data/app/views/thredded/private_post_previews/preview.html.erb +1 -0
- data/app/views/thredded/private_post_previews/update.html.erb +1 -0
- data/app/views/thredded/private_posts/_content.html.erb +1 -0
- data/app/views/thredded/private_posts/_form.html.erb +6 -0
- data/app/views/thredded/private_posts/_private_post.html.erb +6 -0
- data/app/views/thredded/private_posts/edit.html.erb +16 -0
- data/app/views/thredded/private_posts/new.html.erb +11 -0
- data/app/views/thredded/private_topic_mailer/message_notification.html.erb +26 -0
- data/app/views/thredded/private_topic_mailer/message_notification.text.erb +15 -0
- data/app/views/thredded/private_topic_previews/preview.html.erb +1 -0
- data/app/views/thredded/private_topics/_breadcrumbs.html.erb +4 -0
- data/app/views/thredded/private_topics/_form.html.erb +39 -0
- data/app/views/thredded/private_topics/_header.html.erb +17 -0
- data/app/views/thredded/private_topics/_no_private_topics.html.erb +6 -0
- data/app/views/thredded/private_topics/_private_topic.html.erb +23 -0
- data/app/views/thredded/private_topics/edit.html.erb +35 -0
- data/app/views/thredded/private_topics/header/_participant.html.erb +1 -0
- data/app/views/thredded/private_topics/index.html.erb +32 -0
- data/app/views/thredded/private_topics/new.html.erb +11 -0
- data/app/views/thredded/private_topics/private_topic/_participant.html.erb +1 -0
- data/app/views/thredded/private_topics/show.html.erb +28 -0
- data/app/views/thredded/search/_form.html.erb +13 -0
- data/app/views/thredded/shared/_breadcrumbs.html.erb +6 -0
- data/app/views/thredded/shared/_content_moderation_blocked_state.html.erb +8 -0
- data/app/views/thredded/shared/_currently_online.html.erb +6 -0
- data/app/views/thredded/shared/_flash_messages.html.erb +7 -0
- data/app/views/thredded/shared/_header.html.erb +3 -0
- data/app/views/thredded/shared/_nav.html.erb +19 -0
- data/app/views/thredded/shared/_page.html.erb +15 -0
- data/app/views/thredded/shared/currently_online/_header.html.erb +5 -0
- data/app/views/thredded/shared/currently_online/_user_list.html.erb +3 -0
- data/app/views/thredded/shared/currently_online/_user_list_item.html.erb +6 -0
- data/app/views/thredded/shared/nav/_moderation.html.erb +14 -0
- data/app/views/thredded/shared/nav/_notification_preferences.html.erb +8 -0
- data/app/views/thredded/shared/nav/_private_topics.html.erb +12 -0
- data/app/views/thredded/shared/nav/_standalone.html.erb +12 -0
- data/app/views/thredded/shared/nav/_standalone_profile.html.erb +3 -0
- data/app/views/thredded/shared/preview.html.erb +10 -0
- data/app/views/thredded/theme_previews/_section_title.html.erb +3 -0
- data/app/views/thredded/theme_previews/show.html.erb +99 -0
- data/app/views/thredded/topic_previews/preview.html.erb +1 -0
- data/app/views/thredded/topics/_followers.html.erb +12 -0
- data/app/views/thredded/topics/_form.html.erb +32 -0
- data/app/views/thredded/topics/_header.html.erb +32 -0
- data/app/views/thredded/topics/_sticky_topics_divider.html.erb +1 -0
- data/app/views/thredded/topics/_topic.html.erb +47 -0
- data/app/views/thredded/topics/_topic_form_admin_options.html.erb +12 -0
- data/app/views/thredded/topics/edit.html.erb +50 -0
- data/app/views/thredded/topics/index.html.erb +35 -0
- data/app/views/thredded/topics/new.html.erb +12 -0
- data/app/views/thredded/topics/search.html.erb +39 -0
- data/app/views/thredded/topics/show.html.erb +46 -0
- data/app/views/thredded/users/_link.html.erb +14 -0
- data/app/views/thredded/users/_post.html.erb +6 -0
- data/app/views/thredded/users/_posts.html.erb +7 -0
- data/bin/rails +6 -0
- data/config/i18n-tasks.yml +16 -0
- data/config/locales/de.yml +257 -0
- data/config/locales/en.yml +253 -0
- data/config/locales/es.yml +257 -0
- data/config/locales/fr.yml +255 -0
- data/config/locales/it.yml +257 -0
- data/config/locales/pl.yml +257 -0
- data/config/locales/pt-BR.yml +258 -0
- data/config/locales/ru.yml +255 -0
- data/config/locales/zh-CN.yml +246 -0
- data/config/routes.rb +87 -0
- data/db/migrate/20160329231848_create_thredded.rb +257 -0
- data/db/seeds.rb +4 -0
- data/db/upgrade_migrations/20160611094616_upgrade_v0_5_to_v0_6.rb +28 -0
- data/db/upgrade_migrations/20160723012349_upgrade_v0_6_to_v0_7.rb +46 -0
- data/db/upgrade_migrations/20161019150201_upgrade_v0_7_to_v0_8.rb +34 -0
- data/db/upgrade_migrations/20161113161801_upgrade_v0_8_to_v0_9.rb +60 -0
- data/db/upgrade_migrations/20170125033319_upgrade_v0_9_to_v0_10.rb +36 -0
- data/db/upgrade_migrations/20170312131417_upgrade_thredded_v0_10_to_v0_11.rb +23 -0
- data/db/upgrade_migrations/20170420163138_upgrade_thredded_v0_11_to_v0_12.rb +28 -0
- data/db/upgrade_migrations/20170811090735_upgrade_thredded_v0_13_to_v_014.rb +21 -0
- data/lib/generators/thredded/install/USAGE +8 -0
- data/lib/generators/thredded/install/install_generator.rb +20 -0
- data/lib/generators/thredded/install/templates/initializer.rb +160 -0
- data/lib/tasks/thredded_tasks.rake +14 -0
- data/lib/thredded.rb +190 -0
- data/lib/thredded/base_migration.rb +14 -0
- data/lib/thredded/base_notifier.rb +28 -0
- data/lib/thredded/collection_to_strings_with_cache_renderer.rb +86 -0
- data/lib/thredded/content_formatter.rb +129 -0
- data/lib/thredded/database_seeder.rb +290 -0
- data/lib/thredded/db_tools.rb +103 -0
- data/lib/thredded/email_transformer.rb +22 -0
- data/lib/thredded/email_transformer/base.rb +47 -0
- data/lib/thredded/email_transformer/onebox.rb +21 -0
- data/lib/thredded/engine.rb +28 -0
- data/lib/thredded/errors.rb +68 -0
- data/lib/thredded/formatting_demo_content.rb +30 -0
- data/lib/thredded/html_pipeline/at_mention_filter.rb +78 -0
- data/lib/thredded/html_pipeline/autolink_filter.rb +15 -0
- data/lib/thredded/html_pipeline/kramdown_filter.rb +39 -0
- data/lib/thredded/html_pipeline/onebox_filter.rb +143 -0
- data/lib/thredded/html_pipeline/wrap_iframes_filter.rb +13 -0
- data/lib/thredded/version.rb +5 -0
- data/lib/thredded/view_hooks/config.rb +37 -0
- data/lib/thredded/view_hooks/renderer.rb +30 -0
- data/vendor/assets/javascripts/autosize.min.js +6 -0
- data/vendor/assets/javascripts/textcomplete.min.js +2 -0
- metadata +1035 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thredded/base_migration'
|
|
4
|
+
|
|
5
|
+
# rubocop:disable Metrics/MethodLength
|
|
6
|
+
class UpgradeV08ToV09 < Thredded::BaseMigration
|
|
7
|
+
def up
|
|
8
|
+
create_table :thredded_notifications_for_private_topics do |t|
|
|
9
|
+
t.references :user, null: false, index: false, type: user_id_type
|
|
10
|
+
t.string :notifier_key, null: false, limit: 90
|
|
11
|
+
t.boolean :enabled, default: true, null: false
|
|
12
|
+
t.index %i[user_id notifier_key],
|
|
13
|
+
name: 'thredded_notifications_for_private_topics_unique', unique: true
|
|
14
|
+
end
|
|
15
|
+
create_table :thredded_notifications_for_followed_topics do |t|
|
|
16
|
+
t.references :user, null: false, index: false, type: user_id_type
|
|
17
|
+
t.string :notifier_key, null: false, limit: 90
|
|
18
|
+
t.boolean :enabled, default: true, null: false
|
|
19
|
+
t.index %i[user_id notifier_key],
|
|
20
|
+
name: 'thredded_notifications_for_followed_topics_unique', unique: true
|
|
21
|
+
end
|
|
22
|
+
create_table :thredded_messageboard_notifications_for_followed_topics do |t|
|
|
23
|
+
t.references :user, null: false, index: false, type: user_id_type
|
|
24
|
+
t.references :messageboard, null: false, index: false, type: column_type(:thredded_messageboards, :id)
|
|
25
|
+
t.string :notifier_key, null: false, limit: 90
|
|
26
|
+
t.boolean :enabled, default: true, null: false
|
|
27
|
+
t.index %i[user_id messageboard_id notifier_key],
|
|
28
|
+
name: 'thredded_messageboard_notifications_for_followed_topics_unique', unique: true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Thredded::UserPreference.all.each do |pref|
|
|
32
|
+
pref.notifications_for_private_topics.create(notifier_key: 'email', enabled: pref.notify_on_message)
|
|
33
|
+
pref.notifications_for_followed_topics.create(notifier_key: 'email', enabled: pref.followed_topic_emails)
|
|
34
|
+
end
|
|
35
|
+
Thredded::UserMessageboardPreference.pluck(:user_id, :messageboard_id, :followed_topic_emails)
|
|
36
|
+
.each do |user_id, messageboard_id, emails|
|
|
37
|
+
Thredded::MessageboardNotificationsForFollowedTopics.create(
|
|
38
|
+
user_id: user_id,
|
|
39
|
+
messageboard_id: messageboard_id,
|
|
40
|
+
notifier_key: 'email',
|
|
41
|
+
enabled: emails
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
remove_column :thredded_user_preferences, :notify_on_message
|
|
46
|
+
remove_column :thredded_user_preferences, :followed_topic_emails
|
|
47
|
+
remove_column :thredded_user_messageboard_preferences, :followed_topic_emails
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def down
|
|
51
|
+
add_column :thredded_user_preferences, :notify_on_message, :boolean, default: true, null: false
|
|
52
|
+
add_column :thredded_user_preferences, :followed_topic_emails, :boolean, default: true, null: false
|
|
53
|
+
add_column :thredded_user_messageboard_preferences, :followed_topic_emails, :boolean, default: true, null: false
|
|
54
|
+
|
|
55
|
+
drop_table :thredded_messageboard_notifications_for_followed_topics
|
|
56
|
+
drop_table :thredded_notifications_for_followed_topics
|
|
57
|
+
drop_table :thredded_notifications_for_private_topics
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
# rubocop:enable Metrics/MethodLength
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thredded/base_migration'
|
|
4
|
+
|
|
5
|
+
class UpgradeV09ToV010 < Thredded::BaseMigration
|
|
6
|
+
def up
|
|
7
|
+
remove_foreign_key :thredded_messageboard_users, :thredded_messageboards
|
|
8
|
+
add_foreign_key :thredded_messageboard_users, :thredded_messageboards,
|
|
9
|
+
column: :thredded_messageboard_id, on_delete: :cascade
|
|
10
|
+
remove_foreign_key :thredded_messageboard_users, :thredded_user_details
|
|
11
|
+
add_foreign_key :thredded_messageboard_users, :thredded_user_details,
|
|
12
|
+
column: :thredded_user_detail_id, on_delete: :cascade
|
|
13
|
+
|
|
14
|
+
create_table :thredded_user_post_notifications do |t|
|
|
15
|
+
t.references :user, null: false, index: false, type: user_id_type
|
|
16
|
+
t.references :post, null: false, index: false, type: column_type(:thredded_posts, :id)
|
|
17
|
+
t.datetime :notified_at, null: false
|
|
18
|
+
t.index :post_id, name: :index_thredded_user_post_notifications_on_post_id
|
|
19
|
+
t.index %i[user_id post_id], name: :index_thredded_user_post_notifications_on_user_id_and_post_id, unique: true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
add_foreign_key :thredded_user_post_notifications,
|
|
23
|
+
Thredded.user_class.table_name, column: :user_id, on_delete: :cascade
|
|
24
|
+
add_foreign_key :thredded_user_post_notifications,
|
|
25
|
+
:thredded_posts, column: :post_id, on_delete: :cascade
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def down
|
|
29
|
+
drop_table :thredded_user_post_notifications
|
|
30
|
+
|
|
31
|
+
remove_foreign_key :thredded_messageboard_users, :thredded_user_details
|
|
32
|
+
add_foreign_key :thredded_messageboard_users, :thredded_user_details
|
|
33
|
+
remove_foreign_key :thredded_messageboard_users, :thredded_messageboards
|
|
34
|
+
add_foreign_key :thredded_messageboard_users, :thredded_messageboards
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thredded/base_migration'
|
|
4
|
+
|
|
5
|
+
class UpgradeThreddedV010ToV011 < Thredded::BaseMigration
|
|
6
|
+
def up
|
|
7
|
+
drop_table :thredded_post_notifications
|
|
8
|
+
add_column :thredded_user_preferences, :auto_follow_topics, :boolean, default: false, null: false
|
|
9
|
+
add_column :thredded_user_messageboard_preferences, :auto_follow_topics, :boolean, default: false, null: false
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def down
|
|
13
|
+
remove_column :thredded_user_messageboard_preferences, :auto_follow_topics
|
|
14
|
+
remove_column :thredded_user_preferences, :auto_follow_topics
|
|
15
|
+
create_table :thredded_post_notifications do |t|
|
|
16
|
+
t.string :email, limit: 191, null: false
|
|
17
|
+
t.references :post, null: false, index: false
|
|
18
|
+
t.timestamps null: false
|
|
19
|
+
t.string :post_type, limit: 191
|
|
20
|
+
t.index %i[post_id post_type], name: :index_thredded_post_notifications_on_post
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thredded/base_migration'
|
|
4
|
+
|
|
5
|
+
class UpgradeThreddedV011ToV012 < Thredded::BaseMigration
|
|
6
|
+
def up
|
|
7
|
+
FriendlyId::Slug.transaction do
|
|
8
|
+
FriendlyId::Slug.where(sluggable_type: 'Thredded::Topic').where(
|
|
9
|
+
slug: FriendlyId::Slug.group(:slug).having('count(id) > 1').select(:slug)
|
|
10
|
+
).group_by(&:slug).each_value do |slugs|
|
|
11
|
+
slugs.from(1).each(&:delete)
|
|
12
|
+
end
|
|
13
|
+
FriendlyId::Slug.where(sluggable_type: 'Thredded::Topic')
|
|
14
|
+
.update_all(scope: nil)
|
|
15
|
+
end
|
|
16
|
+
Thredded::Topic.all.find_each do |topic|
|
|
17
|
+
# re-generate the slug
|
|
18
|
+
topic.title_will_change!
|
|
19
|
+
topic.save!
|
|
20
|
+
end
|
|
21
|
+
remove_index :thredded_topics, name: :index_thredded_topics_on_messageboard_id_and_slug
|
|
22
|
+
add_index :thredded_topics, [:slug], name: :index_thredded_topics_on_slug, unique: true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def down
|
|
26
|
+
fail ActiveRecord::MigrationError::IrreversibleMigration
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thredded/base_migration'
|
|
4
|
+
|
|
5
|
+
class UpgradeThreddedV013ToV014 < Thredded::BaseMigration
|
|
6
|
+
def change
|
|
7
|
+
add_column :thredded_messageboards, :locked, :boolean, null: false, default: false
|
|
8
|
+
remove_index :thredded_user_details,
|
|
9
|
+
name: :index_thredded_user_details_on_user_id
|
|
10
|
+
add_index :thredded_user_details,
|
|
11
|
+
:user_id,
|
|
12
|
+
name: :index_thredded_user_details_on_user_id,
|
|
13
|
+
unique: true
|
|
14
|
+
remove_index :thredded_user_preferences,
|
|
15
|
+
name: :index_thredded_user_preferences_on_user_id
|
|
16
|
+
add_index :thredded_user_preferences,
|
|
17
|
+
:user_id,
|
|
18
|
+
name: :index_thredded_user_preferences_on_user_id,
|
|
19
|
+
unique: true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Thredded
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
def set_source_paths
|
|
7
|
+
@source_paths = [
|
|
8
|
+
File.expand_path('../templates', __FILE__),
|
|
9
|
+
File.expand_path('../../../../..', __FILE__),
|
|
10
|
+
]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def copy_initializer_file
|
|
14
|
+
copy_file \
|
|
15
|
+
'initializer.rb',
|
|
16
|
+
'config/initializers/thredded.rb'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Thredded configuration
|
|
4
|
+
|
|
5
|
+
# ==> User Configuration
|
|
6
|
+
# The name of the class your app uses for your users.
|
|
7
|
+
# By default the engine will use 'User' but if you have another name
|
|
8
|
+
# for your user class - change it here.
|
|
9
|
+
Thredded.user_class = 'User'
|
|
10
|
+
|
|
11
|
+
# User name column, used in @mention syntax and *must* be unique.
|
|
12
|
+
# This is the column used to search for users' names if/when someone is @ mentioned.
|
|
13
|
+
Thredded.user_name_column = :name
|
|
14
|
+
|
|
15
|
+
# User display name method, by default thredded uses the user_name_column defined above
|
|
16
|
+
# You may want to use :to_s or some more elaborate method
|
|
17
|
+
# Thredded.user_display_name_method = :to_s
|
|
18
|
+
|
|
19
|
+
# The path (or URL) you will use to link to your users' profiles.
|
|
20
|
+
# When linking to a user, Thredded will use this lambda to spit out
|
|
21
|
+
# the path or url to your user. This lambda is evaluated in the view context.
|
|
22
|
+
# If the lambda returns nil, a span element is returned instead of a link; so
|
|
23
|
+
# setting this to always return nil effectively disables all user links.
|
|
24
|
+
Thredded.user_path = lambda do |user|
|
|
25
|
+
user_path = :"#{Thredded.user_class_name.demodulize.underscore}_path"
|
|
26
|
+
main_app.respond_to?(user_path) ? main_app.send(user_path, user) : "/users/#{user.to_param}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# This method is used by Thredded controllers and views to fetch the currently signed-in user
|
|
30
|
+
Thredded.current_user_method = :"current_#{Thredded.user_class_name.demodulize.underscore}"
|
|
31
|
+
|
|
32
|
+
# User avatar URL. rb-gravatar gem is used by default:
|
|
33
|
+
Thredded.avatar_url = ->(user) { Gravatar.src(user.email, 156, 'mm') }
|
|
34
|
+
|
|
35
|
+
# ==> Database Configuration
|
|
36
|
+
# By default, thredded uses integers for record ID route constraints.
|
|
37
|
+
# For integer based IDs (default):
|
|
38
|
+
# Thredded.routes_id_constraint = /[1-9]\d*/
|
|
39
|
+
# For UUID based IDs (example):
|
|
40
|
+
# Thredded.routes_id_constraint = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
|
|
41
|
+
|
|
42
|
+
# ==> Permissions Configuration
|
|
43
|
+
# By default, thredded uses a simple permission model, where all the users can post to all message boards,
|
|
44
|
+
# and admins and moderators are determined by a flag on the users table.
|
|
45
|
+
|
|
46
|
+
# The name of the moderator flag column on the users table.
|
|
47
|
+
Thredded.moderator_column = :admin
|
|
48
|
+
# The name of the admin flag column on the users table.
|
|
49
|
+
Thredded.admin_column = :admin
|
|
50
|
+
|
|
51
|
+
# Whether posts and topics pending moderation are visible to regular users.
|
|
52
|
+
Thredded.content_visible_while_pending_moderation = true
|
|
53
|
+
|
|
54
|
+
# Whether users that are following a topic are listed on topic page.
|
|
55
|
+
Thredded.show_topic_followers = false
|
|
56
|
+
|
|
57
|
+
# This model can be customized further by overriding a handful of methods on the User model.
|
|
58
|
+
# For more information, see app/models/thredded/user_extender.rb.
|
|
59
|
+
|
|
60
|
+
# ==> Ordering configuration
|
|
61
|
+
|
|
62
|
+
# How to calculate the position of messageboards in a list:
|
|
63
|
+
# :position (default) set the position manually (new messageboards go to the bottom, by creation timestamp)
|
|
64
|
+
# :last_post_at_desc most recent post first
|
|
65
|
+
# :topics_count_desc most topics first
|
|
66
|
+
Thredded.messageboards_order = :position
|
|
67
|
+
|
|
68
|
+
# ==> Email Configuration
|
|
69
|
+
# Email "From:" field will use the following
|
|
70
|
+
# Thredded.email_from = 'no-reply@example.com'
|
|
71
|
+
|
|
72
|
+
# Emails going out will prefix the "Subject:" with the following string
|
|
73
|
+
# Thredded.email_outgoing_prefix = '[My Forum] '
|
|
74
|
+
#
|
|
75
|
+
# The parent mailer for all Thredded mailers
|
|
76
|
+
# Thredded.parent_mailer = 'ActionMailer::Base'
|
|
77
|
+
|
|
78
|
+
# ==> View Configuration
|
|
79
|
+
# Set the layout for rendering the thredded views.
|
|
80
|
+
Thredded.layout = 'thredded/application'
|
|
81
|
+
|
|
82
|
+
# ==> URLs
|
|
83
|
+
# How Thredded generates URL slugs from text.
|
|
84
|
+
|
|
85
|
+
# Default:
|
|
86
|
+
# Thredded.slugifier = ->(input) { input.parameterize }
|
|
87
|
+
|
|
88
|
+
# If your forum is in a language other than English, you might want to use the babosa gem instead
|
|
89
|
+
# Thredded.slugifier = ->(input) { Babosa::Identifier.new(input).normalize.transliterate(:russian).to_s }
|
|
90
|
+
|
|
91
|
+
# ==> Post Content Formatting
|
|
92
|
+
# Customize the way Thredded handles post formatting.
|
|
93
|
+
|
|
94
|
+
# Change the default html-pipeline filters used by thredded.
|
|
95
|
+
# E.g. to replace default emoji filter with your own:
|
|
96
|
+
# Thredded::ContentFormatter.after_markup_filters[
|
|
97
|
+
# Thredded::ContentFormatter.after_markup_filters.index(HTML::Pipeline::EmojiFilter)] = MyEmojiFilter
|
|
98
|
+
|
|
99
|
+
# Change the HTML sanitization settings used by Thredded.
|
|
100
|
+
# See the Sanitize docs for more information on the underlying library: https://github.com/rgrove/sanitize/#readme
|
|
101
|
+
# E.g. to allow a custom element <custom-element>:
|
|
102
|
+
# Thredded::ContentFormatter.whitelist[:elements] += %w(custom-element)
|
|
103
|
+
|
|
104
|
+
# ==> User autocompletion (Private messages and @-mentions)
|
|
105
|
+
# Thredded.autocomplete_min_length = 2 lower to 1 if have 1-letter names -- increase if you want
|
|
106
|
+
|
|
107
|
+
# ==> Error Handling
|
|
108
|
+
# By default Thredded just renders a flash alert on errors such as Topic not found, or Login required.
|
|
109
|
+
# Below is an example of overriding the default behavior on LoginRequired:
|
|
110
|
+
#
|
|
111
|
+
# Rails.application.config.to_prepare do
|
|
112
|
+
# Thredded::ApplicationController.module_eval do
|
|
113
|
+
# rescue_from Thredded::Errors::LoginRequired do |exception|
|
|
114
|
+
# @message = exception.message
|
|
115
|
+
# render template: 'sessions/new', status: :forbidden
|
|
116
|
+
# end
|
|
117
|
+
# end
|
|
118
|
+
# end
|
|
119
|
+
|
|
120
|
+
# ==> View hooks
|
|
121
|
+
#
|
|
122
|
+
# Customize the UI before/after/replacing individual components.
|
|
123
|
+
# See the full list of view hooks and their arguments by running:
|
|
124
|
+
#
|
|
125
|
+
# $ grep view_hooks -R --include '*.html.erb' "$(bundle show thredded)"
|
|
126
|
+
#
|
|
127
|
+
# Rails.application.config.to_prepare do
|
|
128
|
+
# Thredded.view_hooks.post_form.content_text_area.config.before do |form:, **args|
|
|
129
|
+
# # This is called in the Thredded view context, so all Thredded helpers and URLs are accessible here directly.
|
|
130
|
+
# 'hi'
|
|
131
|
+
# end
|
|
132
|
+
# end
|
|
133
|
+
|
|
134
|
+
# ==> Topic following
|
|
135
|
+
#
|
|
136
|
+
# By default, a user will be subscribed to a topic they've created. Uncomment this to not subscribe them:
|
|
137
|
+
#
|
|
138
|
+
# Thredded.auto_follow_when_creating_topic = false
|
|
139
|
+
#
|
|
140
|
+
# By default, a user will be subscribed to (follow) a topic they post in. Uncomment this to not subscribe them:
|
|
141
|
+
#
|
|
142
|
+
# Thredded.auto_follow_when_posting_in_topic = false
|
|
143
|
+
#
|
|
144
|
+
# By default, a user will be subscribed to the topic they get @-mentioned in.
|
|
145
|
+
# Individual users can disable this in the Notification Settings.
|
|
146
|
+
# To change the default for all users, simply change the default value of the `follow_topics_on_mention` column
|
|
147
|
+
# of the `thredded_user_preferences` and `thredded_user_messageboard_preferences` tables.
|
|
148
|
+
|
|
149
|
+
# ==> Notifiers
|
|
150
|
+
#
|
|
151
|
+
# Change how users can choose to be notified, by adding notifiers here, or removing the initializer altogether
|
|
152
|
+
#
|
|
153
|
+
# default:
|
|
154
|
+
# Thredded.notifiers = [Thredded::EmailNotifier.new]
|
|
155
|
+
#
|
|
156
|
+
# none:
|
|
157
|
+
# Thredded.notifiers = []
|
|
158
|
+
#
|
|
159
|
+
# add in (must install separate gem (under development) as well):
|
|
160
|
+
# Thredded.notifiers = [Thredded::EmailNotifier.new, Thredded::PushoverNotifier.new(ENV['PUSHOVER_APP_ID'])]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :thredded do
|
|
4
|
+
namespace :install do
|
|
5
|
+
desc 'Copy emoji to the Rails `public/emoji` directory'
|
|
6
|
+
task :emoji do
|
|
7
|
+
require 'emoji'
|
|
8
|
+
|
|
9
|
+
target = Rails.application.root.join('public')
|
|
10
|
+
STDERR.puts "Copying emoji to #{target}"
|
|
11
|
+
`mkdir -p '#{target}' && cp -Rp '#{Emoji.images_path}/emoji' '#{target}'`
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/thredded.rb
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Backend
|
|
4
|
+
require 'pundit'
|
|
5
|
+
require 'active_record_union'
|
|
6
|
+
require 'db_text_search'
|
|
7
|
+
require 'friendly_id'
|
|
8
|
+
require 'html/pipeline'
|
|
9
|
+
require 'html/pipeline/sanitization_filter'
|
|
10
|
+
require 'rinku'
|
|
11
|
+
require 'kaminari'
|
|
12
|
+
require 'rb-gravatar'
|
|
13
|
+
require 'active_job'
|
|
14
|
+
require 'inline_svg'
|
|
15
|
+
|
|
16
|
+
# Require these explictly to make sure they are not reloaded.
|
|
17
|
+
# This allows for configuring them by accessing class methods in the initializer.
|
|
18
|
+
require 'thredded/formatting_demo_content'
|
|
19
|
+
require 'thredded/html_pipeline/at_mention_filter'
|
|
20
|
+
require 'thredded/html_pipeline/autolink_filter'
|
|
21
|
+
require 'thredded/html_pipeline/kramdown_filter'
|
|
22
|
+
require 'thredded/html_pipeline/onebox_filter'
|
|
23
|
+
require 'thredded/html_pipeline/wrap_iframes_filter'
|
|
24
|
+
|
|
25
|
+
# Asset compilation
|
|
26
|
+
require 'autoprefixer-rails'
|
|
27
|
+
require 'timeago_js'
|
|
28
|
+
require 'sprockets/es6'
|
|
29
|
+
|
|
30
|
+
require 'thredded/version'
|
|
31
|
+
require 'thredded/engine'
|
|
32
|
+
require 'thredded/errors'
|
|
33
|
+
|
|
34
|
+
require 'thredded/view_hooks/config'
|
|
35
|
+
require 'thredded/view_hooks/renderer'
|
|
36
|
+
|
|
37
|
+
# Require these explicitly so that they do not need to be required if used in the initializer:
|
|
38
|
+
require 'thredded/content_formatter'
|
|
39
|
+
require 'thredded/email_transformer'
|
|
40
|
+
require 'thredded/base_notifier'
|
|
41
|
+
|
|
42
|
+
require 'thredded/collection_to_strings_with_cache_renderer'
|
|
43
|
+
|
|
44
|
+
module Thredded
|
|
45
|
+
mattr_accessor \
|
|
46
|
+
:autocomplete_min_length,
|
|
47
|
+
:active_user_threshold,
|
|
48
|
+
:avatar_url,
|
|
49
|
+
:email_from,
|
|
50
|
+
:email_outgoing_prefix,
|
|
51
|
+
:layout,
|
|
52
|
+
:messageboards_order,
|
|
53
|
+
:routes_id_constraint,
|
|
54
|
+
:user_display_name_method,
|
|
55
|
+
:user_name_column,
|
|
56
|
+
:user_path
|
|
57
|
+
|
|
58
|
+
# @return [Symbol] The name of the method used by Thredded controllers and views to fetch the currently signed-in user
|
|
59
|
+
mattr_accessor :current_user_method
|
|
60
|
+
|
|
61
|
+
# @return [Symbol] The name of the moderator flag column on the users table for the default permissions model
|
|
62
|
+
mattr_accessor :moderator_column
|
|
63
|
+
|
|
64
|
+
# @return [Symbol] The name of the admin flag column on the users table for the default permissions model
|
|
65
|
+
mattr_accessor :admin_column
|
|
66
|
+
|
|
67
|
+
# @return [Boolean] Whether posts that are pending moderation are visible to regular users.
|
|
68
|
+
mattr_accessor :content_visible_while_pending_moderation
|
|
69
|
+
|
|
70
|
+
# @return [Array] The notifiers, by default just the EmailNotifier
|
|
71
|
+
mattr_accessor :notifiers
|
|
72
|
+
|
|
73
|
+
# @return [Boolean] Whether users that are following a topic are listed on topic page.
|
|
74
|
+
mattr_accessor :show_topic_followers
|
|
75
|
+
|
|
76
|
+
# @return [Symbol] The name of the method used by Thredded to display users
|
|
77
|
+
mattr_accessor :user_display_name_method
|
|
78
|
+
|
|
79
|
+
# @return [String] The name of the parent mailer class for Thredded mailers.
|
|
80
|
+
mattr_accessor :parent_mailer
|
|
81
|
+
self.parent_mailer = 'ActionMailer::Base'
|
|
82
|
+
|
|
83
|
+
# @return [Proc] The proc that Thredded uses to generate URL slugs from text.
|
|
84
|
+
mattr_accessor :slugifier
|
|
85
|
+
self.slugifier = ->(input) { input.parameterize }
|
|
86
|
+
|
|
87
|
+
# @return [Boolean] Whether the user should get subscribed to a new topic they've created.
|
|
88
|
+
mattr_accessor :auto_follow_when_creating_topic
|
|
89
|
+
self.auto_follow_when_creating_topic = true
|
|
90
|
+
|
|
91
|
+
# @return [Boolean] Whether the user should get subscribed to a topic after posting in it.
|
|
92
|
+
mattr_accessor :auto_follow_when_posting_in_topic
|
|
93
|
+
self.auto_follow_when_posting_in_topic = true
|
|
94
|
+
|
|
95
|
+
# @return [String] The name of the user class
|
|
96
|
+
mattr_reader :user_class_name
|
|
97
|
+
|
|
98
|
+
self.active_user_threshold = 5.minutes
|
|
99
|
+
self.admin_column = :admin
|
|
100
|
+
self.avatar_url = ->(user) { Gravatar.src(user.email, 156, 'mm') }
|
|
101
|
+
self.layout = 'thredded/application'
|
|
102
|
+
self.moderator_column = :admin
|
|
103
|
+
self.user_name_column = :name
|
|
104
|
+
self.content_visible_while_pending_moderation = true
|
|
105
|
+
self.show_topic_followers = false
|
|
106
|
+
self.messageboards_order = :position
|
|
107
|
+
self.autocomplete_min_length = 2
|
|
108
|
+
self.routes_id_constraint = /[1-9]\d*/
|
|
109
|
+
|
|
110
|
+
# @return [Thredded::AllViewHooks] View hooks configuration.
|
|
111
|
+
def self.view_hooks
|
|
112
|
+
instance = Thredded::AllViewHooks.instance
|
|
113
|
+
unless instance
|
|
114
|
+
fail '`Thredded.view_hooks` must be configured in a `Rails.application.config.to_prepare` block!'
|
|
115
|
+
end
|
|
116
|
+
instance
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def self.notifiers
|
|
120
|
+
@@notifiers ||= [Thredded::EmailNotifier.new] # rubocop:disable Style/ClassVars
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def self.notifiers=(notifiers)
|
|
124
|
+
notifiers.each { |notifier| BaseNotifier.validate_notifier(notifier) }
|
|
125
|
+
@@notifiers = notifiers # rubocop:disable Style/ClassVars
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def self.user_display_name_method
|
|
129
|
+
@@user_display_name_method || user_name_column
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @param value [:position, :topics_count_desc, :last_post_at_desc]
|
|
133
|
+
def self.messageboards_order=(value)
|
|
134
|
+
case value
|
|
135
|
+
when :position, :topics_count_desc, :last_post_at_desc
|
|
136
|
+
@@messageboards_order = value # rubocop:disable Style/ClassVars
|
|
137
|
+
else
|
|
138
|
+
fail ArgumentError, "Unexpected value for Thredded.messageboards_order: #{value}"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# @param user_class_name [String]
|
|
143
|
+
def self.user_class=(user_class_name)
|
|
144
|
+
unless user_class_name.is_a?(String)
|
|
145
|
+
fail "Thredded.user_class must be set to a String, got #{user_class_name.inspect}"
|
|
146
|
+
end
|
|
147
|
+
@@user_class_name = user_class_name # rubocop:disable Style/ClassVars
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @return [Class<Thredded::UserExtender>] the user class from the host application.
|
|
151
|
+
def self.user_class
|
|
152
|
+
# This is nil before the initializer is installed.
|
|
153
|
+
return nil if @@user_class_name.nil?
|
|
154
|
+
@@user_class_name.constantize
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @param view_context [Object] context to execute the lambda in.
|
|
158
|
+
# @param user [Thredded.user_class]
|
|
159
|
+
# @return [String] path to the user evaluated in the specified context.
|
|
160
|
+
def self.user_path(view_context, user)
|
|
161
|
+
view_context.instance_exec(user, &@@user_path)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Whether the layout is a thredded layout as opposed to the application layout.
|
|
165
|
+
def self.standalone_layout?
|
|
166
|
+
layout.is_a?(String) && layout.start_with?('thredded/')
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Returns a view for the given posts' scope, applying read permission filters to the scope.
|
|
170
|
+
# Can be used in main_app, e.g. for showing the recent user posts on the profile page.
|
|
171
|
+
#
|
|
172
|
+
# @param scope [ActiveRecord::Relation<Thredded::Post>] the posts scope for which to return the view.
|
|
173
|
+
# @param current_user [Thredded.user_class, nil] the user viewing the posts.
|
|
174
|
+
# @return [PostsPageView]
|
|
175
|
+
def self.posts_page_view(scope:, current_user:)
|
|
176
|
+
current_user ||= Thredded::NullUser.new
|
|
177
|
+
PostsPageView.new(
|
|
178
|
+
current_user,
|
|
179
|
+
Pundit.policy_scope!(current_user, scope)
|
|
180
|
+
.where(messageboard_id: Pundit.policy_scope!(current_user, Thredded::Messageboard.all).pluck(:id))
|
|
181
|
+
.includes(:postable)
|
|
182
|
+
)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @api private
|
|
186
|
+
def self.rails_gte_51?
|
|
187
|
+
@rails_gte_51 = (Rails.gem_version >= Gem::Version.new('5.1.0')) if @rails_gte_51.nil?
|
|
188
|
+
@rails_gte_51
|
|
189
|
+
end
|
|
190
|
+
end
|