Merge remote-tracking branch 'discourse/master' into transform-native-emojis-to-names
|
@ -240,7 +240,11 @@ export default Ember.Component.extend({
|
|||
|
||||
$element.on('fileuploadsubmit', (e, data) => {
|
||||
const isPrivateMessage = this.get("composer.privateMessage");
|
||||
const isUploading = validateUploadedFiles(data.files, { isPrivateMessage });
|
||||
const opts = {
|
||||
isPrivateMessage,
|
||||
allowStaffToUploadAnyFileInPm: this.siteSettings.allow_staff_to_upload_any_file_in_pm,
|
||||
}
|
||||
const isUploading = validateUploadedFiles(data.files, opts);
|
||||
data.formData = { type: "composer", for_private_message: isPrivateMessage };
|
||||
this.setProperties({ uploadProgress: 0, isUploading });
|
||||
return isUploading;
|
||||
|
|
|
@ -138,7 +138,7 @@ class Toolbar {
|
|||
label: button.label,
|
||||
icon: button.label ? null : button.icon || button.id,
|
||||
action: button.action || 'toolbarButton',
|
||||
perform: button.perform || Ember.K,
|
||||
perform: button.perform || function() { },
|
||||
trimLeading: button.trimLeading
|
||||
};
|
||||
|
||||
|
@ -338,8 +338,7 @@ export default Ember.Component.extend({
|
|||
},
|
||||
|
||||
onKeyUp(text, cp) {
|
||||
const subtext = text.substring(0, cp);
|
||||
return subtext.match(/(:(?!:).?[\w-]*:?(?!:)(?:t\d?)?:?) ?$/gm);
|
||||
return text.substring(0, cp).match(/(:(?!:).?[\w-]*:?(?!:)(?:t\d?)?:?) ?$/g);
|
||||
},
|
||||
|
||||
transformComplete(v) {
|
||||
|
|
|
@ -4,6 +4,9 @@ const _buttons = [];
|
|||
|
||||
const alwaysTrue = () => true;
|
||||
|
||||
function identity() {
|
||||
}
|
||||
|
||||
function addBulkButton(action, key, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
|
@ -72,7 +75,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
|||
this.perform(operation).then(topics => {
|
||||
if (topics) {
|
||||
topics.forEach(cb);
|
||||
(this.get('refreshClosure') || Ember.k)();
|
||||
(this.get('refreshClosure') || identity)();
|
||||
this.send('closeModal');
|
||||
}
|
||||
});
|
||||
|
@ -80,7 +83,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
|||
|
||||
performAndRefresh(operation) {
|
||||
return this.perform(operation).then(() => {
|
||||
(this.get('refreshClosure') || Ember.k)();
|
||||
(this.get('refreshClosure') || identity)();
|
||||
this.send('closeModal');
|
||||
});
|
||||
},
|
||||
|
@ -145,7 +148,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
|||
|
||||
this.perform({type: 'change_category', category_id: categoryId}).then(topics => {
|
||||
topics.forEach(t => t.set('category', category));
|
||||
(this.get('refreshClosure') || Ember.k)();
|
||||
(this.get('refreshClosure') || identity)();
|
||||
this.send('closeModal');
|
||||
});
|
||||
},
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
export default {
|
||||
name: "inject-objects",
|
||||
initialize: Ember.K
|
||||
initialize() { }
|
||||
};
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
export default {
|
||||
name: "register-discourse-location",
|
||||
initialize: Ember.K
|
||||
initialize() { }
|
||||
};
|
||||
|
|
|
@ -363,7 +363,7 @@ export default function(options) {
|
|||
|
||||
if (options.key) {
|
||||
if (options.onKeyUp && key !== options.key) {
|
||||
var match = options.onKeyUp(me.val(), cp);
|
||||
let match = options.onKeyUp(me.val(), cp);
|
||||
if (match) {
|
||||
completeStart = cp - match[0].length;
|
||||
completeEnd = completeStart + match[0].length - 1;
|
||||
|
|
|
@ -701,7 +701,6 @@ const groups = [
|
|||
"rotating_light",
|
||||
"taxi",
|
||||
"oncoming_taxi",
|
||||
"automobile",
|
||||
"oncoming_automobile",
|
||||
"blue_car",
|
||||
"truck",
|
||||
|
|
|
@ -56,7 +56,7 @@ export default Ember.Object.extend(Ember.Array, {
|
|||
},
|
||||
|
||||
finishedPrepending(postIds) {
|
||||
this._changeArray(Ember.K, 0, 0, postIds.length);
|
||||
this._changeArray(function() { }, 0, 0, postIds.length);
|
||||
},
|
||||
|
||||
objectAt(index) {
|
||||
|
|
|
@ -185,8 +185,8 @@ export function validateUploadedFile(file, opts) {
|
|||
if (!name) { return false; }
|
||||
|
||||
// check that the uploaded file is authorized
|
||||
if (Discourse.SiteSettings.allow_staff_to_upload_any_file_in_pm) {
|
||||
if (opts["isPrivateMessage"] && Discourse.User.current("staff")) {
|
||||
if (opts["allowStaffToUploadAnyFileInPm"] && opts["isPrivateMessage"]) {
|
||||
if (Discourse.User.current("staff")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ const RestModel = Ember.Object.extend({
|
|||
isCreated: Ember.computed.equal('__state', 'created'),
|
||||
isSaving: false,
|
||||
|
||||
afterUpdate: Ember.K,
|
||||
afterUpdate() { },
|
||||
|
||||
update(props) {
|
||||
if (this.get('isSaving')) { return Ember.RSVP.reject(); }
|
||||
|
|
|
@ -220,7 +220,7 @@ module ApplicationHelper
|
|||
|
||||
def gsub_emoji_to_unicode(str)
|
||||
if str
|
||||
str.gsub(/:([\w\-+]*):/) { |name| Emoji.lookup_unicode($1) || name }
|
||||
str.gsub(/:([\w\-+]*(?::t\d)?):/) { |name| Emoji.lookup_unicode($1) || name }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ class Emoji
|
|||
# update this to clear the cache
|
||||
EMOJI_VERSION = "v5"
|
||||
|
||||
FITZPATRICK_SCALE ||= [ "1f3fb", "1f3fc", "1f3fd", "1f3fe", "1f3ff" ]
|
||||
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_reader :path
|
||||
|
@ -147,8 +149,17 @@ class Emoji
|
|||
|
||||
db['emojis'].each do |e|
|
||||
next if e['name'] == 'tm'
|
||||
|
||||
code = replacement_code(e['code'])
|
||||
map[e['name']] = code if code
|
||||
next unless code
|
||||
|
||||
map[e['name']] = code
|
||||
if Emoji.tonable_emojis.include?(e['name'])
|
||||
FITZPATRICK_SCALE.each_with_index do |scale, index|
|
||||
toned_code = (code.codepoints.insert(1, scale.to_i(16))).pack("U*")
|
||||
map["#{e['name']}:t#{index+2}"] = toned_code
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Emoji.aliases.each do |key, alias_names|
|
||||
|
|
|
@ -719,6 +719,21 @@ SQL
|
|||
# ensure all the notifications are out
|
||||
PostAlerter.new.after_save_post(last_post)
|
||||
add_small_action(user, "invited_group", group.name)
|
||||
|
||||
group.users.where(
|
||||
"group_users.notification_level > ?", NotificationLevels.all[:muted]
|
||||
).find_each do |u|
|
||||
|
||||
u.notifications.create!(
|
||||
notification_type: Notification.types[:invited_to_private_message],
|
||||
topic_id: self.id,
|
||||
post_number: 1,
|
||||
data: {
|
||||
topic_title: self.title,
|
||||
display_username: user.username
|
||||
}.to_json
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
|
|
|
@ -55,11 +55,11 @@ module BackupRestore
|
|||
begin
|
||||
notify_user
|
||||
remove_old
|
||||
clean_up
|
||||
rescue => ex
|
||||
Rails.logger.error("#{ex}\n" + ex.backtrace.join("\n"))
|
||||
end
|
||||
|
||||
clean_up
|
||||
@success ? log("[SUCCESS]") : log("[FAILED]")
|
||||
end
|
||||
|
||||
|
@ -259,9 +259,15 @@ module BackupRestore
|
|||
log "Notifying '#{@user.username}' of the end of the backup..."
|
||||
status = @success ? :backup_succeeded : :backup_failed
|
||||
|
||||
SystemMessage.create_from_system_user(@user, status,
|
||||
post = SystemMessage.create_from_system_user(@user, status,
|
||||
logs: Discourse::Utils.pretty_logs(@logs)
|
||||
)
|
||||
|
||||
if @user.id == Discourse::SYSTEM_USER_ID
|
||||
post.topic.invite_group(@user, Group[:admins])
|
||||
end
|
||||
|
||||
post
|
||||
end
|
||||
|
||||
def clean_up
|
||||
|
|
|
@ -5782,6 +5782,8 @@
|
|||
"male_detective",
|
||||
"woman_health_worker",
|
||||
"man_health_worker",
|
||||
"woman_cook",
|
||||
"man_cook",
|
||||
"woman_pilot",
|
||||
"man_pilot",
|
||||
"woman_judge",
|
||||
|
@ -6450,8 +6452,9 @@
|
|||
"new_moon": [
|
||||
"moon"
|
||||
],
|
||||
"automobile": [
|
||||
"car"
|
||||
"oncoming_automobile": [
|
||||
"car",
|
||||
"automobile"
|
||||
],
|
||||
"fleur_de_lis": [
|
||||
"fleur-de-lis"
|
||||
|
|
|
@ -208,7 +208,7 @@ EMOJI_ALIASES ||= {
|
|||
"tipping_hand_woman" => [ "information_desk_person" ],
|
||||
"rowing_man" => [ "rowboat" ],
|
||||
"new_moon" => [ "moon" ],
|
||||
"automobile" => [ "car" ],
|
||||
"oncoming_automobile" => [ "car", "automobile" ],
|
||||
"fleur_de_lis" => [ "fleur-de-lis" ],
|
||||
}
|
||||
|
||||
|
@ -912,7 +912,6 @@ EMOJI_GROUPS ||= [
|
|||
"rotating_light",
|
||||
"taxi",
|
||||
"oncoming_taxi",
|
||||
"automobile",
|
||||
"oncoming_automobile",
|
||||
"blue_car",
|
||||
"truck",
|
||||
|
@ -1727,6 +1726,8 @@ VARIATION_SELECTOR ||= "fe0f"
|
|||
|
||||
# Patch content of EMOJI_KEYWORDS_URL
|
||||
EMOJI_KEYWORDS_PATCH ||= {
|
||||
"woman_cook" => { "fitzpatrick_scale" => true },
|
||||
"man_cook" => { "fitzpatrick_scale" => true },
|
||||
"thumbsup" => { "char" => "👍", "fitzpatrick_scale" => true },
|
||||
"thumbsdown" => { "char" => "👎", "fitzpatrick_scale" => true },
|
||||
"asterisk" => { "char" => "*️⃣" },
|
||||
|
|
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 791 B |
After Width: | Height: | Size: 791 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 568 B |
After Width: | Height: | Size: 568 B |
After Width: | Height: | Size: 858 B |
After Width: | Height: | Size: 896 B |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 830 B |
After Width: | Height: | Size: 806 B |
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 815 B |
After Width: | Height: | Size: 753 B |
After Width: | Height: | Size: 729 B |
After Width: | Height: | Size: 700 B |
|
@ -28,4 +28,18 @@ describe Emoji do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.lookup_unicode' do
|
||||
it 'should return the emoji' do
|
||||
expect(Emoji.lookup_unicode("blonde_man")).to eq("👱")
|
||||
end
|
||||
|
||||
it 'should return an aliased emoji' do
|
||||
expect(Emoji.lookup_unicode("anger_right")).to eq("🗯")
|
||||
end
|
||||
|
||||
it 'should return a skin toned emoji' do
|
||||
expect(Emoji.lookup_unicode("blonde_woman:t6")).to eq("👱🏿♀️")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -439,22 +439,42 @@ describe Topic do
|
|||
let(:walter) { Fabricate(:walter_white) }
|
||||
|
||||
context 'by group name' do
|
||||
let(:group) { Fabricate(:group) }
|
||||
|
||||
it 'can add admin to allowed groups' do
|
||||
admins = Group[:admins]
|
||||
admins.alias_level = Group::ALIAS_LEVELS[:everyone]
|
||||
admins.save
|
||||
admins.update!(alias_level: Group::ALIAS_LEVELS[:everyone])
|
||||
|
||||
expect(topic.invite_group(topic.user, admins)).to eq(true)
|
||||
|
||||
expect(topic.allowed_groups.include?(admins)).to eq(true)
|
||||
|
||||
expect(topic.remove_allowed_group(topic.user, 'admins')).to eq(true)
|
||||
topic.reload
|
||||
|
||||
expect(topic.allowed_groups.include?(admins)).to eq(false)
|
||||
end
|
||||
|
||||
it 'creates a notification for each user in the group' do
|
||||
user = Fabricate(:user)
|
||||
user_2 = Fabricate(:user)
|
||||
Fabricate(:post, topic: topic)
|
||||
|
||||
group.add(user)
|
||||
group.add(user_2)
|
||||
|
||||
group.group_users.find_by(user: user_2).update!(
|
||||
notification_level: NotificationLevels.all[:muted]
|
||||
)
|
||||
|
||||
expect { topic.invite_group(topic.user, group) }
|
||||
.to change { Notification.count }.by(1)
|
||||
|
||||
notification = Notification.last
|
||||
|
||||
expect(notification.user).to eq(user)
|
||||
expect(notification.topic).to eq(topic)
|
||||
|
||||
expect(notification.notification_type)
|
||||
.to eq(Notification.types[:invited_to_private_message])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'by username' do
|
||||
|
|
|
@ -45,7 +45,7 @@ function acceptance(name, options) {
|
|||
resetMobile();
|
||||
|
||||
// For now don't do scrolling stuff in Test Mode
|
||||
HeaderComponent.reopen({examineDockHeader: Ember.K});
|
||||
HeaderComponent.reopen({examineDockHeader: function() { }});
|
||||
|
||||
resetExtraClasses();
|
||||
const siteJson = siteFixtures['site.json'].site;
|
||||
|
|
|
@ -73,14 +73,12 @@ test("ensures an authorized upload", function() {
|
|||
test("staff can upload anything in PM", function() {
|
||||
const files = [{ name: "some.docx" }];
|
||||
Discourse.SiteSettings.authorized_extensions = "jpeg";
|
||||
Discourse.SiteSettings.allow_staff_to_upload_any_file_in_pm = true;
|
||||
|
||||
Discourse.User.resetCurrent(Discourse.User.create({ moderator: true }));
|
||||
|
||||
sandbox.stub(bootbox, "alert");
|
||||
|
||||
not(validUpload(files));
|
||||
ok(validUpload(files, { isPrivateMessage: true }));
|
||||
ok(validUpload(files, { isPrivateMessage: true, allowStaffToUploadAnyFileInPm: true }));
|
||||
});
|
||||
|
||||
var imageSize = 10 * 1024;
|
||||
|
|
|
@ -108,7 +108,7 @@ QUnit.testStart(function(ctx) {
|
|||
window.sandbox.stub(ScrollingDOMMethods, "unbindOnScroll");
|
||||
|
||||
// Unless we ever need to test this, let's leave it off.
|
||||
$.fn.autocomplete = Ember.K;
|
||||
$.fn.autocomplete = function() { };
|
||||
|
||||
// Don't debounce in test unless we're testing debouncing
|
||||
if (ctx.module.indexOf('debounce') === -1) {
|
||||
|
|