Version bump
This commit is contained in:
commit
692d3fb4de
2
.github/workflows/ember.yml
vendored
2
.github/workflows/ember.yml
vendored
@ -9,7 +9,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: run
|
||||
if: false # something is broken with this job so skip for now
|
||||
if: true
|
||||
runs-on: ubuntu-latest
|
||||
container: discourse/discourse_test:release
|
||||
timeout-minutes: 40
|
||||
|
||||
5
Gemfile
5
Gemfile
@ -105,7 +105,10 @@ gem 'omniauth-oauth2', require: false
|
||||
|
||||
gem 'omniauth-google-oauth2'
|
||||
|
||||
gem 'oj'
|
||||
# Pinning oj until https://github.com/ohler55/oj/issues/699 is resolved.
|
||||
# Segfaults and stuck processes after upgrading.
|
||||
gem 'oj', '3.13.2'
|
||||
|
||||
gem 'pg'
|
||||
gem 'mini_sql'
|
||||
gem 'pry-rails', require: false
|
||||
|
||||
@ -52,7 +52,7 @@ GEM
|
||||
activerecord (>= 3.2, < 7.0)
|
||||
rake (>= 10.4, < 14.0)
|
||||
ast (2.4.2)
|
||||
aws-eventstream (1.1.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.432.0)
|
||||
aws-sdk-core (3.112.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
@ -158,7 +158,7 @@ GEM
|
||||
fast_blank (1.0.1)
|
||||
fast_xs (0.8.0)
|
||||
fastimage (2.2.5)
|
||||
ffi (1.15.3)
|
||||
ffi (1.15.4)
|
||||
fspath (3.1.2)
|
||||
gc_tracer (1.5.1)
|
||||
globalid (0.5.2)
|
||||
@ -550,7 +550,7 @@ DEPENDENCIES
|
||||
multi_json
|
||||
mustache
|
||||
nokogiri
|
||||
oj
|
||||
oj (= 3.13.2)
|
||||
omniauth
|
||||
omniauth-facebook
|
||||
omniauth-github
|
||||
@ -609,4 +609,4 @@ DEPENDENCIES
|
||||
yaml-lint
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.19
|
||||
2.2.26
|
||||
|
||||
@ -219,6 +219,8 @@ export default Component.extend(ComposerUpload, {
|
||||
}
|
||||
|
||||
this._bindUploadTarget();
|
||||
this._bindMobileUploadButton();
|
||||
|
||||
this.appEvents.trigger("composer:will-open");
|
||||
},
|
||||
|
||||
@ -607,6 +609,7 @@ export default Component.extend(ComposerUpload, {
|
||||
|
||||
@on("willDestroyElement")
|
||||
_composerClosed() {
|
||||
this._unbindMobileUploadButton();
|
||||
this.appEvents.trigger("composer:will-close");
|
||||
next(() => {
|
||||
// need to wait a bit for the "slide down" transition of the composer
|
||||
|
||||
@ -86,6 +86,25 @@ import { addSearchSuggestion } from "discourse/widgets/search-menu-results";
|
||||
// If you add any methods to the API ensure you bump up this number
|
||||
const PLUGIN_API_VERSION = "0.12.2";
|
||||
|
||||
// This helper prevents us from applying the same `modifyClass` over and over in test mode.
|
||||
function canModify(klass, type, resolverName, changes) {
|
||||
if (!changes.pluginId) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
"To prevent errors, add a `pluginId` key to your changes when calling `modifyClass`"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
let key = "_" + type + "/" + changes.pluginId + "/" + resolverName;
|
||||
if (klass.class[key]) {
|
||||
return false;
|
||||
} else {
|
||||
klass.class[key] = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class PluginApi {
|
||||
constructor(version, container) {
|
||||
this.version = version;
|
||||
@ -138,10 +157,14 @@ class PluginApi {
|
||||
/**
|
||||
* Allows you to overwrite or extend methods in a class.
|
||||
*
|
||||
* You should add a `pluginId` property to identify your plugin
|
||||
* to help Discourse reload classes properly.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* ```
|
||||
* api.modifyClass('controller:composer', {
|
||||
* pluginId: 'my-plugin',
|
||||
* actions: {
|
||||
* newActionHere() { }
|
||||
* }
|
||||
@ -150,9 +173,15 @@ class PluginApi {
|
||||
**/
|
||||
modifyClass(resolverName, changes, opts) {
|
||||
const klass = this._resolveClass(resolverName, opts);
|
||||
if (klass) {
|
||||
if (!klass) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canModify(klass, "member", resolverName, changes)) {
|
||||
delete changes.pluginId;
|
||||
klass.class.reopen(changes);
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
@ -169,9 +198,15 @@ class PluginApi {
|
||||
**/
|
||||
modifyClassStatic(resolverName, changes, opts) {
|
||||
const klass = this._resolveClass(resolverName, opts);
|
||||
if (klass) {
|
||||
if (!klass) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canModify(klass, "static", resolverName, changes)) {
|
||||
delete changes.pluginId;
|
||||
klass.class.reopenClass(changes);
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
|
||||
@ -46,11 +46,6 @@ export default Mixin.create({
|
||||
|
||||
@on("willDestroyElement")
|
||||
_unbindUploadTarget() {
|
||||
this.mobileUploadButton?.removeEventListener(
|
||||
"click",
|
||||
this.mobileUploadButtonEventListener
|
||||
);
|
||||
|
||||
this.fileInputEl?.removeEventListener(
|
||||
"change",
|
||||
this.fileInputEventListener
|
||||
@ -86,7 +81,6 @@ export default Mixin.create({
|
||||
this._unbindUploadTarget();
|
||||
this._bindFileInputChangeListener();
|
||||
this._bindPasteListener();
|
||||
this._bindMobileUploadButton();
|
||||
|
||||
this._uppyInstance = new Uppy({
|
||||
id: this.uppyId,
|
||||
@ -153,6 +147,10 @@ export default Mixin.create({
|
||||
});
|
||||
|
||||
this._uppyInstance.on("progress", (progress) => {
|
||||
if (this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.set("uploadProgress", progress);
|
||||
});
|
||||
|
||||
|
||||
@ -327,8 +327,6 @@ export default Mixin.create({
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this._bindMobileUploadButton();
|
||||
},
|
||||
|
||||
_bindMobileUploadButton() {
|
||||
@ -345,13 +343,15 @@ export default Mixin.create({
|
||||
}
|
||||
},
|
||||
|
||||
@on("willDestroyElement")
|
||||
_unbindUploadTarget() {
|
||||
_unbindMobileUploadButton() {
|
||||
this.mobileUploadButton?.removeEventListener(
|
||||
"click",
|
||||
this.mobileUploadButtonEventListener
|
||||
);
|
||||
},
|
||||
|
||||
@on("willDestroyElement")
|
||||
_unbindUploadTarget() {
|
||||
this._validUploads = 0;
|
||||
const $uploadTarget = $(this.element);
|
||||
try {
|
||||
|
||||
@ -103,6 +103,10 @@ export default Mixin.create({
|
||||
});
|
||||
|
||||
$upload.on("fileuploadprogressall", (e, data) => {
|
||||
if (this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const progress = parseInt((data.loaded / data.total) * 100, 10);
|
||||
this.set("uploadProgress", progress);
|
||||
});
|
||||
|
||||
@ -128,6 +128,10 @@ export default Mixin.create({
|
||||
this._uppyInstance.use(UppyChecksum, { capabilities: this.capabilities });
|
||||
|
||||
this._uppyInstance.on("progress", (progress) => {
|
||||
if (this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.set("uploadProgress", progress);
|
||||
});
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import UserAction from "discourse/models/user-action";
|
||||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default UserTopicListRoute.extend({
|
||||
userActionType: UserAction.TYPES.topics,
|
||||
@ -9,4 +10,9 @@ export default UserTopicListRoute.extend({
|
||||
filter: "read",
|
||||
});
|
||||
},
|
||||
|
||||
@action
|
||||
refresh() {
|
||||
this.refresh();
|
||||
},
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import UserAction from "discourse/models/user-action";
|
||||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default UserTopicListRoute.extend({
|
||||
userActionType: UserAction.TYPES.topics,
|
||||
@ -10,4 +11,9 @@ export default UserTopicListRoute.extend({
|
||||
"topics/created-by/" + this.modelFor("user").get("username_lower"),
|
||||
});
|
||||
},
|
||||
|
||||
@action
|
||||
refresh() {
|
||||
this.refresh();
|
||||
},
|
||||
});
|
||||
|
||||
@ -158,6 +158,10 @@ export default Component.extend(UtilsMixin, {
|
||||
}
|
||||
},
|
||||
|
||||
focusIn(event) {
|
||||
event.stopImmediatePropagation();
|
||||
},
|
||||
|
||||
keyDown(event) {
|
||||
if (this.selectKit.isExpanded) {
|
||||
if (event.key === "Backspace") {
|
||||
|
||||
@ -27,10 +27,10 @@ class TopicEmbed < ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Import an article from a source (RSS/Atom/Other)
|
||||
def self.import(user, url, title, contents, category_id: nil)
|
||||
def self.import(user, url, title, contents, category_id: nil, cook_method: nil)
|
||||
return unless url =~ /^https?\:\/\//
|
||||
|
||||
if SiteSetting.embed_truncate
|
||||
if SiteSetting.embed_truncate && cook_method.nil?
|
||||
contents = first_paragraph_from(contents)
|
||||
end
|
||||
contents ||= ''
|
||||
@ -47,7 +47,7 @@ class TopicEmbed < ActiveRecord::Base
|
||||
Topic.transaction do
|
||||
eh = EmbeddableHost.record_for_url(url)
|
||||
|
||||
cook_method = if SiteSetting.embed_support_markdown
|
||||
cook_method ||= if SiteSetting.embed_support_markdown
|
||||
Post.cook_methods[:regular]
|
||||
else
|
||||
Post.cook_methods[:raw_html]
|
||||
|
||||
@ -111,5 +111,8 @@ class SidekiqLogsterReporter < Sidekiq::ExceptionHandler::Logger
|
||||
end
|
||||
end
|
||||
|
||||
Sidekiq.error_handlers.clear
|
||||
unless Rails.env.development?
|
||||
Sidekiq.error_handlers.clear
|
||||
end
|
||||
|
||||
Sidekiq.error_handlers << SidekiqLogsterReporter.new
|
||||
|
||||
@ -17,7 +17,7 @@ task "release_note:generate", :from, :to, :repo do |t, args|
|
||||
changes = find_changes(repo, args[:from], args[:to])
|
||||
|
||||
CHANGE_TYPES.each do |ct|
|
||||
print_changes(ct[:heading], changes[ct])
|
||||
print_changes(ct[:heading], changes[ct], "###")
|
||||
end
|
||||
|
||||
if changes.values.all?(&:empty?)
|
||||
@ -54,11 +54,10 @@ task "release_note:plugins:generate", :from, :to, :plugin_glob, :org do |t, args
|
||||
next
|
||||
end
|
||||
|
||||
puts "## #{name}\n\n"
|
||||
puts "### #{name}\n\n"
|
||||
CHANGE_TYPES.each do |ct|
|
||||
print_changes(ct[:heading], changes[ct])
|
||||
print_changes(ct[:heading], changes[ct], "####")
|
||||
end
|
||||
puts "---", ""
|
||||
end
|
||||
|
||||
puts "(No changes found in #{no_changes_repos.join(", ")})"
|
||||
@ -99,10 +98,10 @@ def find_changes(repo, from, to)
|
||||
changes
|
||||
end
|
||||
|
||||
def print_changes(heading, changes)
|
||||
def print_changes(heading, changes, importance)
|
||||
return if changes.length == 0
|
||||
|
||||
puts "### #{heading}", ""
|
||||
puts "#{importance} #{heading}", ""
|
||||
puts changes.to_a, ""
|
||||
end
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ module Discourse
|
||||
MAJOR = 2
|
||||
MINOR = 8
|
||||
TINY = 0
|
||||
PRE = 'beta5'
|
||||
PRE = 'beta6'
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
end
|
||||
|
||||
@ -15,6 +15,7 @@ function initializeDetails(api) {
|
||||
});
|
||||
|
||||
api.modifyClass("controller:composer", {
|
||||
pluginId: "discourse-details",
|
||||
actions: {
|
||||
insertDetails() {
|
||||
this.toolbarEvent.applySurround(
|
||||
|
||||
@ -82,6 +82,7 @@ function initializeDiscourseLocalDates(api) {
|
||||
});
|
||||
|
||||
api.modifyClass("component:d-editor", {
|
||||
pluginId: "discourse-local-dates",
|
||||
actions: {
|
||||
insertDiscourseLocalDate(toolbarEvent) {
|
||||
showModal("discourse-local-dates-create-modal").setProperties({
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
||||
const PLUGIN_ID = "new-user-narrative";
|
||||
|
||||
function initialize(api) {
|
||||
const messageBus = api.container.lookup("message-bus:main");
|
||||
const currentUser = api.getCurrentUser();
|
||||
const appEvents = api.container.lookup("service:app-events");
|
||||
|
||||
api.modifyClass("component:site-header", {
|
||||
pluginId: PLUGIN_ID,
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
this.dispatch("header:search-context-trigger", "header");
|
||||
@ -14,6 +17,8 @@ function initialize(api) {
|
||||
});
|
||||
|
||||
api.modifyClass("controller:topic", {
|
||||
pluginId: PLUGIN_ID,
|
||||
|
||||
_togglePostBookmark(post) {
|
||||
// if we are talking to discobot then any bookmarks should just
|
||||
// be created without reminder options, to streamline the new user
|
||||
|
||||
@ -4,6 +4,7 @@ import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
||||
function initializePollUIBuilder(api) {
|
||||
api.modifyClass("controller:composer", {
|
||||
pluginId: "discourse-poll-ui-builder",
|
||||
@discourseComputed(
|
||||
"siteSettings.poll_enabled",
|
||||
"siteSettings.poll_minimum_trust_level_to_create",
|
||||
|
||||
@ -4,10 +4,30 @@ import { getRegister } from "discourse-common/lib/get-owner";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
||||
const PLUGIN_ID = "discourse-poll";
|
||||
let _glued = [];
|
||||
let _interval = null;
|
||||
|
||||
function rerender() {
|
||||
_glued.forEach((g) => g.queueRerender());
|
||||
}
|
||||
|
||||
function cleanUpPolls() {
|
||||
if (_interval) {
|
||||
clearInterval(_interval);
|
||||
_interval = null;
|
||||
}
|
||||
|
||||
_glued.forEach((g) => g.cleanUp());
|
||||
_glued = [];
|
||||
}
|
||||
|
||||
function initializePolls(api) {
|
||||
const register = getRegister(api);
|
||||
cleanUpPolls();
|
||||
|
||||
api.modifyClass("controller:topic", {
|
||||
pluginId: PLUGIN_ID,
|
||||
subscribe() {
|
||||
this._super(...arguments);
|
||||
this.messageBus.subscribe("/polls/" + this.get("model.id"), (msg) => {
|
||||
@ -23,14 +43,8 @@ function initializePolls(api) {
|
||||
},
|
||||
});
|
||||
|
||||
let _glued = [];
|
||||
let _interval = null;
|
||||
|
||||
function rerender() {
|
||||
_glued.forEach((g) => g.queueRerender());
|
||||
}
|
||||
|
||||
api.modifyClass("model:post", {
|
||||
pluginId: PLUGIN_ID,
|
||||
_polls: null,
|
||||
pollsObject: null,
|
||||
|
||||
@ -110,16 +124,6 @@ function initializePolls(api) {
|
||||
});
|
||||
}
|
||||
|
||||
function cleanUpPolls() {
|
||||
if (_interval) {
|
||||
clearInterval(_interval);
|
||||
_interval = null;
|
||||
}
|
||||
|
||||
_glued.forEach((g) => g.cleanUp());
|
||||
_glued = [];
|
||||
}
|
||||
|
||||
api.includePostAttributes("polls", "polls_votes");
|
||||
api.decorateCooked(attachPolls, { onlyStream: true, id: "discourse-poll" });
|
||||
api.cleanupStream(cleanUpPolls);
|
||||
|
||||
@ -99,11 +99,22 @@ describe TopicEmbed do
|
||||
|
||||
it "creates the topic in the category passed as a parameter" do
|
||||
Jobs.run_immediately!
|
||||
SiteSetting.embed_unlisted = false
|
||||
imported_post = TopicEmbed.import(user, "http://eviltrout.com/abcd", title, "some random content", category_id: category.id)
|
||||
expect(imported_post.topic.category).not_to eq(embeddable_host.category)
|
||||
expect(imported_post.topic.category).to eq(category)
|
||||
end
|
||||
|
||||
it "respects overriding the cook_method when asked" do
|
||||
Jobs.run_immediately!
|
||||
SiteSetting.embed_support_markdown = false
|
||||
stub_request(:get, "https://www.youtube.com/watch?v=K56soYl0U1w")
|
||||
.to_return(status: 200, body: "", headers: {})
|
||||
stub_request(:get, "https://www.youtube.com/embed/K56soYl0U1w")
|
||||
.to_return(status: 200, body: "", headers: {})
|
||||
|
||||
imported_post = TopicEmbed.import(user, "http://eviltrout.com/abcd", title, "https://www.youtube.com/watch?v=K56soYl0U1w", cook_method: Post.cook_methods[:regular])
|
||||
expect(imported_post.cooked).to match(/onebox|iframe/)
|
||||
end
|
||||
end
|
||||
|
||||
context "post creation supports markdown rendering" do
|
||||
|
||||
Reference in New Issue
Block a user