diff --git a/Gemfile b/Gemfile index a80f23dbc0f..6c72e48bab4 100644 --- a/Gemfile +++ b/Gemfile @@ -127,6 +127,10 @@ gem 'mini_racer' # TODO: determine why highline is being held back and upgrade to latest gem 'highline', '~> 1.7.0', require: false +# TODO: Upgrading breaks Sidekiq Web +# This is a bit of a hornets nest cause in an ideal world we much prefer +# if Sidekiq reused session and CSRF mitigation with Discourse on the +# _forum_session cookie instead of a rack.session cookie gem 'rack', '2.2.2' gem 'rack-protection' # security @@ -248,5 +252,3 @@ end gem 'webpush', require: false gem 'colored2', require: false gem 'maxminddb' - -gem 'rails_failover', require: false diff --git a/Gemfile.lock b/Gemfile.lock index db4b88d8631..752d48c3c90 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -195,7 +195,7 @@ GEM mini_sql (0.2.5) mini_suffix (0.3.0) ffi (~> 1.9) - minitest (5.14.1) + minitest (5.14.0) mocha (1.11.2) mock_redis (0.23.0) msgpack (1.3.3) @@ -262,7 +262,7 @@ GEM pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (4.0.5) - puma (4.3.5) + puma (4.3.3) nio4r (~> 2.0) r2 (0.2.7) rack (2.2.2) @@ -277,8 +277,6 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - rails_failover (0.2.0) - redis (~> 4) rails_multisite (2.1.2) activerecord (> 5.0, < 7) railties (> 5.0, < 7) @@ -296,7 +294,7 @@ GEM rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) - rbtrace (0.4.13) + rbtrace (0.4.12) ffi (>= 1.0.6) msgpack (>= 0.4.3) optimist (>= 3.0.0) @@ -343,16 +341,13 @@ GEM json-schema (~> 2.2) railties (>= 3.1, < 7.0) rtlit (0.0.5) - rubocop (0.84.0) + rubocop (0.83.0) parallel (~> 1.10) parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) rexml - rubocop-ast (>= 0.0.3) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (0.0.3) - parser (>= 2.7.0.1) rubocop-discourse (2.1.2) rubocop (>= 0.69.0) rubocop-rspec (>= 1.39.0) @@ -514,7 +509,6 @@ DEPENDENCIES rack (= 2.2.2) rack-mini-profiler rack-protection - rails_failover rails_multisite railties (= 6.0.3) rake diff --git a/app/assets/javascripts/admin/models/admin-user.js b/app/assets/javascripts/admin/models/admin-user.js index 9977fa8dd46..71b8078f6ed 100644 --- a/app/assets/javascripts/admin/models/admin-user.js +++ b/app/assets/javascripts/admin/models/admin-user.js @@ -77,6 +77,12 @@ const AdminUser = User.extend({ }); }, + revokeApiKey() { + return ajax(`/admin/users/${this.id}/revoke_api_key`, { + type: "DELETE" + }).then(() => this.set("api_key", null)); + }, + deleteAllPosts() { let deletedPosts = 0; const user = this; diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js index f0860e79f71..34aed775cc5 100644 --- a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js +++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js @@ -1,4 +1,5 @@ import { get } from "@ember/object"; +import { isEmpty } from "@ember/utils"; import DiscourseRoute from "discourse/routes/discourse"; export default DiscourseRoute.extend({ @@ -14,7 +15,7 @@ export default DiscourseRoute.extend({ }, setupController(controller, model) { - if (model.get("isNew")) { + if (model.get("isNew") || isEmpty(model.get("web_hook_event_types"))) { model.set("web_hook_event_types", controller.get("defaultEventTypes")); } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 40f1d275bb4..4445fd79869 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,6 +1,6 @@ //= require_tree ./discourse-common/addon //= require ./polyfills -//= require_tree ./select-kit/addon +//= require_tree ./select-kit/app //= require ./discourse/app/app //= require ./app-boot diff --git a/app/assets/javascripts/discourse-loader.js b/app/assets/javascripts/discourse-loader.js index fc829ae12f0..d11217a985a 100644 --- a/app/assets/javascripts/discourse-loader.js +++ b/app/assets/javascripts/discourse-loader.js @@ -36,6 +36,7 @@ var define, requirejs; default: Ember.Object, get: Ember.get, getProperties: Ember.getProperties, + guidFor: Ember.guidFor, set: Ember.set, setProperties: Ember.setProperties, computed: Ember.computed, diff --git a/app/assets/javascripts/discourse/app/controllers/preferences/interface.js b/app/assets/javascripts/discourse/app/controllers/preferences/interface.js index 2fcc5781c30..1ad85b7d7b1 100644 --- a/app/assets/javascripts/discourse/app/controllers/preferences/interface.js +++ b/app/assets/javascripts/discourse/app/controllers/preferences/interface.js @@ -2,10 +2,13 @@ import I18n from "I18n"; import { inject } from "@ember/controller"; import Controller from "@ember/controller"; import { setDefaultHomepage } from "discourse/lib/utilities"; -import discourseComputed from "discourse-common/utils/decorators"; -import { listThemes, setLocalTheme } from "discourse/lib/theme-selector"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import { + listThemes, + previewTheme, + setLocalTheme +} from "discourse/lib/theme-selector"; import { popupAjaxError } from "discourse/lib/ajax-error"; -import pageReloader from "discourse/helpers/page-reloader"; import { safariHacksDisabled, isiPad, @@ -25,9 +28,6 @@ const TEXT_SIZES = ["smaller", "normal", "larger", "largest"]; const TITLE_COUNT_MODES = ["notifications", "contextual"]; export default Controller.extend({ - currentThemeId: -1, - preferencesController: inject("preferences"), - @discourseComputed("makeThemeDefault") saveAttrNames(makeDefault) { let attrs = [ @@ -51,6 +51,8 @@ export default Controller.extend({ return attrs; }, + preferencesController: inject("preferences"), + @discourseComputed() isiPad() { // TODO: remove this preference checkbox when iOS adoption > 90% @@ -103,14 +105,10 @@ export default Controller.extend({ return themes && themes.length > 1; }, - @discourseComputed("themeId") - themeIdChanged(themeId) { - if (this.currentThemeId === -1) { - this.set("currentThemeId", themeId); - return false; - } else { - return this.currentThemeId !== themeId; - } + @observes("themeId") + themeIdChanged() { + const id = this.themeId; + previewTheme([id]); }, @discourseComputed("model.user_option.theme_ids", "themeId") @@ -191,10 +189,6 @@ export default Controller.extend({ this.disableSafariHacks.toString() ); } - - if (this.themeId !== this.currentThemeId) { - pageReloader.reload(); - } }) .catch(popupAjaxError); }, diff --git a/app/assets/javascripts/discourse/app/controllers/topic.js b/app/assets/javascripts/discourse/app/controllers/topic.js index ba7caf554d1..2c2ebdc7fe6 100644 --- a/app/assets/javascripts/discourse/app/controllers/topic.js +++ b/app/assets/javascripts/discourse/app/controllers/topic.js @@ -185,13 +185,6 @@ export default Controller.extend(bufferedProperty("model"), { ); }, - @discourseComputed("model.category") - minimumRequiredTags(category) { - return category && category.minimum_required_tags > 0 - ? category.minimum_required_tags - : null; - }, - _forceRefreshPostStream() { this.appEvents.trigger("post-stream:refresh", { force: true }); }, diff --git a/app/assets/javascripts/discourse/app/controllers/user.js b/app/assets/javascripts/discourse/app/controllers/user.js index b466f084ed5..cc2db042fbf 100644 --- a/app/assets/javascripts/discourse/app/controllers/user.js +++ b/app/assets/javascripts/discourse/app/controllers/user.js @@ -51,15 +51,13 @@ export default Controller.extend(CanCheckEmails, { hasDeletedPosts: gt("model.number_of_deleted_posts", 0), hasBeenSuspended: gt("model.number_of_suspensions", 0), hasReceivedWarnings: gt("model.warnings_received_count", 0), - hasRejectedPosts: gt("model.number_of_rejected_posts", 0), showStaffCounters: or( "hasGivenFlags", "hasFlaggedPosts", "hasDeletedPosts", "hasBeenSuspended", - "hasReceivedWarnings", - "hasRejectedPosts" + "hasReceivedWarnings" ), showFeaturedTopic: and( diff --git a/app/assets/javascripts/discourse/app/helpers/page-reloader.js b/app/assets/javascripts/discourse/app/helpers/page-reloader.js deleted file mode 100644 index 6429be3a3cc..00000000000 --- a/app/assets/javascripts/discourse/app/helpers/page-reloader.js +++ /dev/null @@ -1,10 +0,0 @@ -import EmberObject from "@ember/object"; -import Ember from "ember"; - -export default EmberObject.create({ - reload: function() { - if (!Ember.testing) { - location.reload(); - } - } -}); diff --git a/app/assets/javascripts/discourse/app/initializers/copy-codeblocks.js b/app/assets/javascripts/discourse/app/initializers/copy-codeblocks.js index f6fcef5e17e..a0b0d509621 100644 --- a/app/assets/javascripts/discourse/app/initializers/copy-codeblocks.js +++ b/app/assets/javascripts/discourse/app/initializers/copy-codeblocks.js @@ -3,7 +3,6 @@ import { cancel, later } from "@ember/runloop"; import { Promise } from "rsvp"; import { iconHTML } from "discourse-common/lib/icon-library"; import I18n from "I18n"; -import { guidFor } from "@ember/object/internals"; // http://github.com/feross/clipboard-copy function clipboardCopy(text) { @@ -91,7 +90,7 @@ export default { const state = button.innerHTML; button.innerHTML = I18n.t("copy_codeblock.copied"); - const commandId = guidFor(button); + const commandId = Ember.guidFor(button); if (_fadeCopyCodeblocksRunners[commandId]) { cancel(_fadeCopyCodeblocksRunners[commandId]); diff --git a/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js b/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js index a2de76d3e9d..a13ccd2219f 100644 --- a/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js +++ b/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js @@ -3,13 +3,6 @@ import showModal from "discourse/lib/show-modal"; import { registerTopicFooterButton } from "discourse/lib/register-topic-footer-button"; import { formattedReminderTime } from "discourse/lib/bookmark"; -const SHARE_PRIORITY = 1000; -const BOOKMARK_PRIORITY = 900; -const ARCHIVE_PRIORITY = 800; -const FLAG_PRIORITY = 700; -const EDIT_MESSAGE_PRIORITY = 600; -const DEFER_PRIORITY = 500; - export default { name: "topic-footer-buttons", @@ -18,12 +11,8 @@ export default { registerTopicFooterButton({ id: "share-and-invite", icon: "link", - priority: SHARE_PRIORITY, - label() { - if (!this.get("topic.isPrivateMessage") || this.site.mobileView) { - return "topic.share.title"; - } - }, + priority: 999, + label: "topic.share.title", title: "topic.share.help", action() { const panels = [ @@ -78,7 +67,7 @@ export default { registerTopicFooterButton({ id: "flag", icon: "flag", - priority: FLAG_PRIORITY, + priority: 998, label: "topic.flag_topic.title", title: "topic.flag_topic.help", action: "showFlagTopic", @@ -104,16 +93,14 @@ export default { } return "bookmark"; }, - priority: BOOKMARK_PRIORITY, + priority: 1000, classNames() { const bookmarked = this.get("topic.bookmarked"); return bookmarked ? ["bookmark", "bookmarked"] : ["bookmark"]; }, label() { - if (!this.get("topic.isPrivateMessage") || this.site.mobileView) { - const bookmarked = this.get("topic.bookmarked"); - return bookmarked ? "bookmarked.clear_bookmarks" : "bookmarked.title"; - } + const bookmarked = this.get("topic.bookmarked"); + return bookmarked ? "bookmarked.clear_bookmarks" : "bookmarked.title"; }, translatedTitle() { const bookmarked = this.get("topic.bookmarked"); @@ -139,7 +126,7 @@ export default { registerTopicFooterButton({ id: "archive", - priority: ARCHIVE_PRIORITY, + priority: 996, icon() { return this.archiveIcon; }, @@ -168,16 +155,13 @@ export default { registerTopicFooterButton({ id: "edit-message", - priority: EDIT_MESSAGE_PRIORITY, + priority: 750, icon: "pencil-alt", label: "topic.edit_message.title", title: "topic.edit_message.help", action: "editFirstPost", classNames: ["edit-message"], dependentKeys: ["editFirstPost", "showEditOnFooter"], - dropdown() { - return this.site.mobileView && this.get("topic.isPrivateMessage"); - }, displayed() { return this.showEditOnFooter; } @@ -186,7 +170,7 @@ export default { registerTopicFooterButton({ id: "defer", icon: "circle", - priority: DEFER_PRIORITY, + priority: 300, label: "topic.defer.title", title: "topic.defer.help", action: "deferTopic", diff --git a/app/assets/javascripts/discourse/app/lib/theme-selector.js b/app/assets/javascripts/discourse/app/lib/theme-selector.js index 48f63c31fbf..9d293fe312c 100644 --- a/app/assets/javascripts/discourse/app/lib/theme-selector.js +++ b/app/assets/javascripts/discourse/app/lib/theme-selector.js @@ -1,4 +1,5 @@ import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; import deprecated from "discourse-common/lib/deprecated"; const keySelector = "meta[name=discourse_theme_ids]"; @@ -78,6 +79,31 @@ export function refreshCSS(node, hash, newHref) { $orig.data("copy", reloaded); } +export function previewTheme(ids = []) { + ids = ids.reject(id => !id); + if (!ids.includes(currentThemeId())) { + Discourse.set("assetVersion", "forceRefresh"); + + ajax(`/themes/assets/${ids.length > 0 ? ids.join("-") : "default"}`).then( + results => { + const elem = _.first($(keySelector)); + if (elem) { + elem.content = ids.join(","); + } + + results.themes.forEach(theme => { + const node = $( + `link[rel=stylesheet][data-target=${theme.target}]` + )[0]; + if (node) { + refreshCSS(node, null, theme.new_href); + } + }); + } + ); + } +} + export function listThemes(site) { let themes = site.get("user_themes"); diff --git a/app/assets/javascripts/discourse/app/models/nav-item.js b/app/assets/javascripts/discourse/app/models/nav-item.js index 955e536e1eb..412cd8ec2e4 100644 --- a/app/assets/javascripts/discourse/app/models/nav-item.js +++ b/app/assets/javascripts/discourse/app/models/nav-item.js @@ -273,17 +273,12 @@ export function addNavItem(item) { NavItem.extraNavItemDescriptors.push(item); } -if (typeof Discourse !== "undefined") { - Object.defineProperty(Discourse, "NavItem", { - get() { - deprecated( - "Import the NavItem class instead of using Discourse.NavItem", - { - since: "2.4.0", - dropFrom: "2.5.0" - } - ); - return NavItem; - } - }); -} +Object.defineProperty(Discourse, "NavItem", { + get() { + deprecated("Import the NavItem class instead of using Discourse.NavItem", { + since: "2.4.0", + dropFrom: "2.5.0" + }); + return NavItem; + } +}); diff --git a/app/assets/javascripts/discourse/app/models/topic-details.js b/app/assets/javascripts/discourse/app/models/topic-details.js index d8d5ea0036f..50449aa0e39 100644 --- a/app/assets/javascripts/discourse/app/models/topic-details.js +++ b/app/assets/javascripts/discourse/app/models/topic-details.js @@ -61,15 +61,12 @@ const TopicDetails = RestModel.extend({ } }, - updateNotifications(level) { - return ajax(`/t/${this.get("topic.id")}/notifications`, { + updateNotifications(v) { + this.set("notification_level", v); + this.set("notifications_reason_id", null); + return ajax("/t/" + this.get("topic.id") + "/notifications", { type: "POST", - data: { notification_level: level } - }).then(() => { - this.setProperties({ - notification_level: level, - notifications_reason_id: null - }); + data: { notification_level: v } }); }, diff --git a/app/assets/javascripts/discourse/app/templates/about.hbs b/app/assets/javascripts/discourse/app/templates/about.hbs index 2659b0ebac4..63cae2c2609 100644 --- a/app/assets/javascripts/discourse/app/templates/about.hbs +++ b/app/assets/javascripts/discourse/app/templates/about.hbs @@ -64,52 +64,50 @@ {{/each}} {{/if}} - {{#if model.can_see_about_stats}} -
-

{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}

+
+

