diff --git a/packages/rocketchat-custom-sounds/admin/adminSounds.html b/packages/rocketchat-custom-sounds/admin/adminSounds.html index bcf0f377496fd4132faeca32f102c3906a675919..c891ff724e64ae23b2d21e70772182346dc48265 100644 --- a/packages/rocketchat-custom-sounds/admin/adminSounds.html +++ b/packages/rocketchat-custom-sounds/admin/adminSounds.html @@ -22,15 +22,13 @@ <table> <thead> <tr> - <th>{{_ "Name"}}</th> - <th>{{_ "Play"}}</th> + <th width="100%">{{_ "Name"}}</th> </tr> </thead> <tbody> {{#each customsounds}} <tr class="sound-info row-link"> - <td>{{name}}</td> - <td><i class="icon-play-circle"></i></td> + <td>{{name}} <i class="icon-play-circled"></i></td> </tr> {{/each}} </tbody> diff --git a/packages/rocketchat-custom-sounds/admin/adminSounds.js b/packages/rocketchat-custom-sounds/admin/adminSounds.js index 67c6921e68bb78aad96feb80c5e6fd1209d170c5..32d7bb7a118eddb5feb3837e0c5a45c9b2e68313 100644 --- a/packages/rocketchat-custom-sounds/admin/adminSounds.js +++ b/packages/rocketchat-custom-sounds/admin/adminSounds.js @@ -43,7 +43,7 @@ Template.adminSounds.onCreated(function() { id: 'add-sound', i18nTitle: 'Custom_Sound_Add', icon: 'icon-plus', - template: 'adminSoundsEdit', + template: 'adminSoundEdit', openClick(/*e, t*/) { RocketChat.TabBar.setData(); return true; @@ -56,7 +56,7 @@ Template.adminSounds.onCreated(function() { id: 'admin-sound-info', i18nTitle: 'Custom_Sound_Info', icon: 'icon-cog', - template: 'adminSoundsInfo', + template: 'adminSoundInfo', order: 2 }); @@ -73,7 +73,7 @@ Template.adminSounds.onCreated(function() { if (filter) { let filterReg = new RegExp(s.escapeRegExp(filter), 'i'); - query = { $or: [ { name: filterReg }, {aliases: filterReg } ] }; + query = { name: filterReg }; } let limit = (isSetNotNull(() => instance.limit))? instance.limit.get() : 0; @@ -106,8 +106,8 @@ Template.adminSounds.events({ ['click .sound-info'](e) { e.preventDefault(); - RocketChat.TabBar.setTemplate('adminSoundsInfo'); - RocketChat.TabBar.setData(RocketChat.models.CustomSound.findOne({_id: this._id})); + RocketChat.TabBar.setTemplate('adminSoundInfo'); + RocketChat.TabBar.setData(RocketChat.models.CustomSounds.findOne({_id: this._id})); RocketChat.TabBar.openFlex(); RocketChat.TabBar.showGroup('adminSounds-selected'); }, @@ -116,5 +116,14 @@ Template.adminSounds.events({ e.preventDefault(); e.stopPropagation(); t.limit.set(t.limit.get() + 50); + }, + + ['click .icon-play-circled'](e) { + e.preventDefault(); + e.stopPropagation(); + const $audio = $('#' + this._id); + if ($audio && $audio[0] && $audio[0].play) { + $audio[0].play(); + } } }); diff --git a/packages/rocketchat-custom-sounds/admin/soundEdit.html b/packages/rocketchat-custom-sounds/admin/soundEdit.html index b5e96922848d757264b1b91a1fe0b6dcc2179448..81b24b6fecc8931dea89140b18c7ce2598825ed8 100644 --- a/packages/rocketchat-custom-sounds/admin/soundEdit.html +++ b/packages/rocketchat-custom-sounds/admin/soundEdit.html @@ -12,7 +12,7 @@ <input type="text" id="name" autocomplete="off" value="{{sound.name}}"> </div> <div class="input-line"> - <label for="image">{{_ "Sound_File"}}</label> + <label for="image">{{_ "Sound_File_mp3"}}</label> <input id="image" type="file" /> </div> <nav> diff --git a/packages/rocketchat-custom-sounds/admin/soundEdit.js b/packages/rocketchat-custom-sounds/admin/soundEdit.js index 038f48b1d78e0d908b994e519ffc54db11fc594b..9a7ee93d5faa279d3d74a738d9119f96ad187883 100644 --- a/packages/rocketchat-custom-sounds/admin/soundEdit.js +++ b/packages/rocketchat-custom-sounds/admin/soundEdit.js @@ -83,7 +83,7 @@ Template.soundEdit.onCreated(function() { if (!soundData._id) { if (!this.soundFile) { - errors.push('Sound_File'); + errors.push('Sound_File_mp3'); } } @@ -92,7 +92,7 @@ Template.soundEdit.onCreated(function() { } if (this.soundFile) { - if (!/audio\/mpeg/.test(this.soundFile.type)) { + if (!/audio\/mp3/.test(this.soundFile.type)) { errors.push('FileType'); toastr.error(TAPi18n.__('error-invalid-file-type')); } @@ -108,44 +108,42 @@ Template.soundEdit.onCreated(function() { if (this.soundFile) { soundData.newFile = true; soundData.extension = this.soundFile.name.split('.').pop(); + soundData.type = this.soundFile.type; } - console.log('save -> ', soundData); - - // Meteor.call('insertOrUpdateSound', soundData, (error, result) => { - // if (result) { - // if (this.soundFile) { - // toastr.info(TAPi18n.__('Uploading_file')); - - // let reader = new FileReader(); - // reader.readAsBinaryString(this.soundFile); - // reader.onloadend = () => { - // Meteor.call('uploadSoundCustom', reader.result, this.soundFile.type, soundData, (uploadError/*, data*/) => { - // if (uploadError != null) { - // handleError(uploadError); - // console.log(uploadError); - // return; - // } - // } - // ); - // delete this.soundFile; - // toastr.success(TAPi18n.__('File_uploaded')); - // }; - // } - - // if (soundData._id) { - // toastr.success(t('Custom_Sound_Updated_Successfully')); - // } else { - // toastr.success(t('Custom_Sound_Added_Successfully')); - // } - - // this.cancel(form, soundData.name); - // } - - // if (error) { - // handleError(error); - // } - // }); + Meteor.call('insertOrUpdateSound', soundData, (error, result) => { + if (result) { + soundData._id = result; + soundData.random = Math.round(Math.random() * 1000); + + if (this.soundFile) { + toastr.info(TAPi18n.__('Uploading_file')); + + let reader = new FileReader(); + reader.readAsBinaryString(this.soundFile); + reader.onloadend = () => { + Meteor.call('uploadCustomSound', reader.result, this.soundFile.type, soundData, (uploadError/*, data*/) => { + if (uploadError != null) { + handleError(uploadError); + console.log(uploadError); + return; + } + } + ); + delete this.soundFile; + toastr.success(TAPi18n.__('File_uploaded')); + }; + } + + toastr.success(t('Custom_Sound_Saved_Successfully')); + + this.cancel(form, soundData.name); + } + + if (error) { + handleError(error); + } + }); } }; }); diff --git a/packages/rocketchat-custom-sounds/admin/soundInfo.html b/packages/rocketchat-custom-sounds/admin/soundInfo.html new file mode 100644 index 0000000000000000000000000000000000000000..09374f00609a9d270b645d4ed743fb1a8f941ec1 --- /dev/null +++ b/packages/rocketchat-custom-sounds/admin/soundInfo.html @@ -0,0 +1,19 @@ +<template name="soundInfo"> + {{#if editingSound}} + {{> soundEdit (soundToEdit)}} + {{else}} + {{#with sound}} + <div class="about clearfix"> + <div class="info"> + <h3 title="{{name}}">{{name}}</h3> + </div> + </div> + {{/with}} + <nav> + {{#if hasPermission 'manage-sounds'}} + <button class='button button-block danger delete'><span><i class='icon-trash'></i> {{_ "Delete"}}</span></button> + <button class='button button-block primary edit-sound'><span><i class='icon-edit'></i> {{_ "Edit"}}</span></button> + {{/if}} + </nav> + {{/if}} +</template> diff --git a/packages/rocketchat-custom-sounds/admin/soundInfo.js b/packages/rocketchat-custom-sounds/admin/soundInfo.js new file mode 100644 index 0000000000000000000000000000000000000000..f0f28e42892eee1b5a8ce8539fdae3750617be2d --- /dev/null +++ b/packages/rocketchat-custom-sounds/admin/soundInfo.js @@ -0,0 +1,111 @@ +/* globals isSetNotNull */ +Template.soundInfo.helpers({ + name() { + let sound = Template.instance().sound.get(); + return sound.name; + }, + + sound() { + return Template.instance().sound.get(); + }, + + editingSound() { + return Template.instance().editingSound.get(); + }, + + soundToEdit() { + let instance = Template.instance(); + return { + sound: instance.sound.get(), + back(name) { + instance.editingSound.set(); + + if (isSetNotNull(() => name)) { + let sound = instance.sound.get(); + if (isSetNotNull(() => sound.name) && sound.name !== name) { + return instance.loadedName.set(name); + } + } + } + }; + } +}); + +Template.soundInfo.events({ + ['click .delete'](e, instance) { + e.stopPropagation(); + e.preventDefault(); + let sound = instance.sound.get(); + if (isSetNotNull(() => sound)) { + let _id = sound._id; + swal({ + title: t('Are_you_sure'), + text: t('Custom_Sound_Delete_Warning'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes_delete_it'), + cancelButtonText: t('Cancel'), + closeOnConfirm: false, + html: false + }, function() { + swal.disableButtons(); + + Meteor.call('deleteCustomSound', _id, (error/*, result*/) => { + if (error) { + handleError(error); + swal.enableButtons(); + } else { + swal({ + title: t('Deleted'), + text: t('Custom_Sound_Has_Been_Deleted'), + type: 'success', + timer: 2000, + showConfirmButton: false + }); + + RocketChat.TabBar.showGroup('adminSounds'); + RocketChat.TabBar.closeFlex(); + } + }); + }); + } + }, + + ['click .edit-sound'](e, instance) { + e.stopPropagation(); + e.preventDefault(); + + instance.editingSound.set(instance.sound.get()._id); + } +}); + +Template.soundInfo.onCreated(function() { + this.sound = new ReactiveVar(); + + this.editingSound = new ReactiveVar(); + + this.loadedName = new ReactiveVar(); + + this.autorun(() => { + let data = Template.currentData(); + if (isSetNotNull(() => data.clear)) { + this.clear = data.clear; + } + }); + + this.autorun(() => { + let data = Template.currentData(); + let sound = this.sound.get(); + if (isSetNotNull(() => sound.name)) { + this.loadedName.set(sound.name); + } else if (isSetNotNull(() => data.name)) { + this.loadedName.set(data.name); + } + }); + + this.autorun(() => { + let data = Template.currentData(); + this.sound.set(data); + }); +}); diff --git a/packages/rocketchat-custom-sounds/assets/stylesheets/customSoundsAdmin.less b/packages/rocketchat-custom-sounds/assets/stylesheets/customSoundsAdmin.less new file mode 100644 index 0000000000000000000000000000000000000000..4845388adc8aa2a3625ac61b209c357ab737c54f --- /dev/null +++ b/packages/rocketchat-custom-sounds/assets/stylesheets/customSoundsAdmin.less @@ -0,0 +1,102 @@ +.sound-info { + .icon-play-circled { + cursor: pointer; + } +} + +.sound-view { + z-index: 15; + overflow-y: auto; + overflow-x: hidden; + + .thumb { + width: 100%; + height: 350px; + padding: 20px; + } + + nav { + padding: 0 20px; + } + + .info { + white-space: normal; + padding: 0 20px; + + h3 { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + font-size: 24px; + margin: 8px 0; + line-height: 27px; + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + white-space: nowrap; + + i::after { + content: " "; + display: inline-block; + width: 8px; + height: 8px; + border-radius: 4px; + vertical-align: middle; + } + } + + p { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + line-height: 18px; + font-size: 12px; + font-weight: 300; + } + } + + .edit-form { + padding: 20px 20px 0; + white-space: normal; + + h3 { + font-size: 24px; + margin-bottom: 8px; + line-height: 22px; + } + + p { + line-height: 18px; + font-size: 12px; + font-weight: 300; + } + + > .input-line { + margin-top: 20px; + } + + nav { + padding: 0; + + &.buttons { + margin-top: 2em; + } + } + + .form-divisor { + text-align: center; + margin: 2em 0; + height: 9px; + + > span { + padding: 0 1em; + } + } + } + + .room-info-content > div { + margin: 0 0 20px; + } +} diff --git a/packages/rocketchat-custom-sounds/client/lib/CustomSounds.js b/packages/rocketchat-custom-sounds/client/lib/CustomSounds.js new file mode 100644 index 0000000000000000000000000000000000000000..4d2afb3ad9add1e1bc76179491c6917ac74af394 --- /dev/null +++ b/packages/rocketchat-custom-sounds/client/lib/CustomSounds.js @@ -0,0 +1,56 @@ +/* globals isSetNotNull */ +class CustomSounds { + constructor() { + this.list = new ReactiveVar({}); + } + + add(sound) { + sound.src = this.getURL(sound); + const audio = $('<audio />', { id: sound._id, preload: true }).append( + $('<source />', { src: sound.src }) + ); + const list = this.list.get(); + list[sound._id] = sound; + this.list.set(list); + $('body').append(audio); + } + + remove(sound) { + const list = this.list.get(); + delete this.list[sound._id]; + this.list.set(list); + $('#' + sound._id).remove(); + } + + update(sound) { + const audio = $(`#${sound._id}`); + if (audio && audio[0]) { + const list = this.list.get(); + list[sound._id] = sound; + this.list.set(list); + $('source', audio).attr('src', this.getURL(sound)); + audio[0].load(); + } else { + this.add(sound); + } + } + + getURL(sound) { + let path = (Meteor.isCordova) ? Meteor.absoluteUrl().replace(/\/$/, '') : __meteor_runtime_config__.ROOT_URL_PATH_PREFIX || ''; + return `${path}/custom-sounds/${sound._id}.${sound.extension}?_dc=${sound.random || 0}`; + } + + getList() { + return Object.values(this.list.get()); + } +} + +RocketChat.CustomSounds = new CustomSounds; + +Meteor.startup(() => + Meteor.call('listCustomSounds', (error, result) => { + for (let sound of result) { + RocketChat.CustomSounds.add(sound); + } + }) +); diff --git a/packages/rocketchat-custom-sounds/client/lib/custom-sounds.js b/packages/rocketchat-custom-sounds/client/lib/custom-sounds.js deleted file mode 100644 index 2273ffea5b21696d28f0b63f1a4e5f01dd5360a9..0000000000000000000000000000000000000000 --- a/packages/rocketchat-custom-sounds/client/lib/custom-sounds.js +++ /dev/null @@ -1,3 +0,0 @@ -RocketChat.sounds = { - list: [] -}; diff --git a/packages/rocketchat-custom-sounds/client/notifications/deleteCustomSound.js b/packages/rocketchat-custom-sounds/client/notifications/deleteCustomSound.js new file mode 100644 index 0000000000000000000000000000000000000000..81323dabc76075d31d56db88279bb8eee88e2a34 --- /dev/null +++ b/packages/rocketchat-custom-sounds/client/notifications/deleteCustomSound.js @@ -0,0 +1,3 @@ +Meteor.startup(() => + RocketChat.Notifications.onAll('deleteCustomSound', data => RocketChat.CustomSounds.remove(data.soundData)) +); diff --git a/packages/rocketchat-custom-sounds/client/notifications/updateCustomSound.js b/packages/rocketchat-custom-sounds/client/notifications/updateCustomSound.js new file mode 100644 index 0000000000000000000000000000000000000000..73b16ae4aa96d0814f28f4def14ee50e61b12935 --- /dev/null +++ b/packages/rocketchat-custom-sounds/client/notifications/updateCustomSound.js @@ -0,0 +1,3 @@ +Meteor.startup(() => + RocketChat.Notifications.onAll('updateCustomSound', data => RocketChat.CustomSounds.update(data.soundData)) +); diff --git a/packages/rocketchat-custom-sounds/package.js b/packages/rocketchat-custom-sounds/package.js index b81cf338dcedc4e1e025a9ef8a380883ea7c908e..37fb34df9c841d391550c58f47bd2b6efe09c1b5 100644 --- a/packages/rocketchat-custom-sounds/package.js +++ b/packages/rocketchat-custom-sounds/package.js @@ -12,6 +12,7 @@ Package.onUse(function(api) { 'rocketchat:file', 'rocketchat:lib', 'templating', + 'reactive-var', 'underscore', 'webapp' ]); @@ -27,6 +28,15 @@ Package.onUse(function(api) { api.addFiles('server/models/CustomSounds.js', 'server'); api.addFiles('server/publications/customSounds.js', 'server'); + api.addFiles([ + 'server/methods/deleteCustomSound.js', + 'server/methods/insertOrUpdateSound.js', + 'server/methods/listCustomSounds.js', + 'server/methods/uploadCustomSound.js' + ], 'server'); + + api.addFiles('assets/stylesheets/customSoundsAdmin.less', 'client'); + api.addFiles('admin/startup.js', 'client'); api.addFiles('admin/adminSounds.html', 'client'); api.addFiles('admin/adminSounds.js', 'client'); @@ -34,8 +44,12 @@ Package.onUse(function(api) { api.addFiles('admin/adminSoundInfo.html', 'client'); api.addFiles('admin/soundEdit.html', 'client'); api.addFiles('admin/soundEdit.js', 'client'); + api.addFiles('admin/soundInfo.html', 'client'); + api.addFiles('admin/soundInfo.js', 'client'); api.addFiles('admin/route.js', 'client'); - api.addFiles('client/lib/custom-sounds.js', 'client'); + api.addFiles('client/lib/CustomSounds.js', 'client'); api.addFiles('client/models/CustomSounds.js', 'client'); + api.addFiles('client/notifications/updateCustomSound.js', 'client'); + api.addFiles('client/notifications/deleteCustomSound.js', 'client'); }); diff --git a/packages/rocketchat-custom-sounds/server/methods/deleteCustomSound.js b/packages/rocketchat-custom-sounds/server/methods/deleteCustomSound.js new file mode 100644 index 0000000000000000000000000000000000000000..b63c7d03857a4b6021ded656d879b51679273d04 --- /dev/null +++ b/packages/rocketchat-custom-sounds/server/methods/deleteCustomSound.js @@ -0,0 +1,22 @@ +/* globals isSetNotNull, RocketChatFileCustomSoundsInstance */ +Meteor.methods({ + deleteCustomSound(_id) { + let sound = null; + + if (RocketChat.authz.hasPermission(this.userId, 'manage-sounds')) { + sound = RocketChat.models.CustomSounds.findOneByID(_id); + } else { + throw new Meteor.Error('not_authorized'); + } + + if (!isSetNotNull(() => sound)) { + throw new Meteor.Error('Custom_Sound_Error_Invalid_Sound', 'Invalid sound', { method: 'deleteCustomSound' }); + } + + RocketChatFileCustomSoundsInstance.deleteFile(`${sound._id}.${sound.extension}`); + RocketChat.models.CustomSounds.removeByID(_id); + RocketChat.Notifications.notifyAll('deleteCustomSound', {soundData: sound}); + + return true; + } +}); diff --git a/packages/rocketchat-custom-sounds/server/methods/insertOrUpdateSound.js b/packages/rocketchat-custom-sounds/server/methods/insertOrUpdateSound.js new file mode 100644 index 0000000000000000000000000000000000000000..845bda2cec78961bb2de1815b702dc8fb2738120 --- /dev/null +++ b/packages/rocketchat-custom-sounds/server/methods/insertOrUpdateSound.js @@ -0,0 +1,62 @@ +/* globals RocketChatFileCustomSoundsInstance */ +Meteor.methods({ + insertOrUpdateSound(soundData) { + if (!RocketChat.authz.hasPermission(this.userId, 'manage-sounds')) { + throw new Meteor.Error('not_authorized'); + } + + if (!s.trim(soundData.name)) { + throw new Meteor.Error('error-the-field-is-required', 'The field Name is required', { method: 'insertOrUpdateSound', field: 'Name' }); + } + + //let nameValidation = new RegExp('^[0-9a-zA-Z-_+;.]+$'); + + //allow all characters except colon, whitespace, comma, >, <, &, ", ', /, \, (, ) + //more practical than allowing specific sets of characters; also allows foreign languages + let nameValidation = /[\s,:><&"'\/\\\(\)]/; + + //silently strip colon; this allows for uploading :soundname: as soundname + soundData.name = soundData.name.replace(/:/g, ''); + + if (nameValidation.test(soundData.name)) { + throw new Meteor.Error('error-input-is-not-a-valid-field', `${soundData.name} is not a valid name`, { method: 'insertOrUpdateSound', input: soundData.name, field: 'Name' }); + } + + let matchingResults = []; + + if (soundData._id) { + matchingResults = RocketChat.models.CustomSounds.findByNameExceptID(soundData.name, soundData._id).fetch(); + } else { + matchingResults = RocketChat.models.CustomSounds.findByName(soundData.name).fetch(); + } + + if (matchingResults.length > 0) { + throw new Meteor.Error('Custom_Sound_Error_Name_Already_In_Use', 'The custom sound name is already in use', { method: 'insertOrUpdateSound' }); + } + + if (!soundData._id) { + //insert sound + let createSound = { + name: soundData.name, + extension: soundData.extension + }; + + let _id = RocketChat.models.CustomSounds.create(createSound); + createSound._id = _id; + + return _id; + } else { + //update sound + if (soundData.newFile) { + RocketChatFileCustomSoundsInstance.deleteFile(`${soundData._id}.${soundData.previousExtension}`); + } + + if (soundData.name !== soundData.previousName) { + RocketChat.models.CustomSounds.setName(soundData._id, soundData.name); + RocketChat.Notifications.notifyAll('updateCustomSound', {soundData}); + } + + return soundData._id; + } + } +}); diff --git a/packages/rocketchat-custom-sounds/server/methods/listCustomSounds.js b/packages/rocketchat-custom-sounds/server/methods/listCustomSounds.js new file mode 100644 index 0000000000000000000000000000000000000000..e16afd389f97eb891f2a7eda41c9cb7654fbcf07 --- /dev/null +++ b/packages/rocketchat-custom-sounds/server/methods/listCustomSounds.js @@ -0,0 +1,5 @@ +Meteor.methods({ + listCustomSounds() { + return RocketChat.models.CustomSounds.find({}).fetch(); + } +}); diff --git a/packages/rocketchat-custom-sounds/server/methods/uploadCustomSound.js b/packages/rocketchat-custom-sounds/server/methods/uploadCustomSound.js new file mode 100644 index 0000000000000000000000000000000000000000..9929871559afd134b375c9089c14d58147f24117 --- /dev/null +++ b/packages/rocketchat-custom-sounds/server/methods/uploadCustomSound.js @@ -0,0 +1,20 @@ +/* globals RocketChatFileCustomSoundsInstance */ +Meteor.methods({ + uploadCustomSound(binaryContent, contentType, soundData) { + if (!RocketChat.authz.hasPermission(this.userId, 'manage-sounds')) { + throw new Meteor.Error('not_authorized'); + } + + let file = new Buffer(binaryContent, 'binary'); + + let rs = RocketChatFile.bufferToStream(file); + RocketChatFileCustomSoundsInstance.deleteFile(`${soundData._id}.${soundData.extension}`); + let ws = RocketChatFileCustomSoundsInstance.createWriteStream(`${soundData._id}.${soundData.extension}`, contentType); + ws.on('end', Meteor.bindEnvironment(() => + Meteor.setTimeout(() => RocketChat.Notifications.notifyAll('updateCustomSound', {soundData}) + , 500) + )); + + rs.pipe(ws); + } +}); diff --git a/packages/rocketchat-custom-sounds/server/models/CustomSounds.js b/packages/rocketchat-custom-sounds/server/models/CustomSounds.js index e205072abcac15cfda04bf833d17fd0e8c8225de..45f742ce5ac2d8f0f597b15fa826e3378d024d3c 100644 --- a/packages/rocketchat-custom-sounds/server/models/CustomSounds.js +++ b/packages/rocketchat-custom-sounds/server/models/CustomSounds.js @@ -19,6 +19,15 @@ class CustomSounds extends RocketChat.models._Base { return this.find(query, options); } + findByNameExceptID(name, except, options) { + let query = { + _id: { $nin: [ except ] }, + name + }; + + return this.find(query, options); + } + //update setName(_id, name) { let update = { diff --git a/packages/rocketchat-custom-sounds/server/publications/customSounds.js b/packages/rocketchat-custom-sounds/server/publications/customSounds.js index 8b105fe1227737dfdd2fc3fb71b33c053e0cab2d..03032018d73a49089de2bbf78a49557b7ceb39bf 100644 --- a/packages/rocketchat-custom-sounds/server/publications/customSounds.js +++ b/packages/rocketchat-custom-sounds/server/publications/customSounds.js @@ -4,7 +4,8 @@ Meteor.publish('customSounds', function(filter, limit) { } let fields = { - name: 1 + name: 1, + extension: 1 }; filter = s.trim(filter); diff --git a/packages/rocketchat-custom-sounds/server/startup/custom-sounds.js b/packages/rocketchat-custom-sounds/server/startup/custom-sounds.js index 502f8bc87123be2fc6a33ff71ea32bc4d4981971..0f8c10a524052c3c3599eecd6fc0ba0a34ea89e0 100644 --- a/packages/rocketchat-custom-sounds/server/startup/custom-sounds.js +++ b/packages/rocketchat-custom-sounds/server/startup/custom-sounds.js @@ -1,4 +1,4 @@ -/* globals isSetNotNull */ +/* globals isSetNotNull, RocketChatFileCustomSoundsInstance */ Meteor.startup(function() { let storeType = 'GridFS'; @@ -39,41 +39,13 @@ Meteor.startup(function() { return; } - let file = self.RocketChatFileCustomSoundsInstance.getFileWithReadStream(encodeURIComponent(params.sound)); - - res.setHeader('Content-Disposition', 'inline'); - - if (!isSetNotNull(() => file)) { - //use code from username initials renderer until file upload is complete - res.setHeader('Content-Type', 'image/svg+xml'); - res.setHeader('Cache-Control', 'public, max-age=0'); - res.setHeader('Expires', '-1'); - res.setHeader('Last-Modified', 'Thu, 01 Jan 2015 00:00:00 GMT'); - - let reqModifiedHeader = req.headers['if-modified-since']; - if (reqModifiedHeader != null) { - if (reqModifiedHeader === 'Thu, 01 Jan 2015 00:00:00 GMT') { - res.writeHead(304); - res.end(); - return; - } - } - - let color = '#000'; - let initials = '?'; - - let svg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg xmlns="http://www.w3.org/2000/svg" pointer-events="none" width="50" height="50" style="width: 50px; height: 50px; background-color: ${color};"> - <text text-anchor="middle" y="50%" x="50%" dy="0.36em" pointer-events="auto" fill="#ffffff" font-family="Helvetica, Arial, Lucida Grande, sans-serif" style="font-weight: 400; font-size: 28px;"> - ${initials} - </text> -</svg>`; - - res.write(svg); - res.end(); + let file = RocketChatFileCustomSoundsInstance.getFileWithReadStream(params.sound); + if (!file) { return; } + res.setHeader('Content-Disposition', 'inline'); + let fileUploadDate = undefined; if (isSetNotNull(() => file.uploadDate)) { fileUploadDate = file.uploadDate.toUTCString(); diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 0ecf988416ac9eaef29d02c4eddc20200f722ff7..9f849d18d9edcfd1bad29ca1b39bb903ac025186 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -329,14 +329,13 @@ "Custom_Script_Logged_In": "Custom Script for logged in users", "Custom_Script_Logged_Out": "Custom Script for logged out users", "Custom_Sounds": "Custom Sounds", - "Custom_Sounds_Add": "Add Custom Sound", - "Custom_Sounds_Added_Successfully": "Custom sound added successfully", - "Custom_Sounds_Delete_Warning": "Deleting a sound cannot be undone.", - "Custom_Sounds_Error_Invalid_Sound": "Invalid sound", - "Custom_Sounds_Error_Name_Already_In_Use": "The custom sound name is already in use.", - "Custom_Sounds_Has_Been_Deleted": "The custom sound has been deleted.", - "Custom_Sounds_Info": "Custom Sound Info", - "Custom_Sounds_Updated_Successfully": "Custom sound updated successfully", + "Custom_Sound_Add": "Add Custom Sound", + "Custom_Sound_Delete_Warning": "Deleting a sound cannot be undone.", + "Custom_Sound_Error_Invalid_Sound": "Invalid sound", + "Custom_Sound_Error_Name_Already_In_Use": "The custom sound name is already in use.", + "Custom_Sound_Has_Been_Deleted": "The custom sound has been deleted.", + "Custom_Sound_Info": "Custom Sound Info", + "Custom_Sound_Saved_Successfully": "Custom sound saved successfully", "Custom_Translations": "Custom Translations", "Custom_Translations_Description": "Should be a valid JSON where keys are languages containing a dictionary of key and translations. Example:</br><code>{\n\t\"en\": {\n\t\t\"key\": \"translation\"\n\t},\n\t\"pt\": {\n\t\t\"key\": \"tradução\"\n\t}\n}</code> ", "CustomSoundsFilesystem": "Custom Sounds Filesystem", @@ -1245,7 +1244,7 @@ "Snippet_Messages": "Snippet Messages", "Snippeted_a_message": "Created a snippet __snippetLink__", "Sound": "Sound", - "Sound_File": "Sound File", + "Sound_File_mp3": "Sound File (mp3)", "SSL": "SSL", "Star_Message": "Star Message", "Starred_Messages": "Starred Messages", diff --git a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js index 0a5df266957324d04ff1d65bb9589622466e5cad..c553c3a8eaa35b4379377a0ffb6f9610a47c7283 100644 --- a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js +++ b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js @@ -1,9 +1,9 @@ import toastr from 'toastr'; -/* globals ChatSubscription, KonchatNotification */ +/* globals ChatSubscription */ Template.pushNotificationsFlexTab.helpers({ audioAssets() { - return KonchatNotification.audioAssets; + return RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || []; }, audioNotifications() { const sub = ChatSubscription.findOne({ @@ -13,7 +13,7 @@ Template.pushNotificationsFlexTab.helpers({ audioNotifications: 1 } }); - return sub ? sub.audioNotifications : ''; + return sub ? sub.audioNotifications || '' : ''; }, desktopNotifications() { var sub = ChatSubscription.findOne({ @@ -91,7 +91,7 @@ Template.pushNotificationsFlexTab.helpers({ audioNotifications: 1 } }); - const audio = sub ? sub.audioNotifications : ''; + const audio = sub ? sub.audioNotifications || '': ''; if (audio === 'none') { return t('None'); } else if (audio === '') { @@ -99,7 +99,8 @@ Template.pushNotificationsFlexTab.helpers({ } else if (audio === 'chime') { return 'Chime'; } else { - const asset = _.findWhere(KonchatNotification.audioAssets, { _id: audio }); + const audioAssets = RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || []; + const asset = _.findWhere(audioAssets, { _id: audio }); return asset && asset.name; } }, @@ -234,6 +235,14 @@ Template.pushNotificationsFlexTab.events({ if ($audio && $audio[0] && $audio[0].play) { $audio[0].play(); } + } else { + audio = Meteor.user() && Meteor.user().settings && Meteor.user().settings.preferences && Meteor.user().settings.preferences.audioNotifications || 'chime'; + if (audio && audio !== 'none') { + let $audio = $('#' + audio); + if ($audio && $audio[0] && $audio[0].play) { + $audio[0].play(); + } + } } }, diff --git a/packages/rocketchat-ui-account/account/accountPreferences.coffee b/packages/rocketchat-ui-account/account/accountPreferences.coffee index 128f88fa672aa6d6107698faf2d8a8b4433baaa5..ba5a08d1445cfadd698ea7b87517847048f2745c 100644 --- a/packages/rocketchat-ui-account/account/accountPreferences.coffee +++ b/packages/rocketchat-ui-account/account/accountPreferences.coffee @@ -1,7 +1,7 @@ import toastr from 'toastr' Template.accountPreferences.helpers audioAssets: -> - return KonchatNotification.audioAssets + return RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || []; audioNotifications: -> return Meteor.user()?.settings?.preferences?.audioNotifications || 'chime' diff --git a/packages/rocketchat-ui/lib/notification.coffee b/packages/rocketchat-ui/lib/notification.coffee index 75c4d1dd921fc872da81183b0604205addbab0c8..e7b72b46237e07d808d3cd31822fc4b5713829bd 100644 --- a/packages/rocketchat-ui/lib/notification.coffee +++ b/packages/rocketchat-ui/lib/notification.coffee @@ -2,16 +2,6 @@ @KonchatNotification = notificationStatus: new ReactiveVar - audioAssets: [ - { '_id': 'beep', 'name': 'Beep', 'sources': [ { 'src': 'sounds/beep.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'ding', 'name': 'Ding', 'sources': [ { 'src': 'sounds/ding.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'seasons', 'name': 'Seasons', 'sources': [ { 'src': 'sounds/seasons.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'chelle', 'name': 'Chelle', 'sources': [ { 'src': 'sounds/chelle.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'highbell', 'name': 'High Bell', 'sources': [ { 'src': 'sounds/highbell.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'droplet', 'name': 'Droplet', 'sources': [ { 'src': 'sounds/droplet.mp3', 'type': 'audio/mpeg' } ] } - { '_id': 'verbal', 'name': 'Verbal', 'sources': [ { 'src': 'sounds/verbal.mp3', 'type': 'audio/mpeg' } ] } - ] - # notificacoes HTML5 getDesktopPermission: -> if window.Notification && Notification.permission != "granted" && !Meteor.settings.public.sandstorm diff --git a/packages/rocketchat-ui/package.js b/packages/rocketchat-ui/package.js index 90231eaa7646b16d64477ca9b7ec0f5b4dac316b..72f8da9b1a6b0ac3330fdc1c4a5b9493bd66c1f0 100644 --- a/packages/rocketchat-ui/package.js +++ b/packages/rocketchat-ui/package.js @@ -78,7 +78,6 @@ Package.onUse(function(api) { api.addFiles('views/404/roomNotFound.html', 'client'); api.addFiles('views/404/invalidSecretURL.html', 'client'); api.addFiles('views/app/audioNotification.html', 'client'); - api.addFiles('views/app/audioNotification.js', 'client'); api.addFiles('views/app/burger.html', 'client'); api.addFiles('views/app/home.html', 'client'); api.addFiles('views/app/notAuthorized.html', 'client'); diff --git a/packages/rocketchat-ui/views/app/audioNotification.html b/packages/rocketchat-ui/views/app/audioNotification.html index a9f36904ccacf10c2f6195f19279d05c829f728e..ec4106f77561f013157dfed46fdee7b0750ec2ab 100644 --- a/packages/rocketchat-ui/views/app/audioNotification.html +++ b/packages/rocketchat-ui/views/app/audioNotification.html @@ -1,15 +1,10 @@ <template name="audioNotification"> - <audio id="chime" preload> - <source src="sounds/chime.mp3" type="audio/mpeg" /> - </audio> - <audio id="chatNewRoomNotification" preload> - <source src="sounds/door.mp3" type="audio/mpeg" /> - </audio> - {{#each audioAssets}} - <audio id="{{_id}}" preload> - {{#each sources}} - <source src="{{src}}" type="{{type}}" /> - {{/each}} + <div id="audioFilesPreload"> + <audio id="chime" preload> + <source src="sounds/chime.mp3" type="audio/mpeg" /> </audio> - {{/each}} + <audio id="chatNewRoomNotification" preload> + <source src="sounds/door.mp3" type="audio/mpeg" /> + </audio> + </div> </template> diff --git a/packages/rocketchat-ui/views/app/audioNotification.js b/packages/rocketchat-ui/views/app/audioNotification.js deleted file mode 100644 index c0f1ccdd8b9cb7e38079fdc86d35e89a29b2817b..0000000000000000000000000000000000000000 --- a/packages/rocketchat-ui/views/app/audioNotification.js +++ /dev/null @@ -1,6 +0,0 @@ -/* globals KonchatNotification */ -Template.audioNotification.helpers({ - audioAssets() { - return KonchatNotification.audioAssets; - } -})