diff --git a/Gemfile b/Gemfile index a80f23dbc0..6c72e48bab 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 db4b88d863..752d48c3c9 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 9977fa8dd4..71b8078f6e 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 f0860e79f7..34aed775cc 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 40f1d275bb..4445fd7986 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 fc829ae12f..d11217a985 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 2fcc5781c3..1ad85b7d7b 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 ba7caf554d..2c2ebdc7fe 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 b466f084ed..cc2db042fb 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 6429be3a3c..0000000000 --- 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 f6fcef5e17..a0b0d50962 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 a2de76d3e9..a13ccd2219 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 48f63c31fb..9d293fe312 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 955e536e1e..412cd8ec2e 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 d8d5ea0036..50449aa0e3 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 2659b0ebac..63cae2c260 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 2ac52d5f71..e9e0b9a34f 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 aa5b44a716..007ec9c19d 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 4f1f13c614..45607c8cb7 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 d5e22f5437..488970c10e 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 8e27a15a03..ca4d73c925 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 e69de29bb2..0000000000 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 91bfe147ff..0000000000 --- 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 f21111ebbd..0000000000 --- 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 72d0167ac0..f36e8be2d3 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 32dc2ad7ba..f5423b9e64 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 02acfb5a2e..f2fbbbf1c2 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 5697826f59..785b2a4702 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 d9c0900182..58329393e7 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 0000000000..f54bdb6b5f --- /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 0000000000..50dd20e56e --- /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 4e2a7adc07..b8e8797f0c 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 a80e54c4fd..aa51fccce1 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 05a2902905..d729cdc742 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 bff0addac1..c279aceff4 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 48c361c164..6e465bbc6b 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 4d5e9f4288..587af3c353 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 20ed535931..3881ee7b70 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 df43c95603..2bbe33c96e 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 3e51092ae3..f080b8a016 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 a9769b5971..130bad52f8 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 b3808031a1..1e7c797205 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 e9213e897b..70229afbbc 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 0000000000..f3f57eac66 --- /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 5adc17d3eb..ca304b8e95 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 a3202ca43c..ee9c3ed92d 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 12e60245e5..0ee9b44ee0 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 fc308f0588..852b284736 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 c9406abca6..260f8d4b13 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 d84b4a727c..9cd4931ce8 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 3f3f9e15a3..fe2d3a2327 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 5eadbbcf6d..81511387f7 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 0000000000..6520ec7097 --- /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 14364d45c3..c579473a4d 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 3d0d8ae905..52a6a8a87e 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 6ecfe9d3af..63db814752 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 21e5a137dc..f4425919ed 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 8199a53cf6..1715a57585 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 e1a3a1f391..89dbbcfebb 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 38affdb327..d331a30806 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 362ee79f4a..a18e5b85de 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 31c931c172..bb4e7976f5 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 d9678d1a1c..9d682a62bd 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 bd2751d6b4..f6dbf13312 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 442f14cb8c..952c1c2062 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 8230c590a4..308f990fd6 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 a5027c5303..e402fb880c 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 99b2e94995..382f939273 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 611eba0df4..80da92efc2 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 4a249e8f32..5bb0f957c5 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 2338d39c6a..2d32efb77b 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 0157dc8289..43a8bf3091 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 f28c59a3b1..e48441594e 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 3c3618ef96..9746f37f37 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 2341f05c72..06f02313eb 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 69ade71938..d3a1082d43 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 6209cc621a..d49bb0e4cf 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 ec666ec5ad..8bf8e93805 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 57b1885e35..092a0e7b99 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 448b7fb771..0000000000 --- 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 632e5013dc..0000000000 --- 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 80fee6dab4..0000000000 --- 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 36c8d0fbb7..0000000000 --- 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 7b26356989..c5e3702488 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 ab382a4d15..ae260e2ce1 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 6b630b7b34..ff946cacfb 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 f42fa73057..6a26ebd7ee 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 5a82623f8f..ee724d56d1 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 456461fead..00d496e46e 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 ab48f7cbea..a993ce52f0 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 42c1bda864..a5a164e9e2 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 c3b9556df2..8a37e4c9c6 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 d610fccf37..3c9ec277cd 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 87fe005b07..d3cf545d2d 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 bab30135a1..e1bb23cb9f 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 fda50b4829..3972a350fb 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 c902973081..0000000000 --- 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 61047c0e8b..a6be5dd056 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 6914dff1d2..4e24b9feae 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 874e40cfe8..5d3674cae0 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 8c14233a5b..1b698cbf36 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 abc9a5917a..6d4af1d817 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 606955551a..3fe4ab41b7 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 15c36b05be..99f57c7104 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 10b6afc941..b812fa9526 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 c5ef73c4d2..8969a526bd 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 599ea3c5aa..a455d81ec1 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 77a234d981..42235cb94f 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 9edc591791..4647251080 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 395dd19df1..ef69850891 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 dcdbb084d5..9ba35cbe97 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 25379d0ba3..0bcfa0b3d2 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 3d9a6d77f6..6af860f2f0 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 5bc5206bce..4cc716d691 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 c91781e6dd..ddfbe115ec 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 d1d5d1cc91..d381579300 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 4d2592c788..89d5f62704 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 064c699a12..922c5f433b 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 256de29658..a0ce4b71b7 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 a10b766304..6c58284979 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 03b9245744..466d4a938b 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 099372cad0..f62407d956 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 bc913c58a0..d1238c1f00 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 ff355ada96..909db8c509 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 dac11690d3..947bd8754a 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 9649f57f5b..726b92228f 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 580c0c72f0..7772e0eb18 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 f6249b275b..5da26a674e 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 5cf70b6583..0f6a2b7bb3 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 2247c8cbee..b6772ab771 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 a3d8472b53..6a4922ed5c 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 20afdcd167..a9db1f08e5 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 4c7de6a87a..7f9f17cbba 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 f795991326..5d80b8f0b3 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); },