{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 {{i18n "about.stat.last_7_days"}}{{i18n "about.stat.last_30_days"}}{{i18n "about.stat.all_time"}}
{{i18n "about.topic_count"}}{{number model.stats.topics_7_days}}{{number model.stats.topics_30_days}}{{number model.stats.topic_count}}
{{i18n "about.post_count"}}{{number model.stats.posts_7_days}}{{number model.stats.posts_30_days}}{{number model.stats.post_count}}
{{i18n "about.user_count"}}{{number model.stats.users_7_days}}{{number model.stats.users_30_days}}{{number model.stats.user_count}}
{{i18n "about.active_user_count"}}{{number model.stats.active_users_7_days}}{{number model.stats.active_users_30_days}}
{{i18n "about.like_count"}}{{number model.stats.likes_7_days}}{{number model.stats.likes_30_days}}{{number model.stats.like_count}}
-
- {{/if}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 {{i18n "about.stat.last_7_days"}}{{i18n "about.stat.last_30_days"}}{{i18n "about.stat.all_time"}}
{{i18n "about.topic_count"}}{{number model.stats.topics_7_days}}{{number model.stats.topics_30_days}}{{number model.stats.topic_count}}
{{i18n "about.post_count"}}{{number model.stats.posts_7_days}}{{number model.stats.posts_30_days}}{{number model.stats.post_count}}
{{i18n "about.user_count"}}{{number model.stats.users_7_days}}{{number model.stats.users_30_days}}{{number model.stats.user_count}}
{{i18n "about.active_user_count"}}{{number model.stats.active_users_7_days}}{{number model.stats.active_users_30_days}}
{{i18n "about.like_count"}}{{number model.stats.likes_7_days}}{{number model.stats.likes_30_days}}{{number model.stats.like_count}}
+
{{#if contactInfo}}
diff --git a/app/assets/javascripts/discourse/app/templates/components/d-navigation.hbs b/app/assets/javascripts/discourse/app/templates/components/d-navigation.hbs index 2ac52d5f71b..e9e0b9a34f1 100644 --- a/app/assets/javascripts/discourse/app/templates/components/d-navigation.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/d-navigation.hbs @@ -3,9 +3,6 @@ {{#if showCategoryAdmin}} {{categories-admin-dropdown onChange=(action "selectCategoryAdminDropdownAction") - options=(hash - triggerOnChangeOnTab=false - ) }} {{/if}} diff --git a/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs b/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs index aa5b44a7163..007ec9c19d2 100644 --- a/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs @@ -50,9 +50,9 @@ args=(hash topic=topic) tagName="" connectorTagName="span"}} - -{{pinned-button pinned=topic.pinned topic=topic}} + {{pinned-button pinned=topic.pinned topic=topic}} + {{#if showNotificationsButton}} {{topic-notifications-button diff --git a/app/assets/javascripts/discourse/app/templates/preferences/interface.hbs b/app/assets/javascripts/discourse/app/templates/preferences/interface.hbs index 4f1f13c6147..45607c8cb75 100644 --- a/app/assets/javascripts/discourse/app/templates/preferences/interface.hbs +++ b/app/assets/javascripts/discourse/app/templates/preferences/interface.hbs @@ -5,11 +5,9 @@ {{combo-box content=userSelectableThemes value=themeId + onChange=(action (mut themeId)) }} - {{#if themeIdChanged}} -

{{i18n "user.save_to_change_theme" save_text=(i18n "save") }}

- {{/if}} {{#if showThemeSetDefault}}
{{preference-checkbox labelKey="user.theme_default_on_all_devices" checked=makeThemeDefault}} diff --git a/app/assets/javascripts/discourse/app/templates/topic.hbs b/app/assets/javascripts/discourse/app/templates/topic.hbs index d5e22f54379..488970c10e8 100644 --- a/app/assets/javascripts/discourse/app/templates/topic.hbs +++ b/app/assets/javascripts/discourse/app/templates/topic.hbs @@ -36,7 +36,6 @@ options=(hash filterable=true categoryId=buffered.category_id - minimum=minimumRequiredTags ) }} {{/if}} diff --git a/app/assets/javascripts/discourse/app/widgets/header.js b/app/assets/javascripts/discourse/app/widgets/header.js index 8e27a15a036..ca4d73c9256 100644 --- a/app/assets/javascripts/discourse/app/widgets/header.js +++ b/app/assets/javascripts/discourse/app/widgets/header.js @@ -125,7 +125,6 @@ createWidget( { attributes: { href: attrs.user.get("path"), - title: attrs.user.get("name"), "data-auto-route": true } }, diff --git a/app/assets/javascripts/select-kit/addon/.gitkeep b/app/assets/javascripts/select-kit/addon/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/app/assets/javascripts/select-kit/addon/templates/components/pinned-button.hbs b/app/assets/javascripts/select-kit/addon/templates/components/pinned-button.hbs deleted file mode 100644 index 91bfe147ff6..00000000000 --- a/app/assets/javascripts/select-kit/addon/templates/components/pinned-button.hbs +++ /dev/null @@ -1,4 +0,0 @@ -

- {{pinned-options value=pinned topic=topic}} - {{html-safe reasonText}} -

diff --git a/app/assets/javascripts/select-kit/addon/templates/components/topic-notifications-button.hbs b/app/assets/javascripts/select-kit/addon/templates/components/topic-notifications-button.hbs deleted file mode 100644 index f21111ebbd5..00000000000 --- a/app/assets/javascripts/select-kit/addon/templates/components/topic-notifications-button.hbs +++ /dev/null @@ -1,30 +0,0 @@ -{{#if appendReason}} -

- {{topic-notifications-options - value=notificationLevel - topic=topic - onChange=(action "changeTopicNotificationLevel") - options=(hash - icon=icon - showFullTitle=showFullTitle - placement=placement - preventsClickPropagation=true - showCaret=showCaret - ) - }} - {{html-safe topic.details.notificationReasonText}} -

-{{else}} - {{topic-notifications-options - value=notificationLevel - topic=topic - onChange=(action "changeTopicNotificationLevel") - options=(hash - icon=icon - showFullTitle=showFullTitle - placement=placement - preventsClickPropagation=true - showCaret=showCaret - ) - }} -{{/if}} diff --git a/app/assets/javascripts/select-kit/addon/components/admin-group-selector.js b/app/assets/javascripts/select-kit/app/components/admin-group-selector.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/admin-group-selector.js rename to app/assets/javascripts/select-kit/app/components/admin-group-selector.js diff --git a/app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js b/app/assets/javascripts/select-kit/app/components/categories-admin-dropdown.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js rename to app/assets/javascripts/select-kit/app/components/categories-admin-dropdown.js diff --git a/app/assets/javascripts/select-kit/addon/components/category-chooser.js b/app/assets/javascripts/select-kit/app/components/category-chooser.js similarity index 99% rename from app/assets/javascripts/select-kit/addon/components/category-chooser.js rename to app/assets/javascripts/select-kit/app/components/category-chooser.js index 72d0167ac09..f36e8be2d32 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-chooser.js +++ b/app/assets/javascripts/select-kit/app/components/category-chooser.js @@ -67,7 +67,6 @@ export default ComboBoxComponent.extend({ search(filter) { if (filter) { - filter = filter.toLowerCase(); return this.content.filter(item => { const category = Category.findById(this.getValue(item)); const categoryName = this.getName(item); diff --git a/app/assets/javascripts/select-kit/addon/components/category-drop.js b/app/assets/javascripts/select-kit/app/components/category-drop.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/category-drop.js rename to app/assets/javascripts/select-kit/app/components/category-drop.js diff --git a/app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js b/app/assets/javascripts/select-kit/app/components/category-drop/category-drop-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js rename to app/assets/javascripts/select-kit/app/components/category-drop/category-drop-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/category-notifications-button.js b/app/assets/javascripts/select-kit/app/components/category-notifications-button.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/category-notifications-button.js rename to app/assets/javascripts/select-kit/app/components/category-notifications-button.js diff --git a/app/assets/javascripts/select-kit/addon/components/category-row.js b/app/assets/javascripts/select-kit/app/components/category-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/category-row.js rename to app/assets/javascripts/select-kit/app/components/category-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/category-selector.js b/app/assets/javascripts/select-kit/app/components/category-selector.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/category-selector.js rename to app/assets/javascripts/select-kit/app/components/category-selector.js diff --git a/app/assets/javascripts/select-kit/addon/components/color-palettes.js b/app/assets/javascripts/select-kit/app/components/color-palettes.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/color-palettes.js rename to app/assets/javascripts/select-kit/app/components/color-palettes.js diff --git a/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js b/app/assets/javascripts/select-kit/app/components/color-palettes/color-palettes-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js rename to app/assets/javascripts/select-kit/app/components/color-palettes/color-palettes-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/combo-box.js b/app/assets/javascripts/select-kit/app/components/combo-box.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/combo-box.js rename to app/assets/javascripts/select-kit/app/components/combo-box.js diff --git a/app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js b/app/assets/javascripts/select-kit/app/components/combo-box/combo-box-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js rename to app/assets/javascripts/select-kit/app/components/combo-box/combo-box-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/composer-actions.js b/app/assets/javascripts/select-kit/app/components/composer-actions.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/composer-actions.js rename to app/assets/javascripts/select-kit/app/components/composer-actions.js diff --git a/app/assets/javascripts/select-kit/addon/components/create-color-row.js b/app/assets/javascripts/select-kit/app/components/create-color-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/create-color-row.js rename to app/assets/javascripts/select-kit/app/components/create-color-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js b/app/assets/javascripts/select-kit/app/components/dropdown-select-box.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js rename to app/assets/javascripts/select-kit/app/components/dropdown-select-box.js diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js b/app/assets/javascripts/select-kit/app/components/dropdown-select-box/dropdown-select-box-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js rename to app/assets/javascripts/select-kit/app/components/dropdown-select-box/dropdown-select-box-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js b/app/assets/javascripts/select-kit/app/components/dropdown-select-box/dropdown-select-box-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js rename to app/assets/javascripts/select-kit/app/components/dropdown-select-box/dropdown-select-box-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js b/app/assets/javascripts/select-kit/app/components/future-date-input-selector.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js rename to app/assets/javascripts/select-kit/app/components/future-date-input-selector.js diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js b/app/assets/javascripts/select-kit/app/components/future-date-input-selector/future-date-input-selector-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js rename to app/assets/javascripts/select-kit/app/components/future-date-input-selector/future-date-input-selector-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js b/app/assets/javascripts/select-kit/app/components/future-date-input-selector/future-date-input-selector-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js rename to app/assets/javascripts/select-kit/app/components/future-date-input-selector/future-date-input-selector-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/mixin.js b/app/assets/javascripts/select-kit/app/components/future-date-input-selector/mixin.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/future-date-input-selector/mixin.js rename to app/assets/javascripts/select-kit/app/components/future-date-input-selector/mixin.js diff --git a/app/assets/javascripts/select-kit/addon/components/group-dropdown.js b/app/assets/javascripts/select-kit/app/components/group-dropdown.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/group-dropdown.js rename to app/assets/javascripts/select-kit/app/components/group-dropdown.js diff --git a/app/assets/javascripts/select-kit/addon/components/group-members-dropdown.js b/app/assets/javascripts/select-kit/app/components/group-members-dropdown.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/group-members-dropdown.js rename to app/assets/javascripts/select-kit/app/components/group-members-dropdown.js diff --git a/app/assets/javascripts/select-kit/addon/components/group-notifications-button.js b/app/assets/javascripts/select-kit/app/components/group-notifications-button.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/group-notifications-button.js rename to app/assets/javascripts/select-kit/app/components/group-notifications-button.js diff --git a/app/assets/javascripts/select-kit/addon/components/icon-picker.js b/app/assets/javascripts/select-kit/app/components/icon-picker.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/icon-picker.js rename to app/assets/javascripts/select-kit/app/components/icon-picker.js diff --git a/app/assets/javascripts/select-kit/addon/components/list-setting.js b/app/assets/javascripts/select-kit/app/components/list-setting.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/list-setting.js rename to app/assets/javascripts/select-kit/app/components/list-setting.js diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js b/app/assets/javascripts/select-kit/app/components/mini-tag-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js rename to app/assets/javascripts/select-kit/app/components/mini-tag-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/mini-tag-chooser-header.js b/app/assets/javascripts/select-kit/app/components/mini-tag-chooser/mini-tag-chooser-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/mini-tag-chooser-header.js rename to app/assets/javascripts/select-kit/app/components/mini-tag-chooser/mini-tag-chooser-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js b/app/assets/javascripts/select-kit/app/components/mini-tag-chooser/selected-collection.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js rename to app/assets/javascripts/select-kit/app/components/mini-tag-chooser/selected-collection.js diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select.js b/app/assets/javascripts/select-kit/app/components/multi-select.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/multi-select.js rename to app/assets/javascripts/select-kit/app/components/multi-select.js diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js b/app/assets/javascripts/select-kit/app/components/multi-select/multi-select-filter.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js rename to app/assets/javascripts/select-kit/app/components/multi-select/multi-select-filter.js diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js b/app/assets/javascripts/select-kit/app/components/multi-select/multi-select-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js rename to app/assets/javascripts/select-kit/app/components/multi-select/multi-select-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js b/app/assets/javascripts/select-kit/app/components/multi-select/selected-category.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js rename to app/assets/javascripts/select-kit/app/components/multi-select/selected-category.js diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js b/app/assets/javascripts/select-kit/app/components/multi-select/selected-color.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js rename to app/assets/javascripts/select-kit/app/components/multi-select/selected-color.js diff --git a/app/assets/javascripts/select-kit/addon/components/none-category-row.js b/app/assets/javascripts/select-kit/app/components/none-category-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/none-category-row.js rename to app/assets/javascripts/select-kit/app/components/none-category-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-button.js b/app/assets/javascripts/select-kit/app/components/notifications-button.js similarity index 96% rename from app/assets/javascripts/select-kit/addon/components/notifications-button.js rename to app/assets/javascripts/select-kit/app/components/notifications-button.js index 32dc2ad7ba1..f5423b9e64a 100644 --- a/app/assets/javascripts/select-kit/addon/components/notifications-button.js +++ b/app/assets/javascripts/select-kit/app/components/notifications-button.js @@ -13,7 +13,8 @@ export default DropdownSelectBoxComponent.extend({ autoFilterable: false, filterable: false, i18nPrefix: "", - i18nPostfix: "" + i18nPostfix: "", + showCaret: true }, modifyComponentForRow() { diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js b/app/assets/javascripts/select-kit/app/components/notifications-button/notifications-button-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js rename to app/assets/javascripts/select-kit/app/components/notifications-button/notifications-button-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-filter.js b/app/assets/javascripts/select-kit/app/components/notifications-filter.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/notifications-filter.js rename to app/assets/javascripts/select-kit/app/components/notifications-filter.js diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js b/app/assets/javascripts/select-kit/app/components/notifications-filter/notifications-filter-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js rename to app/assets/javascripts/select-kit/app/components/notifications-filter/notifications-filter-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser.js b/app/assets/javascripts/select-kit/app/components/period-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/period-chooser.js rename to app/assets/javascripts/select-kit/app/components/period-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js b/app/assets/javascripts/select-kit/app/components/period-chooser/period-chooser-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js rename to app/assets/javascripts/select-kit/app/components/period-chooser/period-chooser-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js b/app/assets/javascripts/select-kit/app/components/period-chooser/period-chooser-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js rename to app/assets/javascripts/select-kit/app/components/period-chooser/period-chooser-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/pinned-button.js b/app/assets/javascripts/select-kit/app/components/pinned-button.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/pinned-button.js rename to app/assets/javascripts/select-kit/app/components/pinned-button.js diff --git a/app/assets/javascripts/select-kit/addon/components/pinned-options.js b/app/assets/javascripts/select-kit/app/components/pinned-options.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/pinned-options.js rename to app/assets/javascripts/select-kit/app/components/pinned-options.js diff --git a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js b/app/assets/javascripts/select-kit/app/components/search-advanced-category-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js rename to app/assets/javascripts/select-kit/app/components/search-advanced-category-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit.js b/app/assets/javascripts/select-kit/app/components/select-kit.js similarity index 99% rename from app/assets/javascripts/select-kit/addon/components/select-kit.js rename to app/assets/javascripts/select-kit/app/components/select-kit.js index 02acfb5a2e1..f2fbbbf1c2b 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit.js +++ b/app/assets/javascripts/select-kit/app/components/select-kit.js @@ -1,6 +1,5 @@ import I18n from "I18n"; -import EmberObject, { computed, get } from "@ember/object"; -import { guidFor } from "@ember/object/internals"; +import EmberObject, { computed, get, guidFor } from "@ember/object"; import Component from "@ember/component"; import deprecated from "discourse-common/lib/deprecated"; import { makeArray } from "discourse-common/lib/helpers"; @@ -272,8 +271,7 @@ export default Component.extend( selectedNameComponent: "selected-name", castInteger: false, preventsClickPropagation: false, - focusAfterOnChange: true, - triggerOnChangeOnTab: true + focusAfterOnChange: true }, autoFilterable: computed("content.[]", "selectKit.filter", function() { diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.js b/app/assets/javascripts/select-kit/app/components/select-kit/errors-collection.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.js rename to app/assets/javascripts/select-kit/app/components/select-kit/errors-collection.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-body.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-body.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-collection.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-collection.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-create-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-create-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-filter.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-filter.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-header.js similarity index 97% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-header.js index 5697826f59f..785b2a47022 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js +++ b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-header.js @@ -140,11 +140,7 @@ export default Component.extend(UtilsMixin, { this._focusFilterInput(); } else if (event.keyCode === 9) { // Tab - if ( - this.selectKit.highlighted && - this.selectKit.isExpanded && - this.selectKit.options.triggerOnChangeOnTab - ) { + if (this.selectKit.highlighted && this.selectKit.isExpanded) { this.selectKit.select( this.getValue(this.selectKit.highlighted), this.selectKit.highlighted diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-none-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-none-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js b/app/assets/javascripts/select-kit/app/components/select-kit/select-kit-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js rename to app/assets/javascripts/select-kit/app/components/select-kit/select-kit-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js b/app/assets/javascripts/select-kit/app/components/select-kit/single-select-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js rename to app/assets/javascripts/select-kit/app/components/select-kit/single-select-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/selected-color.js b/app/assets/javascripts/select-kit/app/components/selected-color.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/selected-color.js rename to app/assets/javascripts/select-kit/app/components/selected-color.js diff --git a/app/assets/javascripts/select-kit/addon/components/selected-name.js b/app/assets/javascripts/select-kit/app/components/selected-name.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/selected-name.js rename to app/assets/javascripts/select-kit/app/components/selected-name.js diff --git a/app/assets/javascripts/select-kit/addon/components/single-select.js b/app/assets/javascripts/select-kit/app/components/single-select.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/single-select.js rename to app/assets/javascripts/select-kit/app/components/single-select.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js b/app/assets/javascripts/select-kit/app/components/tag-chooser-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js rename to app/assets/javascripts/select-kit/app/components/tag-chooser-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-chooser.js b/app/assets/javascripts/select-kit/app/components/tag-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-chooser.js rename to app/assets/javascripts/select-kit/app/components/tag-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop.js b/app/assets/javascripts/select-kit/app/components/tag-drop.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-drop.js rename to app/assets/javascripts/select-kit/app/components/tag-drop.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js b/app/assets/javascripts/select-kit/app/components/tag-drop/tag-drop-header.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js rename to app/assets/javascripts/select-kit/app/components/tag-drop/tag-drop-header.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js b/app/assets/javascripts/select-kit/app/components/tag-group-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js rename to app/assets/javascripts/select-kit/app/components/tag-group-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js b/app/assets/javascripts/select-kit/app/components/tag-notifications-button.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js rename to app/assets/javascripts/select-kit/app/components/tag-notifications-button.js diff --git a/app/assets/javascripts/select-kit/addon/components/tag-row.js b/app/assets/javascripts/select-kit/app/components/tag-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/tag-row.js rename to app/assets/javascripts/select-kit/app/components/tag-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/timezone-input.js b/app/assets/javascripts/select-kit/app/components/timezone-input.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/timezone-input.js rename to app/assets/javascripts/select-kit/app/components/timezone-input.js diff --git a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js b/app/assets/javascripts/select-kit/app/components/toolbar-popup-menu-options.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js rename to app/assets/javascripts/select-kit/app/components/toolbar-popup-menu-options.js diff --git a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js b/app/assets/javascripts/select-kit/app/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js rename to app/assets/javascripts/select-kit/app/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js diff --git a/app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js b/app/assets/javascripts/select-kit/app/components/topic-footer-mobile-dropdown.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js rename to app/assets/javascripts/select-kit/app/components/topic-footer-mobile-dropdown.js diff --git a/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js b/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js similarity index 55% rename from app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js rename to app/assets/javascripts/select-kit/app/components/topic-notifications-button.js index d9c09001823..58329393e7c 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js +++ b/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js @@ -1,28 +1,20 @@ import Component from "@ember/component"; -import { action, computed } from "@ember/object"; +import { action } from "@ember/object"; export default Component.extend({ layoutName: "select-kit/templates/components/topic-notifications-button", classNames: ["topic-notifications-button"], - classNameBindings: ["isLoading"], appendReason: true, showFullTitle: true, placement: "bottom-start", notificationLevel: null, topic: null, showCaret: true, - isLoading: false, - icon: computed("isLoading", function() { - return this.isLoading ? "spinner" : null; - }), @action changeTopicNotificationLevel(levelId) { if (levelId !== this.notificationLevel) { - this.set("isLoading", true); - this.topic.details - .updateNotifications(levelId) - .finally(() => this.set("isLoading", false)); + this.topic.details.updateNotifications(levelId); } } }); diff --git a/app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js b/app/assets/javascripts/select-kit/app/components/topic-notifications-options.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js rename to app/assets/javascripts/select-kit/app/components/topic-notifications-options.js diff --git a/app/assets/javascripts/select-kit/addon/components/user-chooser.js b/app/assets/javascripts/select-kit/app/components/user-chooser.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/user-chooser.js rename to app/assets/javascripts/select-kit/app/components/user-chooser.js diff --git a/app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js b/app/assets/javascripts/select-kit/app/components/user-chooser/user-row.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js rename to app/assets/javascripts/select-kit/app/components/user-chooser/user-row.js diff --git a/app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js b/app/assets/javascripts/select-kit/app/components/user-notifications-dropdown.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js rename to app/assets/javascripts/select-kit/app/components/user-notifications-dropdown.js diff --git a/app/assets/javascripts/select-kit/addon/mixins/plugin-api.js b/app/assets/javascripts/select-kit/app/mixins/plugin-api.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/mixins/plugin-api.js rename to app/assets/javascripts/select-kit/app/mixins/plugin-api.js diff --git a/app/assets/javascripts/select-kit/addon/mixins/tags.js b/app/assets/javascripts/select-kit/app/mixins/tags.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/mixins/tags.js rename to app/assets/javascripts/select-kit/app/mixins/tags.js diff --git a/app/assets/javascripts/select-kit/addon/mixins/utils.js b/app/assets/javascripts/select-kit/app/mixins/utils.js similarity index 100% rename from app/assets/javascripts/select-kit/addon/mixins/utils.js rename to app/assets/javascripts/select-kit/app/mixins/utils.js diff --git a/app/assets/javascripts/select-kit/addon/templates/components/category-drop/category-drop-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/category-drop/category-drop-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/category-drop/category-drop-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/category-drop/category-drop-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/category-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/category-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/category-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/category-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/color-palettes/color-palettes-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/color-palettes/color-palettes-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/color-palettes/color-palettes-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/color-palettes/color-palettes-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/combo-box/combo-box-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/combo-box/combo-box-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/combo-box/combo-box-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/combo-box/combo-box-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/create-color-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/create-color-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/create-color-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/create-color-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/dropdown-select-box/dropdown-select-box-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/dropdown-select-box/dropdown-select-box-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/dropdown-select-box/dropdown-select-box-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/dropdown-select-box/dropdown-select-box-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/dropdown-select-box/dropdown-select-box-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/dropdown-select-box/dropdown-select-box-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/dropdown-select-box/dropdown-select-box-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/dropdown-select-box/dropdown-select-box-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/future-date-input-selector/future-date-input-selector-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/future-date-input-selector/future-date-input-selector-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/future-date-input-selector/future-date-input-selector-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/future-date-input-selector/future-date-input-selector-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/future-date-input-selector/future-date-input-selector-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/future-date-input-selector/future-date-input-selector-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/future-date-input-selector/future-date-input-selector-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/future-date-input-selector/future-date-input-selector-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/mini-tag-chooser/mini-tag-chooser-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/mini-tag-chooser/mini-tag-chooser-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/mini-tag-chooser/mini-tag-chooser-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/mini-tag-chooser/mini-tag-chooser-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/mini-tag-chooser/selected-collection.hbs b/app/assets/javascripts/select-kit/app/templates/components/mini-tag-chooser/selected-collection.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/mini-tag-chooser/selected-collection.hbs rename to app/assets/javascripts/select-kit/app/templates/components/mini-tag-chooser/selected-collection.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/multi-select.hbs b/app/assets/javascripts/select-kit/app/templates/components/multi-select.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/multi-select.hbs rename to app/assets/javascripts/select-kit/app/templates/components/multi-select.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/multi-select/multi-select-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/multi-select/multi-select-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/multi-select/multi-select-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/multi-select/multi-select-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/multi-select/selected-category.hbs b/app/assets/javascripts/select-kit/app/templates/components/multi-select/selected-category.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/multi-select/selected-category.hbs rename to app/assets/javascripts/select-kit/app/templates/components/multi-select/selected-category.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/notifications-filter/notifications-filter-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/notifications-filter/notifications-filter-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/notifications-filter/notifications-filter-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/notifications-filter/notifications-filter-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/period-chooser/period-chooser-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/period-chooser/period-chooser-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/period-chooser/period-chooser-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/period-chooser/period-chooser-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/period-chooser/period-chooser-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/period-chooser/period-chooser-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/period-chooser/period-chooser-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/period-chooser/period-chooser-row.hbs diff --git a/app/assets/javascripts/select-kit/app/templates/components/pinned-button.hbs b/app/assets/javascripts/select-kit/app/templates/components/pinned-button.hbs new file mode 100644 index 00000000000..f54bdb6b5fe --- /dev/null +++ b/app/assets/javascripts/select-kit/app/templates/components/pinned-button.hbs @@ -0,0 +1,5 @@ +{{pinned-options value=pinned topic=topic}} + +

+ {{html-safe reasonText}} +

diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/errors-collection.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/errors-collection.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/errors-collection.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/errors-collection.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-body.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-body.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-body.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-body.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-collection.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-collection.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-collection.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-collection.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-filter.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-filter.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/select-kit-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/single-select-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/select-kit/single-select-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/select-kit/single-select-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/select-kit/single-select-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/selected-name.hbs b/app/assets/javascripts/select-kit/app/templates/components/selected-name.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/selected-name.hbs rename to app/assets/javascripts/select-kit/app/templates/components/selected-name.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/single-select.hbs b/app/assets/javascripts/select-kit/app/templates/components/single-select.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/single-select.hbs rename to app/assets/javascripts/select-kit/app/templates/components/single-select.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/tag-chooser-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/tag-chooser-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/tag-chooser-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/tag-chooser-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/tag-drop/tag-drop-header.hbs b/app/assets/javascripts/select-kit/app/templates/components/tag-drop/tag-drop-header.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/tag-drop/tag-drop-header.hbs rename to app/assets/javascripts/select-kit/app/templates/components/tag-drop/tag-drop-header.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/tag-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/tag-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/tag-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/tag-row.hbs diff --git a/app/assets/javascripts/select-kit/addon/templates/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.hbs b/app/assets/javascripts/select-kit/app/templates/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.hbs rename to app/assets/javascripts/select-kit/app/templates/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.hbs diff --git a/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs b/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs new file mode 100644 index 00000000000..50dd20e56eb --- /dev/null +++ b/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs @@ -0,0 +1,17 @@ +{{topic-notifications-options + value=notificationLevel + topic=topic + onChange=(action "changeTopicNotificationLevel") + options=(hash + showFullTitle=showFullTitle + placement=placement + preventsClickPropagation=true + showCaret=showCaret + ) +}} + +{{#if appendReason}} +

+ {{html-safe topic.details.notificationReasonText}} +

+{{/if}} diff --git a/app/assets/javascripts/select-kit/addon/templates/components/user-chooser/user-row.hbs b/app/assets/javascripts/select-kit/app/templates/components/user-chooser/user-row.hbs similarity index 100% rename from app/assets/javascripts/select-kit/addon/templates/components/user-chooser/user-row.hbs rename to app/assets/javascripts/select-kit/app/templates/components/user-chooser/user-row.hbs diff --git a/app/assets/javascripts/wizard-application.js b/app/assets/javascripts/wizard-application.js index 4e2a7adc072..b8e8797f0c6 100644 --- a/app/assets/javascripts/wizard-application.js +++ b/app/assets/javascripts/wizard-application.js @@ -1,6 +1,6 @@ //= require_tree ./discourse-common/addon //= require i18n-patches -//= require_tree ./select-kit/addon +//= require_tree ./select-kit/app //= require wizard/router //= require wizard/wizard //= require_tree ./wizard/templates diff --git a/app/assets/stylesheets/common/base/_topic-list.scss b/app/assets/stylesheets/common/base/_topic-list.scss index a80e54c4fda..aa51fccce15 100644 --- a/app/assets/stylesheets/common/base/_topic-list.scss +++ b/app/assets/stylesheets/common/base/_topic-list.scss @@ -53,6 +53,7 @@ color: $primary-medium; } span.badge-category { + font-weight: normal; color: $primary-medium; } a.discourse-tag { diff --git a/app/assets/stylesheets/common/base/alert.scss b/app/assets/stylesheets/common/base/alert.scss index 05a29029059..d729cdc7423 100644 --- a/app/assets/stylesheets/common/base/alert.scss +++ b/app/assets/stylesheets/common/base/alert.scss @@ -3,7 +3,6 @@ background-color: $danger-low; color: $primary; position: relative; - margin-bottom: 1em; .close { font-size: $font-up-3; diff --git a/app/assets/stylesheets/common/base/crawler_layout.scss b/app/assets/stylesheets/common/base/crawler_layout.scss index bff0addac1a..c279aceff4c 100644 --- a/app/assets/stylesheets/common/base/crawler_layout.scss +++ b/app/assets/stylesheets/common/base/crawler_layout.scss @@ -27,36 +27,6 @@ body.crawler { .topic-list { margin-bottom: 1em; - @media (max-width: 850px) { - td { - word-break: break-all; - &.posters { - a:not(:last-of-type) { - display: none; - } - a:last-of-type { - display: block; - } - } - } - - td, - th { - &.views { - display: none; - } - } - - .link-top-line { - a.title { - padding: 0; - } - } - - .link-bottom-line { - margin-top: 0.25em; - } - } } footer { diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss index 48c361c1647..6e465bbc6b6 100644 --- a/app/assets/stylesheets/common/base/topic-post.scss +++ b/app/assets/stylesheets/common/base/topic-post.scss @@ -1005,51 +1005,10 @@ a.mention-group { } #topic-footer-buttons { - padding: 0.5em 0; - - .topic-footer-main-buttons { - margin: 0 0 -0.5em 0; - display: flex; - flex-wrap: wrap; - - > .btn { - margin: 0 0.5em 0.5em 0; - display: inline-flex; - align-items: center; - - .d-button-label { - display: flex; - flex: 1 0 auto; - align-items: center; - } - } - - .topic-admin-menu-button-container { - display: inline-flex; - } - - .topic-admin-menu-button-container > span:not(:empty) { - margin: 0 0.5em 0.5em 0; - } - } - - .pinned-button:not(.is-hidden) + .topic-notifications-button { - margin-top: 0; - } - - .pinned-button, - .topic-notifications-button { - margin: 1em 0; - - .reason { - color: $primary-high; - display: inline-flex; - margin: 0; - align-items: center; - - .text { - margin-left: 0.5em; - } - } + .reason { + color: $primary-high; + display: inline; + margin: 0 0 0 8px; + line-height: $line-height-medium; } } diff --git a/app/assets/stylesheets/common/base/user.scss b/app/assets/stylesheets/common/base/user.scss index 4d5e9f42886..587af3c3539 100644 --- a/app/assets/stylesheets/common/base/user.scss +++ b/app/assets/stylesheets/common/base/user.scss @@ -653,9 +653,6 @@ padding: 5px 0; font-weight: bold; } - .save-theme-alert { - font-size: $font-down-1; - } } .paginated-topics-list { diff --git a/app/assets/stylesheets/common/components/badges.scss b/app/assets/stylesheets/common/components/badges.scss index 20ed535931d..3881ee7b70f 100644 --- a/app/assets/stylesheets/common/components/badges.scss +++ b/app/assets/stylesheets/common/components/badges.scss @@ -17,6 +17,7 @@ .badge-wrapper { font-size: $font-down-1; + font-weight: bold; white-space: nowrap; position: relative; display: inline-flex; diff --git a/app/assets/stylesheets/common/select-kit/category-row.scss b/app/assets/stylesheets/common/select-kit/category-row.scss index df43c956035..2bbe33c96ea 100644 --- a/app/assets/stylesheets/common/select-kit/category-row.scss +++ b/app/assets/stylesheets/common/select-kit/category-row.scss @@ -9,9 +9,6 @@ -ms-flex: 1 1 auto; flex: 1 1 auto; } - .category-desc p { - margin: 0; - } .category-status { .badge-wrapper.box { margin-bottom: 1px; diff --git a/app/assets/stylesheets/common/select-kit/pinned-button.scss b/app/assets/stylesheets/common/select-kit/pinned-button.scss index 3e51092ae39..f080b8a016c 100644 --- a/app/assets/stylesheets/common/select-kit/pinned-button.scss +++ b/app/assets/stylesheets/common/select-kit/pinned-button.scss @@ -1,7 +1,28 @@ #topic-footer-buttons { .pinned-button { + min-width: auto; + margin: 1em 0; + &.is-hidden { display: none; } + + .btn { + margin: 0; + } + + .reason { + display: inline; + line-height: $line-height-medium; + } + } +} + +.pinned-button { + margin: 0; + min-width: auto; + + .pinned-options { + display: inline; } } diff --git a/app/assets/stylesheets/common/select-kit/select-kit.scss b/app/assets/stylesheets/common/select-kit/select-kit.scss index a9769b59710..130bad52f80 100644 --- a/app/assets/stylesheets/common/select-kit/select-kit.scss +++ b/app/assets/stylesheets/common/select-kit/select-kit.scss @@ -63,11 +63,6 @@ flex-direction: row; min-height: 30px; - .d-icon-spinner { - -webkit-animation: rotate-forever 1s infinite linear; - animation: rotate-forever 1s infinite linear; - } - .selected-name { text-align: left; flex: 0 1 auto; diff --git a/app/assets/stylesheets/common/select-kit/topic-notifications-button.scss b/app/assets/stylesheets/common/select-kit/topic-notifications-button.scss index b3808031a1d..1e7c7972054 100644 --- a/app/assets/stylesheets/common/select-kit/topic-notifications-button.scss +++ b/app/assets/stylesheets/common/select-kit/topic-notifications-button.scss @@ -1,18 +1,27 @@ -.topic-notifications-button { - &.is-loading { - pointer-events: none; - user-select: none; +#topic-footer-buttons { + .topic-notifications-button { + min-width: auto; + margin: 1em 0; - .d-icon-spinner { + .btn { margin: 0; } - .selected-name .d-icon { - display: none; - } - - .topic-notifications-options { - opacity: 0.5; + .reason { + display: inline; + line-height: $line-height-medium; } } } + +.topic-notifications-button .topic-notifications-options { + min-width: auto; +} + +.topic-notifications-button { + margin: 0; + + .topic-notifications-options { + display: inline-flex; + } +} diff --git a/app/assets/stylesheets/desktop.scss b/app/assets/stylesheets/desktop.scss index e9213e897b3..70229afbbc1 100644 --- a/app/assets/stylesheets/desktop.scss +++ b/app/assets/stylesheets/desktop.scss @@ -1,6 +1,24 @@ @import "common"; -@import "desktop/*"; +/* @import "desktop/*"; TODO: get this working again */ + +@import "desktop/alert"; +@import "desktop/banner"; +@import "desktop/compose"; +@import "desktop/discourse"; +@import "desktop/header"; +@import "desktop/login"; +@import "desktop/modal"; +@import "desktop/category-list"; +@import "desktop/latest-topic-list"; +@import "desktop/topic-list"; +@import "desktop/topic-post"; +@import "desktop/topic"; +@import "desktop/upload"; +@import "desktop/user"; +@import "desktop/history"; +@import "desktop/group"; +@import "desktop/admin_customize"; // Import all component-specific files @import "desktop/components/*"; diff --git a/app/assets/stylesheets/desktop/alert.scss b/app/assets/stylesheets/desktop/alert.scss new file mode 100644 index 00000000000..f3f57eac668 --- /dev/null +++ b/app/assets/stylesheets/desktop/alert.scss @@ -0,0 +1,3 @@ +.alert { + margin-bottom: 1em; +} diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss index 5adc17d3eb1..ca304b8e951 100644 --- a/app/assets/stylesheets/desktop/topic-post.scss +++ b/app/assets/stylesheets/desktop/topic-post.scss @@ -451,15 +451,20 @@ pre.copy-codeblocks:hover .copy-cmd { } } -#topic-footer-buttons { - max-width: calc(690px + (11px * 2) + 45px); +@mixin topic-footer-button { + margin-bottom: 5px; + margin-right: 10px; +} - .bookmark { +#topic-footer-buttons { + padding: 10px 10px 0 0; + float: left; + .btn { + @include topic-footer-button; .d-icon-bookmark.bookmarked { color: $tertiary; } } - .bookmark.bookmarked .d-icon-bookmark, .bookmark.bookmarked .d-icon-discourse-bookmark-clock { color: $tertiary; @@ -469,6 +474,10 @@ pre.copy-codeblocks:hover .copy-cmd { } } +#topic-footer-button { + width: 757px; +} + .suggested-topics { clear: left; padding: 20px 0 15px 0; diff --git a/app/assets/stylesheets/mobile.scss b/app/assets/stylesheets/mobile.scss index a3202ca43c1..ee9c3ed92df 100644 --- a/app/assets/stylesheets/mobile.scss +++ b/app/assets/stylesheets/mobile.scss @@ -1,6 +1,37 @@ @import "common"; -@import "mobile/*"; +/* @import "mobile/*"; TODO: get this working again */ + +@import "mobile/buttons"; +@import "mobile/alert"; +@import "mobile/banner"; +@import "mobile/compose"; +@import "mobile/discourse"; +@import "mobile/header"; +@import "mobile/login"; +@import "mobile/modal"; +@import "mobile/topic-list"; +@import "mobile/topic-post"; +@import "mobile/topic"; +@import "mobile/upload"; +@import "mobile/user"; +@import "mobile/history"; +@import "mobile/lightbox"; +@import "mobile/directory"; +@import "mobile/search"; +@import "mobile/emoji"; +@import "mobile/ring"; +@import "mobile/group"; +@import "mobile/dashboard"; +@import "mobile/admin_badges"; +@import "mobile/admin_customize"; +@import "mobile/admin_reports"; +@import "mobile/admin_report"; +@import "mobile/admin_report_table"; +@import "mobile/admin_report_counters"; +@import "mobile/admin_emojis"; +@import "mobile/menu-panel"; +@import "mobile/reviewables"; // Import all component-specific files @import "mobile/components/*"; diff --git a/app/assets/stylesheets/mobile/alert.scss b/app/assets/stylesheets/mobile/alert.scss index 12e60245e57..0ee9b44ee0e 100644 --- a/app/assets/stylesheets/mobile/alert.scss +++ b/app/assets/stylesheets/mobile/alert.scss @@ -1,8 +1,7 @@ +// there are (n) new or updated topics, click to show .alert.alert-info { - margin-bottom: 0.5em; + margin: 0; &.clickable { - // there are (n) new or updated topics, click to show - margin-bottom: 0; padding: 1em; } } diff --git a/app/assets/stylesheets/mobile/banner.scss b/app/assets/stylesheets/mobile/banner.scss index fc308f05880..852b2847364 100644 --- a/app/assets/stylesheets/mobile/banner.scss +++ b/app/assets/stylesheets/mobile/banner.scss @@ -3,6 +3,11 @@ // -------------------------------------------------- #banner { + // go full width on mobile, by extending into the 10px wrap + // borders on left and right + margin: 0 -10px; max-height: 180px; - height: 20vh; + @media all and (max-height: 499px) { + max-height: 100px; + } } diff --git a/app/assets/stylesheets/mobile/discourse.scss b/app/assets/stylesheets/mobile/discourse.scss index c9406abca6b..260f8d4b13f 100644 --- a/app/assets/stylesheets/mobile/discourse.scss +++ b/app/assets/stylesheets/mobile/discourse.scss @@ -63,6 +63,11 @@ blockquote { margin-bottom: 9px; } +// categories should not be bold on mobile; they fight with the topic title too much +.badge-wrapper { + font-weight: normal; +} + .mobile-nav { margin: 0; padding: 0; diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss index d84b4a727cf..9cd4931ce83 100644 --- a/app/assets/stylesheets/mobile/topic-post.scss +++ b/app/assets/stylesheets/mobile/topic-post.scss @@ -36,7 +36,6 @@ span.badge-posts { .double-button { display: flex; flex: 0 1 auto; - align-items: center; button { &.like, &.read-indicator, @@ -236,16 +235,20 @@ a.reply-to-tab { } #topic-footer-buttons { + @include clearfix; + padding: 20px 0 0 0; .d-icon-bookmark.bookmarked, .d-icon-discourse-bookmark-clock.bookmarked { color: $tertiary; } - - .topic-footer-mobile-dropdown { - margin: 0 0.5em 0.5em 0; + .combobox { + margin-right: 0.5em; width: 160px; + margin-bottom: 0.5em; } +} +#topic-footer-buttons { .topic-notifications-button, .pinned-button { display: flex; @@ -260,6 +263,11 @@ a.reply-to-tab { } } +#topic-footer-button { + width: 100px; + margin: 0 auto; +} + .suggested-topics { clear: left; padding: 20px 0 15px 0; @@ -284,6 +292,13 @@ span.post-count { opacity: 0.8; } +#topic-footer-buttons { + .btn { + margin-bottom: 0.5em; + margin-right: 0.5em; + } +} + #topic-title { z-index: z("base") + 1; margin: 0 0 0 0 !important; diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index 3f3f9e15a36..fe2d3a2327d 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -16,7 +16,7 @@ class AboutController < ApplicationController render :index end format.json do - render_json_dump(AboutSerializer.new(@about, scope: guardian)) + render_serialized(@about, AboutSerializer) end end end diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 5eadbbcf6d7..81511387f73 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -331,13 +331,7 @@ class ListController < ApplicationController params[:category] = @category.id.to_s - @description_meta = if @category.uncategorized? - I18n.t('category.uncategorized_description', locale: SiteSetting.default_locale) - else - @category.description_text - end - @description_meta = SiteSetting.site_description if @description_meta.blank? - + @description_meta = @category.description_text if !guardian.can_see?(@category) if SiteSetting.detailed_404 raise Discourse::InvalidAccess diff --git a/app/controllers/themes_controller.rb b/app/controllers/themes_controller.rb new file mode 100644 index 00000000000..6520ec70975 --- /dev/null +++ b/app/controllers/themes_controller.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class ThemesController < ::ApplicationController + def assets + theme_ids = params[:ids].to_s.split("-").map(&:to_i) + + if params[:ids] == "default" + theme_ids = nil + else + raise Discourse::NotFound unless guardian.allow_themes?(theme_ids) + end + + targets = view_context.mobile_view? ? [:mobile, :mobile_theme] : [:desktop, :desktop_theme] + targets << :admin if guardian.is_staff? + targets.append(*Discourse.find_plugin_css_assets(mobile_view: true, desktop_view: true)) + + object = targets.map do |target| + Stylesheet::Manager.stylesheet_data(target, theme_ids).map do |hash| + next hash unless Rails.env.development? + + dup_hash = hash.dup + dup_hash[:new_href] = dup_hash[:new_href].dup + dup_hash[:new_href] << (dup_hash[:new_href].include?("?") ? "&" : "?") + dup_hash[:new_href] << SecureRandom.hex + dup_hash + end + end.flatten + + render json: object.as_json + end +end diff --git a/app/helpers/email_helper.rb b/app/helpers/email_helper.rb index 14364d45c32..c579473a4d2 100644 --- a/app/helpers/email_helper.rb +++ b/app/helpers/email_helper.rb @@ -25,8 +25,12 @@ module EmailHelper raw "#{title}" end - def email_html_template - EmailStyle.new.html.sub('%{email_content}', yield).html_safe + def email_html_template(binding_arg) + template = EmailStyle.new.html.sub( + '%{email_content}', + '<%= yield %><% if defined?(html_body) %><%= html_body %><% end %>' + ) + ERB.new(template).result(binding_arg) end protected diff --git a/app/models/application_request.rb b/app/models/application_request.rb index 3d0d8ae905f..52a6a8a87e0 100644 --- a/app/models/application_request.rb +++ b/app/models/application_request.rb @@ -16,16 +16,15 @@ class ApplicationRequest < ActiveRecord::Base include CachedCounting def self.disable - @disabled = true + @enabled = false end def self.enable - @disabled = false + @enabled = true end def self.increment!(type, opts = nil) - return if @disabled - perform_increment!(redis_key(type), opts) + perform_increment!(redis_key(type), opts) if @enabled end def self.write_cache!(date = nil) diff --git a/app/models/category.rb b/app/models/category.rb index 6ecfe9d3afe..63db814752e 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -709,29 +709,37 @@ class Category < ActiveRecord::Base ].include? id end - def full_slug(separator = "-") - start_idx = "#{Discourse.base_uri}/c/".size - url[start_idx..-1].gsub("/", separator) - end - - @@url_cache = DistributedCache.new("category_url") + @@url_cache = DistributedCache.new('category_url') def clear_url_cache @@url_cache.clear end + def full_slug(separator = "-") + start_idx = "#{Discourse.base_uri}/c/".length + url[start_idx..-1].gsub("/", separator) + end + def url - @@url_cache[self.id] ||= "#{Discourse.base_uri}/c/#{slug_path.join('/')}" + url = @@url_cache[self.id] + unless url + url = "#{Discourse.base_uri}/c/#{slug_path.join('/')}" + + @@url_cache[self.id] = url + end + + url end def url_with_id self.parent_category ? "#{url}/#{self.id}" : "#{Discourse.base_uri}/c/#{self.slug}/#{self.id}" end - # If the name changes, try and update the category definition topic too if it's an exact match + # If the name changes, try and update the category definition topic too if it's + # an exact match def rename_category_definition - return unless topic.present? old_name = saved_changes.transform_values(&:first)["name"] + return unless topic.present? if topic.title == I18n.t("category.topic_prefix", category: old_name) topic.update_attribute(:title, I18n.t("category.topic_prefix", category: name)) end diff --git a/app/models/global_setting.rb b/app/models/global_setting.rb index 21e5a137dcf..f4425919ed3 100644 --- a/app/models/global_setting.rb +++ b/app/models/global_setting.rb @@ -164,15 +164,9 @@ class GlobalSetting c[:port] = redis_port if redis_port if redis_slave_host && redis_slave_port - if ENV["RAILS_FAILOVER"] - c[:replica_host] = redis_slave_host - c[:replica_port] = redis_slave_port - c[:connector] = RailsFailover::Redis::Connector - else - c[:slave_host] = redis_slave_host - c[:slave_port] = redis_slave_port - c[:connector] = DiscourseRedis::Connector - end + c[:slave_host] = redis_slave_host + c[:slave_port] = redis_slave_port + c[:connector] = DiscourseRedis::Connector end c[:password] = redis_password if redis_password.present? @@ -194,15 +188,9 @@ class GlobalSetting c[:port] = message_bus_redis_port if message_bus_redis_port if message_bus_redis_slave_host && message_bus_redis_slave_port - if ENV["RAILS_FAILOVER"] - c[:replica_host] = message_bus_redis_slave_host - c[:replica_port] = message_bus_redis_slave_port - c[:connector] = RailsFailover::Redis::Connector - else - c[:slave_host] = message_bus_redis_slave_host - c[:slave_port] = message_bus_redis_slave_port - c[:connector] = DiscourseRedis::Connector - end + c[:slave_host] = message_bus_redis_slave_host + c[:slave_port] = message_bus_redis_slave_port + c[:connector] = DiscourseRedis::Connector end c[:password] = message_bus_redis_password if message_bus_redis_password.present? diff --git a/app/models/group_archived_message.rb b/app/models/group_archived_message.rb index 8199a53cf62..1715a57585f 100644 --- a/app/models/group_archived_message.rb +++ b/app/models/group_archived_message.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class GroupArchivedMessage < ActiveRecord::Base - belongs_to :group + belongs_to :user belongs_to :topic def self.move_to_inbox!(group_id, topic) diff --git a/app/models/post.rb b/app/models/post.rb index e1a3a1f391e..89dbbcfebba 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -159,6 +159,14 @@ class Post < ActiveRecord::Base includes(:post_details).find_by(post_details: { key: key, value: value }) end + def self.excerpt_size=(sz) + @excerpt_size = sz + end + + def self.excerpt_size + @excerpt_size || 220 + end + def whisper? post_type == Post.types[:whisper] end @@ -474,7 +482,7 @@ class Post < ActiveRecord::Base end def excerpt_for_topic - Post.excerpt(cooked, SiteSetting.topic_excerpt_maxlength, strip_links: true, strip_images: true, post: self) + Post.excerpt(cooked, Post.excerpt_size, strip_links: true, strip_images: true, post: self) end def is_first_post? @@ -650,10 +658,6 @@ class Post < ActiveRecord::Base baked_version: BAKED_VERSION ) - if is_first_post? - topic.update_excerpt(excerpt_for_topic) - end - if invalidate_broken_images custom_fields.delete(BROKEN_IMAGES) save_custom_fields diff --git a/app/models/topic.rb b/app/models/topic.rb index 38affdb327b..d331a308060 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -33,11 +33,11 @@ class Topic < ActiveRecord::Base end def self.thumbnail_sizes - [ self.share_thumbnail_size ] + DiscoursePluginRegistry.topic_thumbnail_sizes + [ self.share_thumbnail_size ] end - def thumbnail_job_redis_key(sizes) - "generate_topic_thumbnail_enqueue_#{id}_#{sizes.inspect}" + def thumbnail_job_redis_key(extra_sizes) + "generate_topic_thumbnail_enqueue_#{id}_#{extra_sizes.inspect}" end def filtered_topic_thumbnails(extra_sizes: []) @@ -79,7 +79,7 @@ class Topic < ActiveRecord::Base if SiteSetting.create_thumbnails && enqueue_if_missing && records.length < thumbnail_sizes.length && - Discourse.redis.set(thumbnail_job_redis_key(thumbnail_sizes), 1, nx: true, ex: 1.minute) + Discourse.redis.set(thumbnail_job_redis_key(extra_sizes), 1, nx: true, ex: 1.minute) Jobs.enqueue(:generate_topic_thumbnails, { topic_id: id, extra_sizes: extra_sizes }) end @@ -1476,13 +1476,6 @@ class Topic < ActiveRecord::Base private_topic end - def update_excerpt(excerpt) - update_column(:excerpt, excerpt) - if archetype == "banner" - ApplicationController.banner_json_cache.clear - end - end - def pm_with_non_human_user? sql = <<~SQL SELECT 1 FROM topics diff --git a/app/models/topic_embed.rb b/app/models/topic_embed.rb index 362ee79f4ac..a18e5b85dea 100644 --- a/app/models/topic_embed.rb +++ b/app/models/topic_embed.rb @@ -109,8 +109,6 @@ class TopicEmbed < ActiveRecord::Base url = UrlHelper.escape_uri(url) original_uri = URI.parse(url) - raise URI::InvalidURIError unless original_uri.is_a?(URI::HTTP) - opts = { tags: %w[div p code pre h1 h2 h3 b em i strong a img ul li ol blockquote], attributes: %w[href src class], diff --git a/app/models/upload.rb b/app/models/upload.rb index 31c931c172b..bb4e7976f5e 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -448,3 +448,7 @@ end # index_uploads_on_url (url) # index_uploads_on_user_id (user_id) # +# Foreign Keys +# +# fk_rails_... (access_control_post_id => posts.id) +# diff --git a/app/models/user.rb b/app/models/user.rb index d9678d1a1c7..9d682a62bd8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,95 +7,102 @@ class User < ActiveRecord::Base include SecondFactorManager include HasDestroyedWebHook - DEFAULT_FEATURED_BADGE_COUNT = 3 - - # not deleted on user delete has_many :posts - has_many :topics - has_many :uploads - + has_many :notifications, dependent: :delete_all + has_many :topic_users, dependent: :delete_all has_many :category_users, dependent: :destroy has_many :tag_users, dependent: :destroy has_many :user_api_keys, dependent: :destroy - has_many :topic_allowed_users, dependent: :destroy - has_many :user_archived_messages, dependent: :destroy - has_many :email_change_requests, dependent: :destroy - has_many :email_tokens, dependent: :destroy - has_many :invites, dependent: :destroy - has_many :topic_links, dependent: :destroy - has_many :user_uploads, dependent: :destroy - has_many :user_emails, dependent: :destroy - has_many :user_associated_accounts, dependent: :destroy - has_many :oauth2_user_infos, dependent: :destroy - has_many :user_second_factors, dependent: :destroy - has_many :user_badges, -> { for_enabled_badges }, dependent: :destroy - has_many :user_auth_tokens, dependent: :destroy - has_many :group_users, dependent: :destroy - has_many :user_warnings, dependent: :destroy - has_many :api_keys, dependent: :destroy - has_many :push_subscriptions, dependent: :destroy - has_many :acting_group_histories, dependent: :destroy, foreign_key: :acting_user_id, class_name: 'GroupHistory' - has_many :targeted_group_histories, dependent: :destroy, foreign_key: :target_user_id, class_name: 'GroupHistory' - has_many :reviewable_scores, dependent: :destroy + has_many :topics + has_many :bookmarks - has_one :user_option, dependent: :destroy - has_one :user_avatar, dependent: :destroy - has_one :github_user_info, dependent: :destroy - has_one :primary_email, -> { where(primary: true) }, class_name: 'UserEmail', dependent: :destroy - has_one :user_stat, dependent: :destroy - has_one :user_profile, dependent: :destroy, inverse_of: :user - has_one :single_sign_on_record, dependent: :destroy - has_one :anonymous_user_master, class_name: 'AnonymousUser', dependent: :destroy - has_one :anonymous_user_shadow, ->(record) { where(active: true) }, foreign_key: :master_user_id, class_name: 'AnonymousUser', dependent: :destroy - - # delete all is faster but bypasses callbacks - has_many :bookmarks, dependent: :delete_all - has_many :notifications, dependent: :delete_all - has_many :topic_users, dependent: :delete_all - has_many :email_logs, dependent: :delete_all - has_many :incoming_emails, dependent: :delete_all - has_many :user_visits, dependent: :delete_all - has_many :user_auth_token_logs, dependent: :delete_all - has_many :group_requests, dependent: :delete_all - has_many :muted_user_records, class_name: 'MutedUser', dependent: :delete_all - has_many :ignored_user_records, class_name: 'IgnoredUser', dependent: :delete_all - - # dependent deleting handled via before_destroy (special cases) + # dependent deleting handled via before_destroy has_many :user_actions has_many :post_actions - has_many :post_timings - has_many :directory_items - has_many :security_keys, -> { - where(enabled: true) - }, class_name: "UserSecurityKey" + DEFAULT_FEATURED_BADGE_COUNT = 3 + + has_many :user_badges, -> { for_enabled_badges }, dependent: :destroy has_many :badges, through: :user_badges has_many :default_featured_user_badges, -> { for_enabled_badges.grouped_with_count.where("featured_rank <= ?", DEFAULT_FEATURED_BADGE_COUNT) }, class_name: "UserBadge" + has_many :email_logs, dependent: :delete_all + has_many :incoming_emails, dependent: :delete_all + has_many :post_timings + has_many :topic_allowed_users, dependent: :destroy has_many :topics_allowed, through: :topic_allowed_users, source: :topic + has_many :email_tokens, dependent: :destroy + has_many :user_visits, dependent: :destroy + has_many :invites, dependent: :destroy + has_many :topic_links, dependent: :destroy + has_many :uploads + has_many :user_warnings + has_many :user_archived_messages, dependent: :destroy + has_many :email_change_requests, dependent: :destroy + + # see before_destroy + has_many :directory_items + has_many :user_auth_tokens, dependent: :destroy + has_many :user_auth_token_logs, dependent: :destroy + + has_many :group_users, dependent: :destroy has_many :groups, through: :group_users + has_many :group_requests, dependent: :destroy has_many :secure_categories, through: :groups, source: :categories - # deleted in user_second_factors relationship + has_many :user_uploads, dependent: :destroy + has_many :user_emails, dependent: :destroy + + has_one :primary_email, -> { where(primary: true) }, class_name: 'UserEmail', dependent: :destroy + + has_one :user_option, dependent: :destroy + has_one :user_avatar, dependent: :destroy + has_many :user_associated_accounts, dependent: :destroy + has_one :github_user_info, dependent: :destroy + has_many :oauth2_user_infos, dependent: :destroy + has_many :user_second_factors, dependent: :destroy + has_many :totps, -> { where(method: UserSecondFactor.methods[:totp], enabled: true) }, class_name: "UserSecondFactor" + has_many :security_keys, -> { + where(enabled: true) + }, class_name: "UserSecurityKey" + + has_one :anonymous_user_master, class_name: 'AnonymousUser' + has_one :anonymous_user_shadow, ->(record) { where(active: true) }, foreign_key: :master_user_id, class_name: 'AnonymousUser' + has_one :master_user, through: :anonymous_user_master has_one :shadow_user, through: :anonymous_user_shadow, source: :user + has_one :user_stat, dependent: :destroy + has_one :user_profile, dependent: :destroy, inverse_of: :user has_one :profile_background_upload, through: :user_profile has_one :card_background_upload, through: :user_profile + has_one :single_sign_on_record, dependent: :destroy belongs_to :approved_by, class_name: 'User' belongs_to :primary_group, class_name: 'Group' + has_many :muted_user_records, class_name: 'MutedUser' has_many :muted_users, through: :muted_user_records + + has_many :ignored_user_records, class_name: 'IgnoredUser' has_many :ignored_users, through: :ignored_user_records + has_many :api_keys, dependent: :destroy + + has_many :push_subscriptions, dependent: :destroy + belongs_to :uploaded_avatar, class_name: 'Upload' + has_many :acting_group_histories, dependent: :destroy, foreign_key: :acting_user_id, class_name: 'GroupHistory' + has_many :targeted_group_histories, dependent: :destroy, foreign_key: :target_user_id, class_name: 'GroupHistory' + + has_many :reviewable_scores, dependent: :destroy + delegate :last_sent_email_address, to: :email_logs validates_presence_of :username @@ -157,9 +164,6 @@ class User < ActiveRecord::Base DirectoryItem.where(user_id: self.id) .where('period_type in (?)', DirectoryItem.period_types.values) .delete_all - - # our relationship filters on enabled, this makes sure everything is deleted - UserSecurityKey.where(user_id: self.id).delete_all end # Skip validating email, for example from a particular auth provider plugin @@ -929,7 +933,7 @@ class User < ActiveRecord::Base def activate if email_token = self.email_tokens.active.where(email: self.email).first - EmailToken.confirm(email_token.token, skip_reviewable: true) + user = EmailToken.confirm(email_token.token, skip_reviewable: true) end self.update!(active: true) create_reviewable @@ -1115,9 +1119,10 @@ class User < ActiveRecord::Base end def number_of_rejected_posts - ReviewableQueuedPost - .where(status: Reviewable.statuses[:rejected]) - .where(created_by_id: self.id) + Post.with_deleted + .where(user_id: self.id) + .joins('INNER JOIN reviewables r ON posts.id = r.target_id') + .where(r: { status: Reviewable.statuses[:rejected], type: ReviewableQueuedPost.name }) .count end diff --git a/app/models/user_avatar.rb b/app/models/user_avatar.rb index bd2751d6b45..f6dbf133126 100644 --- a/app/models/user_avatar.rb +++ b/app/models/user_avatar.rb @@ -5,14 +5,6 @@ class UserAvatar < ActiveRecord::Base belongs_to :gravatar_upload, class_name: 'Upload' belongs_to :custom_upload, class_name: 'Upload' - @@custom_user_gravatar_email_hash = { - Discourse::SYSTEM_USER_ID => User.email_hash("info@discourse.org") - } - - def self.register_custom_user_gravatar_email_hash(user_id, email) - @@custom_user_gravatar_email_hash[user_id] = User.email_hash(email) - end - def contains_upload?(id) gravatar_upload_id == id || custom_upload_id == id end @@ -20,14 +12,14 @@ class UserAvatar < ActiveRecord::Base def update_gravatar! DistributedMutex.synchronize("update_gravatar_#{user_id}") do begin - self.update!(last_gravatar_download_attempt: Time.zone.now) + self.update!(last_gravatar_download_attempt: Time.now) max = Discourse.avatar_sizes.max # The user could be deleted before this executes return if user.blank? || user.primary_email.blank? - email_hash = @@custom_user_gravatar_email_hash[user_id] || user.email_hash + email_hash = user_id == Discourse::SYSTEM_USER_ID ? User.email_hash("info@discourse.org") : user.email_hash gravatar_url = "https://#{SiteSetting.gravatar_base_url}/avatar/#{email_hash}.png?s=#{max}&d=404&reset_cache=#{SecureRandom.urlsafe_base64(5)}" # follow redirects in case gravatar change rules on us diff --git a/app/models/web_hook_event_type.rb b/app/models/web_hook_event_type.rb index 442f14cb8ce..952c1c2062c 100644 --- a/app/models/web_hook_event_type.rb +++ b/app/models/web_hook_event_type.rb @@ -7,6 +7,8 @@ class WebHookEventType < ActiveRecord::Base GROUP = 4 CATEGORY = 5 TAG = 6 + FLAG = 7 + QUEUED_POST = 8 REVIEWABLE = 9 NOTIFICATION = 10 SOLVED = 11 diff --git a/app/serializers/about_serializer.rb b/app/serializers/about_serializer.rb index 8230c590a4c..308f990fd6c 100644 --- a/app/serializers/about_serializer.rb +++ b/app/serializers/about_serializer.rb @@ -21,16 +21,7 @@ class AboutSerializer < ApplicationSerializer :title, :locale, :version, - :https, - :can_see_about_stats - - def can_see_about_stats - scope.can_see_about_stats? - end - - def include_stats? - can_see_about_stats - end + :https def stats object.class.fetch_cached_stats || Jobs::AboutStats.new.execute({}) diff --git a/app/services/badge_granter.rb b/app/services/badge_granter.rb index a5027c53030..e402fb880cc 100644 --- a/app/services/badge_granter.rb +++ b/app/services/badge_granter.rb @@ -3,11 +3,11 @@ class BadgeGranter def self.disable_queue - @queue_disabled = true + @queue_enabled = false end def self.enable_queue - @queue_disabled = false + @queue_enabled = true end def initialize(badge, user, opts = {}) @@ -124,7 +124,7 @@ class BadgeGranter end def self.queue_badge_grant(type, opt) - return if !SiteSetting.enable_badges || @queue_disabled + return if !SiteSetting.enable_badges || !@queue_enabled payload = nil case type diff --git a/app/views/email/default_template.html b/app/views/email/default_template.html index 99b2e94995c..382f939273b 100644 --- a/app/views/email/default_template.html +++ b/app/views/email/default_template.html @@ -3,8 +3,6 @@ - - diff --git a/app/views/layouts/email_template.html.erb b/app/views/layouts/email_template.html.erb index 611eba0df49..80da92efc20 100644 --- a/app/views/layouts/email_template.html.erb +++ b/app/views/layouts/email_template.html.erb @@ -2,8 +2,5 @@ <%= yield %> <% if defined?(html_body) %><%= html_body %><% end %> <% else %> - <%= email_html_template do %> - <%= yield %> - <% if defined?(html_body) %><%= html_body %><% end %> - <% end %> + <%= email_html_template(binding).html_safe %> <% end %> diff --git a/app/views/layouts/publish.html.erb b/app/views/layouts/publish.html.erb index 4a249e8f32d..5bb0f957c58 100644 --- a/app/views/layouts/publish.html.erb +++ b/app/views/layouts/publish.html.erb @@ -2,8 +2,13 @@ - <%= render partial: "layouts/head" %> + + <%= render partial: "common/discourse_publish_stylesheet" %> + + <%- if @canonical_url -%> + + <%- end -%> <%= yield %> diff --git a/app/views/list/list.erb b/app/views/list/list.erb index 2338d39c6a5..2d32efb77bf 100644 --- a/app/views/list/list.erb +++ b/app/views/list/list.erb @@ -47,8 +47,8 @@ <%= t 'js.topic.title' %> - <%= t 'js.replies' %> - <%= t 'js.views' %> + <%= t 'js.replies' %> + <%= t 'js.views' %> <%= t 'js.activity' %> @@ -101,10 +101,10 @@ <% end %> <% end %> - + '><%= t.posts_count %> - + '><%= t.views %> diff --git a/config/application.rb b/config/application.rb index 0157dc82895..43a8bf3091d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -27,10 +27,6 @@ require_relative '../lib/discourse_plugin_registry' require_relative '../lib/plugin_gem' -if ENV['RAILS_FAILOVER'] - require 'rails_failover' -end - # Global config require_relative '../app/models/global_setting' GlobalSetting.configure! @@ -254,7 +250,7 @@ module Discourse # Our templates shouldn't start with 'discourse/app/templates' config.handlebars.templates_root = { 'discourse/app/templates' => '', - 'select-kit/addon/templates' => 'select-kit/templates/' + 'select-kit/app/templates' => 'select-kit/templates/' } config.handlebars.raw_template_namespace = "__DISCOURSE_RAW_TEMPLATES" diff --git a/config/initializers/001-redis.rb b/config/initializers/001-redis.rb index f28c59a3b1d..e48441594e9 100644 --- a/config/initializers/001-redis.rb +++ b/config/initializers/001-redis.rb @@ -2,20 +2,5 @@ if Rails.env.development? && ENV['DISCOURSE_FLUSH_REDIS'] puts "Flushing redis (development mode)" - Discourse.redis.flushdb -end - -if ENV['RAILS_FAILOVER'] - message_bus_keepalive_interval = MessageBus.keepalive_interval - - RailsFailover::Redis.register_master_up_callback do - MessageBus.keepalive_interval = message_bus_keepalive_interval - Discourse.clear_readonly! - Discourse.request_refresh! - end - - RailsFailover::Redis.register_master_down_callback do - # Disables MessageBus keepalive when Redis is in readonly mode - MessageBus.keepalive_interval = 0 - end + Discourse.redis.flushall end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 3c3618ef96e..9746f37f376 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -963,7 +963,6 @@ en: api_approved: "Approved:" api_last_used_at: "Last used at:" theme: "Theme" - save_to_change_theme: 'Theme will be updated after you click "%{save_text}"' home: "Default Home Page" staged: "Staged" @@ -2101,7 +2100,7 @@ en: help: "Move message back to Inbox" edit_message: help: "Edit first post of the message" - title: "Edit" + title: "Edit Message" defer: help: "Mark as unread" title: "Defer" @@ -3599,6 +3598,12 @@ en: tag_event: name: "Tag Event" details: "When a tag is created, updated or destroyed." + flag_event: + name: "Flag Event" + details: "When a flag is created, agreed, disagreed or ignored." + queued_post_event: + name: "Post Approval Event" + details: "When a new queued post is created, approved or rejected." reviewable_event: name: "Reviewable Event" details: "When a new item is ready for review and when its status is updated." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 2341f05c729..06f02313eb9 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1467,7 +1467,6 @@ en: exclude_rel_nofollow_domains: "A list of domains where nofollow should not be added to links. example.com will automatically allow sub.example.com as well. As a minimum, you should add the domain of this site to help web crawlers find all content. If other parts of your website are at other domains, add those too." post_excerpt_maxlength: "Maximum length of a post excerpt / summary." - topic_excerpt_maxlength: "Maximum length of a topic excerpt / summary, generated from the first post in a topic." show_pinned_excerpt_mobile: "Show excerpt on pinned topics in mobile view." show_pinned_excerpt_desktop: "Show excerpt on pinned topics in desktop view." post_onebox_maxlength: "Maximum length of a oneboxed Discourse post in characters." diff --git a/config/routes.rb b/config/routes.rb index 69ade71938a..d3a1082d435 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,7 +23,6 @@ Discourse::Application.routes.draw do post "webhooks/sparkpost" => "webhooks#sparkpost" scope path: nil, constraints: { format: /.*/ } do - Sidekiq::Web.set :sessions, Rails.application.config.session_options if Rails.env.development? mount Sidekiq::Web => "/sidekiq" mount Logster::Web => "/logs" @@ -121,6 +120,7 @@ Discourse::Application.routes.draw do put "unsuspend" put "revoke_admin", constraints: AdminConstraint.new put "grant_admin", constraints: AdminConstraint.new + post "generate_api_key", constraints: AdminConstraint.new put "revoke_moderation", constraints: AdminConstraint.new put "grant_moderation", constraints: AdminConstraint.new put "approve" @@ -950,6 +950,8 @@ Discourse::Application.routes.draw do get "/safe-mode" => "safe_mode#index" post "/safe-mode" => "safe_mode#enter", as: "safe_mode_enter" + get "/themes/assets/:ids" => "themes#assets" + unless Rails.env.production? get "/qunit" => "qunit#index" get "/wizard/qunit" => "wizard#qunit" diff --git a/config/site_settings.yml b/config/site_settings.yml index 6209cc621aa..d49bb0e4cfa 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -394,7 +394,7 @@ login: default: false github_client_id: default: "" - regex: "^[a-zA-Z0-9\\.]+$" + regex: "^[a-f0-9]+$" github_client_secret: default: "" regex: "^[a-f0-9]+$" @@ -819,12 +819,6 @@ posting: ja: 120 zh_CN: 120 zh_TW: 120 - topic_excerpt_maxlength: - default: 220 - locale_default: - ja: 120 - zh_CN: 120 - zh_TW: 120 show_pinned_excerpt_mobile: client: true default: true @@ -1388,8 +1382,7 @@ security: - Lax - Strict - Disabled - - None - regex: "^(Lax|Strict|Disabled|None)$" + regex: "^(Lax|Strict|Disabled)$" enable_escaped_fragments: true allow_index_in_robots_txt: true moderators_create_categories: false diff --git a/db/fixtures/007_web_hook_event_types.rb b/db/fixtures/007_web_hook_event_types.rb index ec666ec5ad2..8bf8e938055 100644 --- a/db/fixtures/007_web_hook_event_types.rb +++ b/db/fixtures/007_web_hook_event_types.rb @@ -30,6 +30,16 @@ WebHookEventType.seed do |b| b.name = "tag" end +WebHookEventType.seed do |b| + b.id = WebHookEventType::FLAG + b.name = "flag" +end + +WebHookEventType.seed do |b| + b.id = WebHookEventType::QUEUED_POST + b.name = "queued_post" +end + WebHookEventType.seed do |b| b.id = WebHookEventType::REVIEWABLE b.name = "reviewable" diff --git a/db/migrate/20200409033412_create_bookmarks_from_post_action_bookmarks.rb b/db/migrate/20200409033412_create_bookmarks_from_post_action_bookmarks.rb index 57b1885e350..092a0e7b992 100644 --- a/db/migrate/20200409033412_create_bookmarks_from_post_action_bookmarks.rb +++ b/db/migrate/20200409033412_create_bookmarks_from_post_action_bookmarks.rb @@ -16,7 +16,6 @@ class CreateBookmarksFromPostActionBookmarks < ActiveRecord::Migration[6.0] INNER JOIN posts ON posts.id = post_actions.post_id LEFT JOIN bookmarks ON bookmarks.post_id = post_actions.post_id AND bookmarks.user_id = post_actions.user_id INNER JOIN topics ON topics.id = posts.topic_id - INNER JOIN users ON users.id = post_actions.user_id WHERE bookmarks.id IS NULL AND post_action_type_id = :type_id AND post_actions.deleted_at IS NULL AND posts.deleted_at IS NULL LIMIT 2000 SQL diff --git a/db/migrate/20200514075356_remove_flag_web_hooks.rb b/db/migrate/20200514075356_remove_flag_web_hooks.rb deleted file mode 100644 index 448b7fb771b..00000000000 --- a/db/migrate/20200514075356_remove_flag_web_hooks.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -class RemoveFlagWebHooks < ActiveRecord::Migration[6.0] - def up - flag_event_type_id = 7 - - DB.exec <<~SQL - DELETE FROM web_hook_event_types_hooks - WHERE web_hook_event_type_id = #{flag_event_type_id} - SQL - - DB.exec <<~SQL - DELETE FROM web_hook_event_types - WHERE id = #{flag_event_type_id} - SQL - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20200514075407_remove_queued_post_web_hooks.rb b/db/migrate/20200514075407_remove_queued_post_web_hooks.rb deleted file mode 100644 index 632e5013dc9..00000000000 --- a/db/migrate/20200514075407_remove_queued_post_web_hooks.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -class RemoveQueuedPostWebHooks < ActiveRecord::Migration[6.0] - def up - queued_post_event_type_id = 8 - - DB.exec <<~SQL - DELETE FROM web_hook_event_types_hooks - WHERE web_hook_event_type_id = #{queued_post_event_type_id} - SQL - - DB.exec <<~SQL - DELETE FROM web_hook_event_types - WHERE id = #{queued_post_event_type_id} - SQL - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/post_migrate/20200520001619_remove_fks_from_bookmarks.rb b/db/post_migrate/20200520001619_remove_fks_from_bookmarks.rb deleted file mode 100644 index 80fee6dab4f..00000000000 --- a/db/post_migrate/20200520001619_remove_fks_from_bookmarks.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class RemoveFksFromBookmarks < ActiveRecord::Migration[6.0] - def change - remove_foreign_key :bookmarks, :topics - remove_foreign_key :bookmarks, :posts - remove_foreign_key :bookmarks, :users - end -end diff --git a/db/post_migrate/20200522004855_remove_access_control_post_fk.rb b/db/post_migrate/20200522004855_remove_access_control_post_fk.rb deleted file mode 100644 index 36c8d0fbb72..00000000000 --- a/db/post_migrate/20200522004855_remove_access_control_post_fk.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class RemoveAccessControlPostFk < ActiveRecord::Migration[6.0] - def change - remove_foreign_key :uploads, column: :access_control_post_id - end -end diff --git a/lib/backup_restore/backup_file_handler.rb b/lib/backup_restore/backup_file_handler.rb index 7b26356989e..c5e37024880 100644 --- a/lib/backup_restore/backup_file_handler.rb +++ b/lib/backup_restore/backup_file_handler.rb @@ -65,10 +65,9 @@ module BackupRestore return if !@is_archive log "Unzipping archive, this may take a while..." - Discourse::Utils.execute_command( - 'tar', '--extract', '--gzip', '--file', @archive_path, '--directory', @tmp_directory, - failure_message: "Failed to decompress archive." - ) + pipeline = Compression::Pipeline.new([Compression::Tar.new, Compression::Gzip.new]) + unzipped_path = pipeline.decompress(@tmp_directory, @archive_path, available_size) + pipeline.strip_directory(unzipped_path, @tmp_directory) end def extract_db_dump diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb index ab382a4d15c..ae260e2ce1a 100644 --- a/lib/discourse_plugin_registry.rb +++ b/lib/discourse_plugin_registry.rb @@ -75,8 +75,6 @@ class DiscoursePluginRegistry define_filtered_register :editable_group_custom_fields - define_filtered_register :topic_thumbnail_sizes - def self.register_auth_provider(auth_provider) self.auth_providers << auth_provider end diff --git a/lib/discourse_redis.rb b/lib/discourse_redis.rb index 6b630b7b34d..ff946cacfb5 100644 --- a/lib/discourse_redis.rb +++ b/lib/discourse_redis.rb @@ -266,6 +266,12 @@ class DiscourseRedis end end + def flushdb + DiscourseRedis.ignore_readonly do + keys.each { |k| del(k) } + end + end + def reconnect @redis._client.reconnect end diff --git a/lib/file_store/s3_store.rb b/lib/file_store/s3_store.rb index f42fa73057b..6a26ebd7ee6 100644 --- a/lib/file_store/s3_store.rb +++ b/lib/file_store/s3_store.rb @@ -79,35 +79,12 @@ module FileStore def has_been_uploaded?(url) return false if url.blank? - begin - parsed_url = URI.parse(URI.encode(url)) - rescue URI::InvalidURIError - return false - end - base_hostname = URI.parse(absolute_base_url).hostname - if url[base_hostname] - # if the hostnames match it means the upload is in the same - # bucket on s3. however, the bucket folder path may differ in - # some cases, and we do not want to assume the url is uploaded - # here. e.g. the path of the current site could be /prod and the - # other site could be /staging - if s3_bucket_folder_path.present? - return parsed_url.path.starts_with?("/#{s3_bucket_folder_path}") - else - return true - end - return false - end + return true if url[base_hostname] return false if SiteSetting.Upload.s3_cdn_url.blank? cdn_hostname = URI.parse(SiteSetting.Upload.s3_cdn_url || "").hostname - return true if cdn_hostname.presence && url[cdn_hostname] - false - end - - def s3_bucket_folder_path - @s3_helper.s3_bucket_folder_path + cdn_hostname.presence && url[cdn_hostname] end def s3_bucket_name diff --git a/lib/freedom_patches/translate_accelerator.rb b/lib/freedom_patches/translate_accelerator.rb index 5a82623f8f7..ee724d56d12 100644 --- a/lib/freedom_patches/translate_accelerator.rb +++ b/lib/freedom_patches/translate_accelerator.rb @@ -164,7 +164,7 @@ module I18n by_site[locale].with_indifferent_access rescue ActiveRecord::StatementInvalid => e - if PG::UndefinedTable === e.cause || PG::UndefinedColumn === e.cause + if PG::UndefinedTable === e.cause {} else raise diff --git a/lib/guardian.rb b/lib/guardian.rb index 456461fead6..00d496e46eb 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -493,10 +493,6 @@ class Guardian is_staff? end - def can_see_about_stats? - true - end - def auth_token if cookie = request&.cookies[Auth::DefaultCurrentUserProvider::TOKEN_COOKIE] UserAuthToken.hash_token(cookie) diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index ab48f7cbead..a993ce52f0b 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -165,16 +165,6 @@ class Plugin::Instance DiscoursePluginRegistry.register_editable_group_custom_field(field, self) end - # Request a new size for topic thumbnails - # Will respect plugin enabled setting is enabled - # Size should be an array with two elements [max_width, max_height] - def register_topic_thumbnail_size(size) - if !(size.kind_of?(Array) && size.length == 2) - raise ArgumentError.new("Topic thumbnail dimension is not valid") - end - DiscoursePluginRegistry.register_topic_thumbnail_size(size, self) - end - def custom_avatar_column(column) reloadable_patch do |plugin| AvatarLookup.lookup_columns << column diff --git a/lib/plugin_initialization_guard.rb b/lib/plugin_initialization_guard.rb index 42c1bda864f..a5a164e9e2e 100644 --- a/lib/plugin_initialization_guard.rb +++ b/lib/plugin_initialization_guard.rb @@ -6,44 +6,33 @@ def plugin_initialization_guard(&block) rescue => error plugins_directory = Rails.root + 'plugins' - if error.backtrace && error.backtrace_locations - plugin_path = error.backtrace_locations.lazy.map do |location| - Pathname.new(location.absolute_path) - .ascend - .lazy - .find { |path| path.parent == plugins_directory } - end.next + plugin_path = error.backtrace_locations.lazy.map do |location| + Pathname.new(location.absolute_path) + .ascend + .lazy + .find { |path| path.parent == plugins_directory } + end.next - raise unless plugin_path + raise unless plugin_path - stack_trace = error.backtrace.each_with_index.inject([]) do |messages, (line, index)| - if index == 0 - messages << "#{line}: #{error} (#{error.class})" - else - messages << "\t#{index}: from #{line}" - end - end.reverse.join("\n") + stack_trace = error.backtrace.each_with_index.inject([]) do |messages, (line, index)| + if index == 0 + messages << "#{line}: #{error} (#{error.class})" + else + messages << "\t#{index}: from #{line}" + end + end.reverse.join("\n") - STDERR.puts <<~MESSAGE - #{stack_trace} + STDERR.puts <<~MESSAGE + #{stack_trace} - ** INCOMPATIBLE PLUGIN ** + ** INCOMPATIBLE PLUGIN ** - You are unable to build Discourse due to errors in the plugin at - #{plugin_path} + You are unable to build Discourse due to errors in the plugin at + #{plugin_path} - Please try removing this plugin and rebuilding again! - MESSAGE - else - STDERR.puts <<~MESSAGE - ** PLUGIN FAILURE ** - - You are unable to build Discourse due to this error during plugin - initialization: - - #{error} - MESSAGE - end + Please try removing this plugin and rebuilding again! + MESSAGE exit 1 end end diff --git a/lib/post_creator.rb b/lib/post_creator.rb index c3b9556df21..8a37e4c9c64 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -374,10 +374,6 @@ class PostCreator # discourse post. def create_embedded_topic return unless @opts[:embed_url].present? - - original_uri = URI.parse(@opts[:embed_url]) - raise Discourse::InvalidParameters.new(:embed_url) unless original_uri.is_a?(URI::HTTP) - embed = TopicEmbed.new(topic_id: @post.topic_id, post_id: @post.id, embed_url: @opts[:embed_url]) rollback_from_errors!(embed) unless embed.save end diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index d610fccf375..3c9ec277cdb 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -567,7 +567,11 @@ class PostRevisor end def update_topic_excerpt - @topic.update_excerpt(@post.excerpt_for_topic) + excerpt = @post.excerpt_for_topic + @topic.update_column(:excerpt, excerpt) + if @topic.archetype == "banner" + ApplicationController.banner_json_cache.clear + end end def update_category_description diff --git a/lib/tasks/bookmarks.rake b/lib/tasks/bookmarks.rake index 87fe005b075..d3cf545d2d0 100644 --- a/lib/tasks/bookmarks.rake +++ b/lib/tasks/bookmarks.rake @@ -22,7 +22,6 @@ task "bookmarks:sync_to_table" => :environment do |_t, args| INNER JOIN posts ON posts.id = post_actions.post_id LEFT JOIN bookmarks ON bookmarks.post_id = post_actions.post_id AND bookmarks.user_id = post_actions.user_id INNER JOIN topics ON topics.id = posts.topic_id - INNER JOIN users ON users.id = post_actions.user_id WHERE bookmarks.id IS NULL AND post_action_type_id = :type_id AND post_actions.deleted_at IS NULL AND posts.deleted_at IS NULL LIMIT 2000 SQL diff --git a/lib/topic_query_params.rb b/lib/topic_query_params.rb index bab30135a17..e1bb23cb9f7 100644 --- a/lib/topic_query_params.rb +++ b/lib/topic_query_params.rb @@ -3,7 +3,7 @@ module TopicQueryParams def build_topic_list_options options = {} - params[:tags] = [params[:tag_id]] if params[:tag_id].present? && guardian.can_tag_pms? + params[:tags] = [params[:tag_id].parameterize] if params[:tag_id].present? && guardian.can_tag_pms? TopicQuery.public_valid_options.each do |key| if params.key?(key) diff --git a/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb b/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb index fda50b48299..3972a350fbf 100644 --- a/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb +++ b/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb @@ -4,20 +4,20 @@ discobot_username = 'discobot' def seed_primary_email UserEmail.seed do |ue| - ue.id = DiscourseNarrativeBot::BOT_USER_ID + ue.id = -2 ue.email = "discobot_email" ue.primary = true - ue.user_id = DiscourseNarrativeBot::BOT_USER_ID + ue.user_id = -2 end end -unless user = User.find_by(id: DiscourseNarrativeBot::BOT_USER_ID) +unless user = User.find_by(id: -2) suggested_username = UserNameSuggester.suggest(discobot_username) seed_primary_email User.seed do |u| - u.id = DiscourseNarrativeBot::BOT_USER_ID + u.id = -2 u.name = discobot_username u.username = suggested_username u.username_lower = suggested_username.downcase @@ -26,9 +26,22 @@ unless user = User.find_by(id: DiscourseNarrativeBot::BOT_USER_ID) u.approved = true u.trust_level = TrustLevel[4] end + + # TODO Pull the user avatar from that thread for now. In the future, pull it from a local file or from some central discobot repo. + if !Rails.env.test? + begin + UserAvatar.import_url_for_user( + "https://cdn.discourse.org/dev/uploads/default/original/2X/e/edb63d57a720838a7ce6a68f02ba4618787f2299.png", + User.find(-2), + override_gravatar: true + ) + rescue + # In case the avatar can't be downloaded, don't fail seed + end + end end -bot = User.find(DiscourseNarrativeBot::BOT_USER_ID) +bot = User.find(-2) # ensure discobot has a primary email unless bot.primary_email @@ -49,4 +62,4 @@ if !bot.user_profile.bio_raw ) end -Group.user_trust_level_change!(DiscourseNarrativeBot::BOT_USER_ID, TrustLevel[4]) +Group.user_trust_level_change!(-2, TrustLevel[4]) diff --git a/plugins/discourse-narrative-bot/db/post_migrate/20200520015508_clear_last_gravatar_download_attempt_on_user_avatars.rb b/plugins/discourse-narrative-bot/db/post_migrate/20200520015508_clear_last_gravatar_download_attempt_on_user_avatars.rb deleted file mode 100644 index c9029730814..00000000000 --- a/plugins/discourse-narrative-bot/db/post_migrate/20200520015508_clear_last_gravatar_download_attempt_on_user_avatars.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -class ClearLastGravatarDownloadAttemptOnUserAvatars < ActiveRecord::Migration[6.0] - def up - execute <<~SQL - UPDATE user_avatars - SET last_gravatar_download_attempt = null - WHERE user_id = -2 AND custom_upload_id IS NULL AND gravatar_upload_id IS NULL - SQL - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/plugins/discourse-narrative-bot/plugin.rb b/plugins/discourse-narrative-bot/plugin.rb index 61047c0e8b2..a6be5dd056f 100644 --- a/plugins/discourse-narrative-bot/plugin.rb +++ b/plugins/discourse-narrative-bot/plugin.rb @@ -55,7 +55,6 @@ after_initialize do module ::DiscourseNarrativeBot PLUGIN_NAME = "discourse-narrative-bot".freeze - BOT_USER_ID = -2 class Engine < ::Rails::Engine engine_name PLUGIN_NAME @@ -272,9 +271,4 @@ after_initialize do end end end - - UserAvatar.register_custom_user_gravatar_email_hash( - DiscourseNarrativeBot::BOT_USER_ID, - "discobot@discourse.org" - ) end diff --git a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb index 6914dff1d2f..4e24b9feaef 100644 --- a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb +++ b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb @@ -472,7 +472,7 @@ describe DiscourseNarrativeBot::TrackSelector do let(:post) { Fabricate(:post, topic: topic) } after do - Discourse.redis.flushdb + Discourse.redis.flushall end describe 'when random reply massage has been displayed in the last 6 hours' do diff --git a/plugins/discourse-narrative-bot/spec/jobs/send_advanced_tutorial_message_spec.rb b/plugins/discourse-narrative-bot/spec/jobs/send_advanced_tutorial_message_spec.rb index 874e40cfe81..5d3674cae08 100644 --- a/plugins/discourse-narrative-bot/spec/jobs/send_advanced_tutorial_message_spec.rb +++ b/plugins/discourse-narrative-bot/spec/jobs/send_advanced_tutorial_message_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'rails_helper' - RSpec.describe Jobs::SendAdvancedTutorialMessage do before do Jobs.run_immediately! diff --git a/spec/components/auth/default_current_user_provider_spec.rb b/spec/components/auth/default_current_user_provider_spec.rb index 8c14233a5ba..1b698cbf368 100644 --- a/spec/components/auth/default_current_user_provider_spec.rb +++ b/spec/components/auth/default_current_user_provider_spec.rb @@ -237,7 +237,7 @@ describe Auth::DefaultCurrentUserProvider do end after do - Discourse.redis.flushdb + Discourse.redis.flushall end it "should not update last seen for suspended users" do diff --git a/spec/components/discourse_redis_spec.rb b/spec/components/discourse_redis_spec.rb index abc9a5917a8..6d4af1d8174 100644 --- a/spec/components/discourse_redis_spec.rb +++ b/spec/components/discourse_redis_spec.rb @@ -21,11 +21,11 @@ describe DiscourseRedis do let(:raw_redis) { Redis.new(DiscourseRedis.config) } before do - raw_redis.flushdb + raw_redis.flushall end after do - raw_redis.flushdb + raw_redis.flushall end describe 'when namespace is enabled' do diff --git a/spec/components/email/processor_spec.rb b/spec/components/email/processor_spec.rb index 606955551a1..3fe4ab41b7a 100644 --- a/spec/components/email/processor_spec.rb +++ b/spec/components/email/processor_spec.rb @@ -5,7 +5,7 @@ require "email/processor" describe Email::Processor do after do - Discourse.redis.flushdb + Discourse.redis.flushall end let(:from) { "foo@bar.com" } diff --git a/spec/components/file_store/s3_store_spec.rb b/spec/components/file_store/s3_store_spec.rb index 15c36b05be6..99f57c71047 100644 --- a/spec/components/file_store/s3_store_spec.rb +++ b/spec/components/file_store/s3_store_spec.rb @@ -251,7 +251,7 @@ describe FileStore::S3Store do before do optimized_image.update!( - url: "//s3-upload-bucket.s3.dualstack.us-west-1.amazonaws.com/#{image_path}" + url: "//s3-upload-bucket.s3.dualstack.us-west-1.amazonaws.com#{image_path}" ) end @@ -272,12 +272,6 @@ describe FileStore::S3Store do SiteSetting.s3_upload_bucket = "s3-upload-bucket/discourse-uploads" end - before do - optimized_image.update!( - url: "//s3-upload-bucket.s3.dualstack.us-west-1.amazonaws.com/discourse-uploads/#{image_path}" - ) - end - it "removes the file from s3 with the right paths" do s3_helper.expects(:s3_bucket).returns(s3_bucket).at_least_once s3_object = stub @@ -304,15 +298,6 @@ describe FileStore::S3Store do describe ".has_been_uploaded?" do - it "doesn't crash for invalid URLs" do - expect(store.has_been_uploaded?("https://site.discourse.com/#bad#6")).to eq(false) - end - - it "doesn't crash if URL contains non-ascii characters" do - expect(store.has_been_uploaded?("//s3-upload-bucket.s3.dualstack.us-east-1.amazonaws.com/漢1337.png")).to eq(true) - expect(store.has_been_uploaded?("//s3-upload-bucket.s3.amazonaws.com/漢1337.png")).to eq(false) - end - it "identifies S3 uploads" do expect(store.has_been_uploaded?("//s3-upload-bucket.s3.dualstack.us-east-1.amazonaws.com/1337.png")).to eq(true) end diff --git a/spec/components/guardian/user_guardian_spec.rb b/spec/components/guardian/user_guardian_spec.rb index 10b6afc9413..b812fa9526d 100644 --- a/spec/components/guardian/user_guardian_spec.rb +++ b/spec/components/guardian/user_guardian_spec.rb @@ -25,13 +25,13 @@ describe UserGuardian do end let :already_uploaded do - u = Upload.new(user_id: 9999, id: 2) + u = Upload.new(user_id: 999, id: 2) user_avatar.custom_upload_id = u.id u end let :not_my_upload do - Upload.new(user_id: 9999, id: 3) + Upload.new(user_id: 999, id: 3) end let(:moderator_upload) do diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index c5ef73c4d23..8969a526bd5 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -508,7 +508,7 @@ describe PrettyText do ['apple', 'banana'].each { |w| Fabricate(:watched_word, word: w, action: WatchedWord.actions[:censor]) } expect(PrettyText.cook("# banana")).not_to include('banana') ensure - Discourse.redis.flushdb + Discourse.redis.flushall end end end @@ -1166,7 +1166,7 @@ HTML end describe "censoring" do - after(:all) { Discourse.redis.flushdb } + after(:all) { Discourse.redis.flushall } def expect_cooked_match(raw, expected_cooked) expect(PrettyText.cook(raw)).to eq(expected_cooked) diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 599ea3c5aa5..a455d81ec13 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -444,7 +444,7 @@ describe Search do end let(:expected_blurb) do - "...quire content longer than the typical test post raw content. It really is some long content, folks. elephant" + "...to satisfy any test conditions that require content longer than the typical test post raw content. elephant" end it 'returns the post' do diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index 77a234d9814..42235cb94fc 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -10,7 +10,7 @@ end Fabricator(:post_with_long_raw_content, from: :post) do raw 'This is a sample post with semi-long raw content. The raw content is also more than two hundred characters to satisfy any test conditions that require content longer - than the typical test post raw content. It really is some long content, folks.' + than the typical test post raw content.' end Fabricator(:post_with_youtube, from: :post) do diff --git a/spec/fabricators/web_hook_fabricator.rb b/spec/fabricators/web_hook_fabricator.rb index 9edc591791f..46472510808 100644 --- a/spec/fabricators/web_hook_fabricator.rb +++ b/spec/fabricators/web_hook_fabricator.rb @@ -71,6 +71,22 @@ Fabricator(:tag_web_hook, from: :web_hook) do end end +Fabricator(:flag_web_hook, from: :web_hook) do + transient flag_hook: WebHookEventType.find_by(name: 'flag') + + after_build do |web_hook, transients| + web_hook.web_hook_event_types = [transients[:flag_hook]] + end +end + +Fabricator(:queued_post_web_hook, from: :web_hook) do + transient queued_post_hook: WebHookEventType.find_by(name: 'queued_post') + + after_build do |web_hook, transients| + web_hook.web_hook_event_types = [transients[:queued_post_hook]] + end +end + Fabricator(:reviewable_web_hook, from: :web_hook) do transient reviewable_hook: WebHookEventType.find_by(name: 'reviewable') diff --git a/spec/integration/email_style_spec.rb b/spec/integration/email_style_spec.rb index 395dd19df15..ef69850891d 100644 --- a/spec/integration/email_style_spec.rb +++ b/spec/integration/email_style_spec.rb @@ -3,139 +3,128 @@ require "rails_helper" describe EmailStyle do + before do + SiteSetting.email_custom_template = "

FOR YOU

%{email_content}
" + SiteSetting.email_custom_css = 'h1 { color: red; } div.body { color: #FAB; }' + SiteSetting.email_custom_css_compiled = SiteSetting.email_custom_css + end - context "ERB evaluation" do - it "does not evaluate ERB outside of the email itself" do - SiteSetting.email_custom_template = "
%{email_content}
<%= (111 * 333) %>" - html = Email::Renderer.new(UserNotifications.signup(Fabricate(:user))).html - expect(html).not_to match("36963") + after do + SiteSetting.remove_override!(:email_custom_template) + SiteSetting.remove_override!(:email_custom_css) + end + + context 'invite' do + fab!(:invite) { Fabricate(:invite) } + let(:invite_mail) { InviteMailer.send_invite(invite) } + + subject(:mail_html) { Email::Renderer.new(invite_mail).html } + + it 'applies customizations' do + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}") + end + + it 'applies customizations if compiled is missing' do + SiteSetting.remove_override!(:email_custom_css_compiled) + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}") + end + + it 'can apply RTL attrs' do + SiteSetting.default_locale = 'he' + body_attrs = mail_html.match(/])+/) + expect(body_attrs[0]&.downcase).to match(/text-align:\s*right/) + expect(body_attrs[0]&.downcase).to include('dir="rtl"') end end - context "with a custom template" do - before do - SiteSetting.email_custom_template = "

FOR YOU

%{email_content}
" - SiteSetting.email_custom_css = 'h1 { color: red; } div.body { color: #FAB; }' - SiteSetting.email_custom_css_compiled = SiteSetting.email_custom_css + context 'user_replied' do + let(:response_by_user) { Fabricate(:user, name: "John Doe") } + let(:category) { Fabricate(:category, name: 'India') } + let(:topic) { Fabricate(:topic, category: category, title: "Super cool topic") } + let(:post) { Fabricate(:post, topic: topic, raw: 'This is My super duper cool topic') } + let(:response) { Fabricate(:basic_reply, topic: post.topic, user: response_by_user) } + let(:user) { Fabricate(:user) } + let(:notification) { Fabricate(:replied_notification, user: user, post: response) } + + let(:mail) do + UserNotifications.user_replied( + user, + post: response, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) end - after do - SiteSetting.remove_override!(:email_custom_template) - SiteSetting.remove_override!(:email_custom_css) + subject(:mail_html) { Email::Renderer.new(mail).html } + + it "customizations are applied to html part of emails" do + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + matches = mail_html.match(/
#{post.raw}/) + expect(matches[1]).to include('color: #FAB;') # custom + expect(matches[1]).to include('padding-top:5px;') # div.body end - context 'invite' do - fab!(:invite) { Fabricate(:invite) } - let(:invite_mail) { InviteMailer.send_invite(invite) } + # TODO: translation override + end - subject(:mail_html) { Email::Renderer.new(invite_mail).html } + context 'signup' do + let(:signup_mail) { UserNotifications.signup(Fabricate(:user)) } + subject(:mail_html) { Email::Renderer.new(signup_mail).html } - it 'applies customizations' do - expect(mail_html.scan('

FOR YOU

').count).to eq(1) - expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}") - end - - it 'applies customizations if compiled is missing' do - SiteSetting.remove_override!(:email_custom_css_compiled) - expect(mail_html.scan('

FOR YOU

').count).to eq(1) - expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}") - end - - it 'can apply RTL attrs' do - SiteSetting.default_locale = 'he' - body_attrs = mail_html.match(/])+/) - expect(body_attrs[0]&.downcase).to match(/text-align:\s*right/) - expect(body_attrs[0]&.downcase).to include('dir="rtl"') - end + it "customizations are applied to html part of emails" do + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + expect(mail_html).to include('activate-account') end - context 'user_replied' do - let(:response_by_user) { Fabricate(:user, name: "John Doe") } - let(:category) { Fabricate(:category, name: 'India') } - let(:topic) { Fabricate(:topic, category: category, title: "Super cool topic") } - let(:post) { Fabricate(:post, topic: topic, raw: 'This is My super duper cool topic') } - let(:response) { Fabricate(:basic_reply, topic: post.topic, user: response_by_user) } - let(:user) { Fabricate(:user) } - let(:notification) { Fabricate(:replied_notification, user: user, post: response) } - - let(:mail) do - UserNotifications.user_replied( - user, - post: response, - notification_type: notification.notification_type, - notification_data_hash: notification.data_hash + context 'translation override' do + before do + TranslationOverride.upsert!( + 'en', + 'user_notifications.signup.text_body_template', + "CLICK THAT LINK: %{base_url}/u/activate-account/%{email_token}" ) end - subject(:mail_html) { Email::Renderer.new(mail).html } - - it "customizations are applied to html part of emails" do - expect(mail_html.scan('

FOR YOU

').count).to eq(1) - matches = mail_html.match(/
#{post.raw}/) - expect(matches[1]).to include('color: #FAB;') # custom - expect(matches[1]).to include('padding-top:5px;') # div.body + after do + TranslationOverride.revert!('en', ['user_notifications.signup.text_body_template']) end - # TODO: translation override + it "applies customizations when translation override exists" do + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + expect(mail_html.scan('CLICK THAT LINK').count).to eq(1) + end end - context 'signup' do - let(:signup_mail) { UserNotifications.signup(Fabricate(:user)) } - subject(:mail_html) { Email::Renderer.new(signup_mail).html } + context 'with some bad css' do + before do + SiteSetting.email_custom_css = '@import "nope.css"; h1 {{{ size: really big; ' + SiteSetting.email_custom_css_compiled = SiteSetting.email_custom_css + end - it "customizations are applied to html part of emails" do - expect(mail_html.scan('

FOR YOU

').count).to eq(1) + it "can render the html" do + expect(mail_html.scan(/FOR YOU<\/h1>/).count).to eq(1) expect(mail_html).to include('activate-account') end - - context 'translation override' do - before do - TranslationOverride.upsert!( - 'en', - 'user_notifications.signup.text_body_template', - "CLICK THAT LINK: %{base_url}/u/activate-account/%{email_token}" - ) - end - - after do - TranslationOverride.revert!('en', ['user_notifications.signup.text_body_template']) - end - - it "applies customizations when translation override exists" do - expect(mail_html.scan('

FOR YOU

').count).to eq(1) - expect(mail_html.scan('CLICK THAT LINK').count).to eq(1) - end - end - - context 'with some bad css' do - before do - SiteSetting.email_custom_css = '@import "nope.css"; h1 {{{ size: really big; ' - SiteSetting.email_custom_css_compiled = SiteSetting.email_custom_css - end - - it "can render the html" do - expect(mail_html.scan(/FOR YOU<\/h1>/).count).to eq(1) - expect(mail_html).to include('activate-account') - end - end - end - - context 'digest' do - fab!(:popular_topic) { Fabricate(:topic, user: Fabricate(:coding_horror), created_at: 1.hour.ago) } - let(:summary_email) { UserNotifications.digest(Fabricate(:user)) } - subject(:mail_html) { Email::Renderer.new(summary_email).html } - - it "customizations are applied to html part of emails" do - expect(mail_html.scan('

FOR YOU

').count).to eq(1) - expect(mail_html).to include(popular_topic.title) - end - - it "doesn't apply customizations if apply_custom_styles_to_digest is disabled" do - SiteSetting.apply_custom_styles_to_digest = false - expect(mail_html).to_not include('

FOR YOU

') - expect(mail_html).to_not include('FOR YOU') - expect(mail_html).to include(popular_topic.title) - end + end + end + + context 'digest' do + fab!(:popular_topic) { Fabricate(:topic, user: Fabricate(:coding_horror), created_at: 1.hour.ago) } + let(:summary_email) { UserNotifications.digest(Fabricate(:user)) } + subject(:mail_html) { Email::Renderer.new(summary_email).html } + + it "customizations are applied to html part of emails" do + expect(mail_html.scan('

FOR YOU

').count).to eq(1) + expect(mail_html).to include(popular_topic.title) + end + + it "doesn't apply customizations if apply_custom_styles_to_digest is disabled" do + SiteSetting.apply_custom_styles_to_digest = false + expect(mail_html).to_not include('

FOR YOU

') + expect(mail_html).to_not include('FOR YOU') + expect(mail_html).to include(popular_topic.title) end end end diff --git a/spec/integration/topic_thumbnail_spec.rb b/spec/integration/topic_thumbnail_spec.rb index dcdbb084d5a..9ba35cbe970 100644 --- a/spec/integration/topic_thumbnail_spec.rb +++ b/spec/integration/topic_thumbnail_spec.rb @@ -10,7 +10,7 @@ describe "Topic Thumbnails" do context 'latest' do def get_topic - Discourse.redis.del(topic.thumbnail_job_redis_key(Topic.thumbnail_sizes)) + Discourse.redis.del(topic.thumbnail_job_redis_key([])) get '/latest.json' response.parsed_body["topic_list"]["topics"][0] end @@ -84,38 +84,5 @@ describe "Topic Thumbnails" do expect(thumbnails.length).to eq(5) end end - - context "with a plugin" do - before do - plugin = Plugin::Instance.new - plugin.register_topic_thumbnail_size [512, 512] - end - - after do - DiscoursePluginRegistry.reset! - end - - it "includes the theme specified resolutions" do - topic_json = nil - - expect do - topic_json = get_topic - end.to change { Jobs::GenerateTopicThumbnails.jobs.size }.by(1) - - # Run the job - args = Jobs::GenerateTopicThumbnails.jobs.last["args"].first - Jobs::GenerateTopicThumbnails.new.execute(args.with_indifferent_access) - - # Request again - expect do - topic_json = get_topic - end.to change { Jobs::GenerateTopicThumbnails.jobs.size }.by(0) - - thumbnails = topic_json["thumbnails"] - - # Original + Optimized + 1 plugin request - expect(thumbnails.length).to eq(3) - end - end end end diff --git a/spec/jobs/bookmark_reminder_notifications_spec.rb b/spec/jobs/bookmark_reminder_notifications_spec.rb index 25379d0ba39..0bcfa0b3d21 100644 --- a/spec/jobs/bookmark_reminder_notifications_spec.rb +++ b/spec/jobs/bookmark_reminder_notifications_spec.rb @@ -22,7 +22,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do bookmark1.update_column(:reminder_at, five_minutes_ago - 10.minutes) bookmark2.update_column(:reminder_at, five_minutes_ago - 5.minutes) bookmark3.update_column(:reminder_at, five_minutes_ago) - Discourse.redis.flushdb + Discourse.redis.flushall end it "sends every reminder and marks the reminder_at to nil for all bookmarks, as well as last sent date" do diff --git a/spec/lib/bookmark_reminder_notification_handler_spec.rb b/spec/lib/bookmark_reminder_notification_handler_spec.rb index 3d9a6d77f64..6af860f2f04 100644 --- a/spec/lib/bookmark_reminder_notification_handler_spec.rb +++ b/spec/lib/bookmark_reminder_notification_handler_spec.rb @@ -8,7 +8,7 @@ RSpec.describe BookmarkReminderNotificationHandler do fab!(:user) { Fabricate(:user) } before do - Discourse.redis.flushdb + Discourse.redis.flushall end describe "#send_notification" do diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 5bc5206bced..4cc716d6916 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -1158,25 +1158,6 @@ describe Post do expect(post.custom_fields).to eq("Tommy" => "Hanks", "Vincent" => "Vega") end - describe "#excerpt_for_topic" do - it "returns a topic excerpt, defaulting to 220 chars" do - expected_excerpt = "This is a sample post with semi-long raw content. The raw content is also more than \ntwo hundred characters to satisfy any test conditions that require content longer \nthan the typical test post raw content. It really is…" - post = Fabricate(:post_with_long_raw_content) - post.rebake! - excerpt = post.excerpt_for_topic - expect(excerpt).to eq(expected_excerpt) - end - - it "respects the site setting for topic excerpt" do - SiteSetting.topic_excerpt_maxlength = 10 - expected_excerpt = "This is a …" - post = Fabricate(:post_with_long_raw_content) - post.rebake! - excerpt = post.excerpt_for_topic - expect(excerpt).to eq(expected_excerpt) - end - end - describe "#rebake!" do it "will rebake a post correctly" do post = create_post @@ -1195,25 +1176,6 @@ describe Post do expect(post.cooked).to eq(first_cooked) expect(result).to eq(true) end - - it "updates the topic excerpt at the same time if it is the OP" do - post = create_post - post.topic.update(excerpt: "test") - DB.exec("UPDATE posts SET cooked = 'frogs' WHERE id = ?", [ post.id ]) - post.reload - result = post.rebake! - post.topic.reload - expect(post.topic.excerpt).not_to eq("test") - end - - it "does not update the topic excerpt if the post is not the OP" do - post = create_post - post2 = create_post - post.topic.update(excerpt: "test") - result = post2.rebake! - post.topic.reload - expect(post.topic.excerpt).to eq("test") - end end describe "#set_owner" do diff --git a/spec/models/topic_embed_spec.rb b/spec/models/topic_embed_spec.rb index c91781e6dd7..ddfbe115ecf 100644 --- a/spec/models/topic_embed_spec.rb +++ b/spec/models/topic_embed_spec.rb @@ -308,14 +308,6 @@ describe TopicEmbed do end end - context "non-http URL" do - let(:url) { '/test.txt' } - - it "throws an error" do - expect { TopicEmbed.find_remote(url) }.to raise_error(URI::InvalidURIError) - end - end - context "emails" do let(:url) { 'http://example.com/foo' } let(:contents) { '

URL encoded @ symbol

normal mailto link

' } diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index d1d5d1cc911..d3815793009 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -33,7 +33,7 @@ describe Topic do describe 'censored words' do after do - Discourse.redis.flushdb + Discourse.redis.flushall end describe 'when title contains censored words' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4d2592c788f..89d5f627041 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1578,15 +1578,20 @@ describe User do describe '#number_of_rejected_posts' do it 'counts rejected posts' do - Fabricate(:reviewable_queued_post, created_by: user, status: Reviewable.statuses[:rejected]) + post = Fabricate(:post, user: user) + + Fabricate(:reviewable_queued_post, target: post, status: Reviewable.statuses[:rejected]) expect(user.number_of_rejected_posts).to eq(1) end it 'ignore non-rejected posts' do - Fabricate(:reviewable_queued_post, created_by: user, status: Reviewable.statuses[:approved]) + post = Fabricate(:post, user: user) + + Fabricate(:reviewable_queued_post, target: post, status: Reviewable.statuses[:approved]) expect(user.number_of_rejected_posts).to eq(0) + end end end diff --git a/spec/multisite/s3_store_spec.rb b/spec/multisite/s3_store_spec.rb index 064c699a12b..922c5f433ba 100644 --- a/spec/multisite/s3_store_spec.rb +++ b/spec/multisite/s3_store_spec.rb @@ -217,47 +217,4 @@ RSpec.describe 'Multisite s3 uploads', type: :multisite do end end end - - describe "#has_been_uploaded?" do - before do - SiteSetting.s3_region = 'us-west-1' - SiteSetting.s3_upload_bucket = "s3-upload-bucket/test" - SiteSetting.s3_access_key_id = "s3-access-key-id" - SiteSetting.s3_secret_access_key = "s3-secret-access-key" - SiteSetting.enable_s3_uploads = true - end - - let(:store) { FileStore::S3Store.new } - let(:client) { Aws::S3::Client.new(stub_responses: true) } - let(:resource) { Aws::S3::Resource.new(client: client) } - let(:s3_bucket) { resource.bucket(SiteSetting.s3_upload_bucket) } - let(:s3_helper) { store.s3_helper } - - it "returns false for blank urls" do - url = "" - expect(store.has_been_uploaded?(url)).to eq(false) - end - - it "returns true if the base hostname is the same for both urls" do - url = "https://s3-upload-bucket.s3.dualstack.us-west-1.amazonaws.com/test/original/2X/d/dd7964f5fd13e1103c5244ca30abe1936c0a4b88.png" - expect(store.has_been_uploaded?(url)).to eq(true) - end - - it "returns false if the base hostname is the same for both urls BUT the bucket name is different in the path" do - bucket = "someotherbucket" - url = "https://s3-upload-bucket.s3.dualstack.us-west-1.amazonaws.com/#{bucket}/original/2X/d/dd7964f5fd13e1103c5244ca30abe1936c0a4b88.png" - expect(store.has_been_uploaded?(url)).to eq(false) - end - - it "returns false if the hostnames do not match and the s3_cdn_url is blank" do - url = "https://www.someotherhostname.com/test/original/2X/d/dd7964f5fd13e1103c5244ca30abe1936c0a4b88.png" - expect(store.has_been_uploaded?(url)).to eq(false) - end - - it "returns true if the s3_cdn_url is present and matches the url hostname" do - SiteSetting.s3_cdn_url = "https://www.someotherhostname.com" - url = "https://www.someotherhostname.com/test/original/2X/d/dd7964f5fd13e1103c5244ca30abe1936c0a4b88.png" - expect(store.has_been_uploaded?(url)).to eq(true) - end - end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 256de296583..a0ce4b71b7d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -128,12 +128,6 @@ module TestSetup # code that runs inside jobs. run_later! means they are put on the redis # queue and never processed. Jobs.run_later! - - # Don't track ApplicationRequests in test mode unless opted in - ApplicationRequest.disable - - # Don't queue badge grant in test mode - BadgeGranter.disable_queue end end diff --git a/spec/requests/about_controller_spec.rb b/spec/requests/about_controller_spec.rb index a10b7663043..6c58284979f 100644 --- a/spec/requests/about_controller_spec.rb +++ b/spec/requests/about_controller_spec.rb @@ -36,21 +36,5 @@ describe AboutController do expect(response.body).to include("About - Discourse") end end - - it "serializes stats when 'Guardian#can_see_about_stats?' is true" do - Guardian.any_instance.stubs(:can_see_about_stats?).returns(true) - get "/about.json" - - expect(response.status).to eq(200) - expect(response.parsed_body["about"].keys).to include("stats") - end - - it "does not serialize stats when 'Guardian#can_see_about_stats?' is false" do - Guardian.any_instance.stubs(:can_see_about_stats?).returns(false) - get "/about.json" - - expect(response.status).to eq(200) - expect(response.parsed_body["about"].keys).not_to include("stats") - end end end diff --git a/spec/requests/admin/backups_controller_spec.rb b/spec/requests/admin/backups_controller_spec.rb index 03b9245744d..466d4a938be 100644 --- a/spec/requests/admin/backups_controller_spec.rb +++ b/spec/requests/admin/backups_controller_spec.rb @@ -35,7 +35,7 @@ RSpec.describe Admin::BackupsController do end after do - Discourse.redis.flushdb + Discourse.redis.flushall @paths&.each { |path| File.delete(path) if File.exists?(path) } @paths = nil diff --git a/spec/requests/admin/users_controller_spec.rb b/spec/requests/admin/users_controller_spec.rb index 099372cad00..f62407d9569 100644 --- a/spec/requests/admin/users_controller_spec.rb +++ b/spec/requests/admin/users_controller_spec.rb @@ -293,7 +293,7 @@ RSpec.describe Admin::UsersController do fab!(:another_user) { Fabricate(:coding_horror) } after do - Discourse.redis.flushdb + Discourse.redis.flushall end it "raises an error when the user doesn't have permission" do diff --git a/spec/requests/list_controller_spec.rb b/spec/requests/list_controller_spec.rb index bc913c58a04..d1238c1f00f 100644 --- a/spec/requests/list_controller_spec.rb +++ b/spec/requests/list_controller_spec.rb @@ -128,7 +128,7 @@ RSpec.describe ListController do let(:moderator) { Fabricate(:moderator) } let(:admin) { Fabricate(:admin) } let(:tag) { Fabricate(:tag) } - let(:private_message) { Fabricate(:private_message_topic, user: admin) } + let(:private_message) { Fabricate(:private_message_topic) } before do SiteSetting.tagging_enabled = true @@ -149,17 +149,6 @@ RSpec.describe ListController do expect(response.status).to eq(200) end end - - it 'should work for tag with unicode name' do - unicode_tag = Fabricate(:tag, name: 'hello-🇺🇸') - Fabricate(:topic_tag, tag: unicode_tag, topic: private_message) - - sign_in(admin) - get "/topics/private-messages-tags/#{admin.username}/#{UrlHelper.encode_component(unicode_tag.name)}.json" - expect(response.status).to eq(200) - expect(response.parsed_body["topic_list"]["topics"].first["id"]) - .to eq(private_message.id) - end end describe '#private_messages_group' do diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb index ff355ada967..909db8c509b 100644 --- a/spec/requests/posts_controller_spec.rb +++ b/spec/requests/posts_controller_spec.rb @@ -675,17 +675,6 @@ describe PostsController do I18n.t("invalid_params", message: "category") ) end - - it 'will raise an error if specified embed_url is invalid' do - user = Fabricate(:admin) - master_key = Fabricate(:api_key).key - - post "/posts.json", - params: { title: 'this is a test title', raw: 'this is test body', embed_url: '/test.txt' }, - headers: { HTTP_API_USERNAME: user.username, HTTP_API_KEY: master_key } - - expect(response.status).to eq(422) - end end describe "when logged in" do diff --git a/spec/requests/search_controller_spec.rb b/spec/requests/search_controller_spec.rb index dac11690d3e..947bd8754a9 100644 --- a/spec/requests/search_controller_spec.rb +++ b/spec/requests/search_controller_spec.rb @@ -26,11 +26,11 @@ describe SearchController do before do # TODO be a bit more strategic here instead of junking # all of redis - Discourse.redis.flushdb + Discourse.redis.flushall end after do - Discourse.redis.flushdb + Discourse.redis.flushall end context "when overloaded" do diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index 9649f57f5ba..726b92228f2 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -2127,7 +2127,7 @@ RSpec.describe TopicsController do let(:topic) { post.topic } after do - Discourse.redis.flushdb + Discourse.redis.flushall end it 'returns first post of the topic' do diff --git a/spec/requests/webhooks_controller_spec.rb b/spec/requests/webhooks_controller_spec.rb index 580c0c72f05..7772e0eb186 100644 --- a/spec/requests/webhooks_controller_spec.rb +++ b/spec/requests/webhooks_controller_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" describe WebhooksController do - before { Discourse.redis.flushdb } + before { Discourse.redis.flushall } let(:email) { "em@il.com" } let(:message_id) { "12345@il.com" } diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb index f6249b275bb..5da26a674ec 100644 --- a/spec/serializers/topic_view_serializer_spec.rb +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -60,7 +60,7 @@ describe TopicViewSerializer do it 'should have thumbnails' do SiteSetting.create_thumbnails = true - Discourse.redis.del(topic.thumbnail_job_redis_key(Topic.thumbnail_sizes)) + Discourse.redis.del(topic.thumbnail_job_redis_key([])) json = nil expect do diff --git a/spec/services/word_watcher_spec.rb b/spec/services/word_watcher_spec.rb index 5cf70b65839..0f6a2b7bb39 100644 --- a/spec/services/word_watcher_spec.rb +++ b/spec/services/word_watcher_spec.rb @@ -7,7 +7,7 @@ describe WordWatcher do let(:raw) { "Do you like liquorice?\n\nI really like them. One could even say that I am *addicted* to liquorice. Anf if\nyou can mix it up with some anise, then I'm in heaven ;)" } after do - Discourse.redis.flushdb + Discourse.redis.flushall end describe '.word_matcher_regexp' do diff --git a/test/javascripts/acceptance/category-chooser-test.js b/test/javascripts/acceptance/category-chooser-test.js index 2247c8cbee7..b6772ab7710 100644 --- a/test/javascripts/acceptance/category-chooser-test.js +++ b/test/javascripts/acceptance/category-chooser-test.js @@ -29,19 +29,3 @@ QUnit.test("prefill category when category_id is set", async assert => { 1 ); }); - -QUnit.test("filter is case insensitive", async assert => { - const categoryChooser = selectKit(".category-chooser"); - - await visit("/"); - await click("#create-topic"); - await categoryChooser.expand(); - await categoryChooser.fillInFilter("bug"); - - assert.ok(categoryChooser.rows().length, 1); - - await categoryChooser.emptyFilter(); - await categoryChooser.fillInFilter("Bug"); - - assert.ok(categoryChooser.rows().length, 1); -}); diff --git a/test/javascripts/acceptance/emoji-picker-test.js b/test/javascripts/acceptance/emoji-picker-test.js index a3d8472b535..6a4922ed5c0 100644 --- a/test/javascripts/acceptance/emoji-picker-test.js +++ b/test/javascripts/acceptance/emoji-picker-test.js @@ -168,6 +168,19 @@ QUnit.test( } ); +QUnit.test("emoji picker lazy loads emojis", async assert => { + await visit("/t/internationalization-localization/280"); + await click("#topic-footer-buttons .btn.create"); + + await click("button.emoji.btn"); + + assert.equal( + find('.emoji-picker button[title="massage_woman"]').css("background-image"), + "none", + "it doesn't load invisible emojis" + ); +}); + QUnit.test("emoji picker persists state", async assert => { await visit("/t/internationalization-localization/280"); await click("#topic-footer-buttons .btn.create"); diff --git a/test/javascripts/acceptance/preferences-test.js b/test/javascripts/acceptance/preferences-test.js index 20afdcd1677..a9db1f08e50 100644 --- a/test/javascripts/acceptance/preferences-test.js +++ b/test/javascripts/acceptance/preferences-test.js @@ -1,6 +1,7 @@ import I18n from "I18n"; import { acceptance, updateCurrentUser } from "helpers/qunit-helpers"; import selectKit from "helpers/select-kit-helper"; + import User from "discourse/models/user"; acceptance("User Preferences", { diff --git a/test/javascripts/fixtures/about.js b/test/javascripts/fixtures/about.js index 4c7de6a87a3..7f9f17cbba5 100644 --- a/test/javascripts/fixtures/about.js +++ b/test/javascripts/fixtures/about.js @@ -1,7 +1,6 @@ export default { "about.json": { about: { - can_see_about_stats: true, stats: { topic_count: 27480, post_count: 490358, diff --git a/test/javascripts/helpers/select-kit-helper.js b/test/javascripts/helpers/select-kit-helper.js index f7959913263..5d80b8f0b37 100644 --- a/test/javascripts/helpers/select-kit-helper.js +++ b/test/javascripts/helpers/select-kit-helper.js @@ -32,11 +32,6 @@ async function selectKitFillInFilter(filter, selector) { ); } -async function selectKitEmptyFilter(selector) { - checkSelectKitIsNotCollapsed(selector); - await fillIn(`${selector} .filter-input`, ""); -} - async function selectKitSelectRowByValue(value, selector) { checkSelectKitIsNotCollapsed(selector); await click(`${selector} .select-kit-row[data-value='${value}']`); @@ -185,10 +180,6 @@ export default function selectKit(selector) { await selectKitFillInFilter(filter, selector); }, - async emptyFilter() { - await selectKitEmptyFilter(selector); - }, - async keyboard(value, target) { await keyboardHelper(value, target, selector); },