Remove sounds (#8617)

* feat: remove sounds

* feat: remove more sounds

* feat: disable sounds plugin

* fix: openapi
v1.18.x
Barış Soner Uşaklı 4 years ago committed by GitHub
parent 251ea79bd2
commit 5f10d67db5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,7 +7,6 @@ node_modules/
logs/
/public/templates
/public/uploads
/public/sounds
/public/vendor
/public/src/modules/string.js
.idea/

1
.gitignore vendored

@ -28,7 +28,6 @@ pidfile
# templates
/public/templates
/public/sounds
/public/uploads
/test/uploads

@ -393,75 +393,6 @@ paths:
type: integer
description: Whether the forum will attempt to guess language based on browser's `Accept-Language` header
- $ref: components/schemas/CommonProps.yaml#/CommonProps
/api/admin/settings/sounds:
get:
tags:
- admin
summary: Get sound settings
responses:
"200":
description: A JSON object containing available sounds and settings
content:
application/json:
schema:
allOf:
- type: object
properties:
notification-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
chat-incoming-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
chat-outgoing-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
- $ref: components/schemas/CommonProps.yaml#/CommonProps
/api/admin/settings/navigation:
get:
tags:
@ -2689,33 +2620,6 @@ paths:
url:
type: string
description: URL of the uploaded image for use client-side
/api/admin/upload/sound:
post:
tags:
- admin
summary: Upload sound file
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
files:
type: array
items:
type: string
format: binary
required:
- files
responses:
"200":
description: "Sound uploaded"
content:
application/json:
schema:
type: object
properties: {}
/api/admin/upload/file:
post:
tags:
@ -7437,12 +7341,6 @@ paths:
type: string
scrollToMyPost:
type: boolean
notificationSound:
type: string
incomingChatSound:
type: string
outgoingChatSound:
type: string
notificationType_new-chat:
type: string
notificationType_new-reply:
@ -7541,87 +7439,6 @@ paths:
type: string
selected:
type: boolean
notification-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
notificationSound:
type: array
items:
type: object
properties:
name:
type: string
selected:
type: boolean
chat-incoming-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
incomingChatSound:
type: array
items:
type: object
properties:
name:
type: string
selected:
type: boolean
chat-outgoing-sound:
type: array
items:
type: object
properties:
name:
type: string
sounds:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
selected:
type: boolean
outgoingChatSound:
type: array
items:
type: object
properties:
name:
type: string
selected:
type: boolean
customSettings:
type: array
items:

@ -121,12 +121,7 @@ define('admin/settings', ['uploader'], function (uploader) {
showHelp: uploadBtn.attr('data-help') ? uploadBtn.attr('data-help') === 1 : undefined,
accept: uploadBtn.attr('data-accept'),
}, function (image) {
// need to move these into template, ex data-callback
if (ajaxify.currentPage === 'admin/settings/sounds') {
ajaxify.refresh();
} else {
$('#' + uploadBtn.attr('data-target')).val(image);
}
$('#' + uploadBtn.attr('data-target')).val(image);
});
});
});

@ -1,21 +0,0 @@
'use strict';
define('admin/settings/sounds', ['sounds', 'settings', 'admin/settings'], function (Sounds, Settings, AdminSettings) {
var SoundsAdmin = {};
SoundsAdmin.init = function () {
// Sounds tab
$('.sounds').find('button[data-action="play"]').on('click', function (e) {
e.preventDefault();
var soundName = $(this).parent().parent().find('select')
.val();
Sounds.playSound(soundName);
});
AdminSettings.prepare();
};
return SoundsAdmin;
});

@ -1,7 +1,7 @@
'use strict';
define('forum/account/settings', ['forum/account/header', 'components', 'sounds', 'translator'], function (header, components, sounds, translator) {
define('forum/account/settings', ['forum/account/header', 'components', 'translator'], function (header, components, translator) {
var AccountSettings = {};
// If page skin is changed but not saved, switch the skin back
@ -36,14 +36,6 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
$('[data-property="homePageRoute"]').on('change', toggleCustomRoute);
$('.account').find('button[data-action="play"]').on('click', function (e) {
e.preventDefault();
var soundName = $(this).parent().parent().find('select')
.val();
sounds.playSound(soundName);
});
toggleCustomRoute();
components.get('user/sessions').find('.timeago').timeago();
@ -93,8 +85,6 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
}
}
sounds.loadMap();
if (languageChanged && parseInt(app.user.uid, 10) === parseInt(ajaxify.data.theirid, 10)) {
translator.translate('[[language:dir]]', config.userLang, function (translated) {
var htmlEl = $('html');

@ -1,7 +1,7 @@
'use strict';
define('forum/chats/messages', ['components', 'sounds', 'translator', 'benchpress'], function (components, sounds, translator, Benchpress) {
define('forum/chats/messages', ['components', 'translator', 'benchpress'], function (components, translator, Benchpress) {
var messages = {};
messages.sendMessage = function (roomId, inputEl) {
@ -41,8 +41,6 @@ define('forum/chats/messages', ['components', 'sounds', 'translator', 'benchpres
timeout: 10000,
});
}
sounds.play('chat-outgoing');
});
} else {
socket.emit('modules.chats.edit', {

@ -1,7 +1,7 @@
'use strict';
define('notifications', ['sounds', 'translator', 'components', 'navigator', 'benchpress'], function (sounds, translator, components, navigator, Benchpress) {
define('notifications', ['translator', 'components', 'navigator', 'benchpress'], function (translator, components, navigator, Benchpress) {
var Notifications = {};
var unreadNotifs = {};
@ -68,7 +68,6 @@ define('notifications', ['sounds', 'translator', 'components', 'navigator', 'ben
});
if (!unreadNotifs[notifData.nid]) {
sounds.play('notification', notifData.nid);
unreadNotifs[notifData.nid] = true;
}
};

@ -1,95 +0,0 @@
'use strict';
define('sounds', ['storage'], function (storage) {
var Sounds = {};
var fileMap;
var soundMap;
var cache = {};
Sounds.loadMap = function loadMap(callback) {
socket.emit('modules.sounds.getUserSoundMap', function (err, map) {
if (err) {
return app.alertError(err.message);
}
soundMap = map;
if (callback) {
callback();
}
});
};
function loadData(callback) {
var outstanding = 2;
function after() {
outstanding -= 1;
if (outstanding === 0 && callback) {
callback();
}
}
if (fileMap) {
outstanding -= 1;
} else {
$.getJSON(config.relative_path + '/assets/sounds/fileMap.json', function (map) {
fileMap = map;
after();
});
}
Sounds.loadMap(after);
}
Sounds.playSound = function playSound(soundName) {
if (!soundMap || !fileMap) {
return loadData(after);
}
function after() {
if (!fileMap[soundName]) {
return;
}
var audio = cache[soundName] || new Audio(config.relative_path + '/assets/sounds/' + fileMap[soundName]);
cache[soundName] = audio;
audio.pause();
audio.currentTime = 0;
audio.play();
}
after();
};
Sounds.play = function play(type, id) {
function after() {
if (!soundMap[type]) {
return;
}
if (id) {
var item = 'sounds.handled:' + id;
if (storage.getItem(item)) {
return;
}
storage.setItem(item, true);
setTimeout(function () {
storage.removeItem(item);
}, 5000);
}
Sounds.playSound(soundMap[type]);
}
if (!soundMap || !fileMap) {
return loadData(after);
}
after();
};
socket.on('event:sounds.reloadMapping', function () {
Sounds.loadMap();
});
return Sounds;
});

@ -189,7 +189,7 @@ program
});
program
.command('build [targets...]')
.description('Compile static assets ' + '(JS, CSS, templates, languages, sounds)'.red)
.description('Compile static assets ' + '(JS, CSS, templates, languages)'.red)
.option('-s, --series', 'Run builds in series without extra processes')
.action(function (targets, options) {
require('./manage').build(targets.length ? targets : true, options);

@ -22,10 +22,9 @@ settingsController.get = async function (req, res, next) {
if (!userData) {
return next();
}
const [settings, languagesData, soundsMapping] = await Promise.all([
const [settings, languagesData] = await Promise.all([
user.getSettings(userData.uid),
languages.list(),
meta.sounds.getUserSoundMap(userData.uid),
]);
userData.settings = settings;
@ -34,8 +33,6 @@ settingsController.get = async function (req, res, next) {
userData.acpLanguages = _.cloneDeep(languagesData);
}
addSoundSettings(userData, soundsMapping);
const data = await plugins.fireHook('filter:user.customSettings', {
settings: settings,
customSettings: [],
@ -124,48 +121,6 @@ settingsController.get = async function (req, res, next) {
res.render('account/settings', userData);
};
function addSoundSettings(userData, soundsMapping) {
const types = [
'notification',
'chat-incoming',
'chat-outgoing',
];
const aliases = {
notification: 'notificationSound',
'chat-incoming': 'incomingChatSound',
'chat-outgoing': 'outgoingChatSound',
};
types.forEach(function (type) {
const soundpacks = plugins.soundpacks.map(function (pack) {
const sounds = Object.keys(pack.sounds).map(function (soundName) {
const value = pack.name + ' | ' + soundName;
return {
name: soundName,
value: value,
selected: value === soundsMapping[type],
};
});
return {
name: pack.name,
sounds: sounds,
};
});
userData[type + '-sound'] = soundpacks;
// fallback
userData[aliases[type]] = soundpacks.concat.apply([], soundpacks.map(function (pack) {
return pack.sounds.map(function (sound) {
return {
name: sound.value,
selected: sound.selected,
};
});
}));
});
}
const unsubscribable = ['digest', 'notification'];
const jwtVerifyAsync = util.promisify(function (token, callback) {
jwt.verify(token, nconf.get('secret'), (err, payload) => callback(err, payload));

@ -5,7 +5,6 @@ const emailer = require('../../emailer');
const notifications = require('../../notifications');
const groups = require('../../groups');
const languages = require('../../languages');
const plugins = require('../../plugins');
const navigationAdmin = require('../../navigation/admin');
const social = require('../../social');
@ -61,38 +60,6 @@ settingsController.languages = async function (req, res) {
});
};
settingsController.sounds = async function (req, res) {
const types = [
'notification',
'chat-incoming',
'chat-outgoing',
];
const settings = await meta.configs.getFields(types) || {};
var output = {};
types.forEach(function (type) {
var soundpacks = plugins.soundpacks.map(function (pack) {
var sounds = Object.keys(pack.sounds).map(function (soundName) {
var value = pack.name + ' | ' + soundName;
return {
name: soundName,
value: value,
selected: value === settings[type],
};
});
return {
name: pack.name,
sounds: sounds,
};
});
output[type + '-sound'] = soundpacks;
});
res.render('admin/settings/sounds', output);
};
settingsController.navigation = async function (req, res) {
const [admin, allGroups] = await Promise.all([
navigationAdmin.getAdmin(),

@ -2,7 +2,6 @@
const path = require('path');
const nconf = require('nconf');
const mime = require('mime');
const fs = require('fs');
const meta = require('../../meta');
@ -171,24 +170,6 @@ uploadsController.uploadLogo = async function (req, res, next) {
await upload('site-logo', req, res, next);
};
uploadsController.uploadSound = async function (req, res, next) {
const uploadedFile = req.files.files[0];
const mimeType = mime.getType(uploadedFile.name);
if (!/^audio\//.test(mimeType)) {
return next(Error('[[error:invalid-data]]'));
}
try {
await file.saveFileToLocal(uploadedFile.name, 'sounds', uploadedFile.path);
await meta.sounds.build();
res.json([{}]);
} catch (err) {
next(err);
} finally {
file.delete(uploadedFile.path);
}
};
uploadsController.uploadFile = async function (req, res, next) {
const uploadedFile = req.files.files[0];
let params;

@ -323,7 +323,7 @@ async function buildCustomTemplates(config) {
Benchpress.flush();
winston.verbose('[emailer] Built custom email templates');
} catch (err) {
winston.error('[emailer] Failed to build custom email templates', err.stack);
winston.error('[emailer] Failed to build custom email templates\n' + err.stack);
}
}

@ -420,7 +420,6 @@ async function enableDefaultPlugins() {
'nodebb-plugin-mentions',
'nodebb-widget-essentials',
'nodebb-rewards-essentials',
'nodebb-plugin-soundpack-default',
'nodebb-plugin-emoji',
'nodebb-plugin-emoji-android',
];

@ -61,9 +61,6 @@ var targetHandlers = {
languages: function (parallel, callback) {
meta.languages.build(callback);
},
sounds: function (parallel, callback) {
meta.sounds.build(callback);
},
};
var aliases = {
@ -81,7 +78,6 @@ var aliases = {
styles: ['css', 'less', 'style'],
templates: ['tpl'],
languages: ['lang', 'i18n'],
sounds: ['sound'],
};
exports.aliases = aliases;

@ -15,7 +15,6 @@ Meta.configs = require('./configs');
Meta.themes = require('./themes');
Meta.js = require('./js');
Meta.css = require('./css');
Meta.sounds = require('./sounds');
Meta.settings = require('./settings');
Meta.logs = require('./logs');
Meta.errors = require('./errors');

@ -1,101 +0,0 @@
'use strict';
const path = require('path');
const fs = require('fs');
const util = require('util');
let mkdirp = require('mkdirp');
mkdirp = mkdirp.hasOwnProperty('native') ? mkdirp : util.promisify(mkdirp);
const rimraf = require('rimraf');
const rimrafAsync = util.promisify(rimraf);
const file = require('../file');
const plugins = require('../plugins');
const user = require('../user');
const Meta = require('./index');
const soundsPath = path.join(__dirname, '../../build/public/sounds');
const uploadsPath = path.join(__dirname, '../../public/uploads/sounds');
const Sounds = module.exports;
Sounds.addUploads = async function addUploads() {
let files = [];
try {
files = await fs.promises.readdir(uploadsPath);
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
files = [];
}
var uploadSounds = files.reduce(function (prev, fileName) {
var name = fileName.split('.');
if (!name.length || !name[0].length) {
return prev;
}
name = name[0];
name = name[0].toUpperCase() + name.slice(1);
prev[name] = fileName;
return prev;
}, {});
plugins.soundpacks = plugins.soundpacks.filter(pack => pack.name !== 'Uploads');
if (Object.keys(uploadSounds).length) {
plugins.soundpacks.push({
name: 'Uploads',
id: 'uploads',
dir: uploadsPath,
sounds: uploadSounds,
});
}
};
Sounds.build = async function build() {
await Sounds.addUploads();
var map = plugins.soundpacks.map(function (pack) {
return Object.keys(pack.sounds).reduce(function (prev, soundName) {
var soundPath = pack.sounds[soundName];
prev[pack.name + ' | ' + soundName] = pack.id + '/' + soundPath;
return prev;
}, {});
});
map.unshift({});
map = Object.assign.apply(null, map);
await rimrafAsync(soundsPath);
await mkdirp(soundsPath);
await fs.promises.writeFile(path.join(soundsPath, 'fileMap.json'), JSON.stringify(map));
await Promise.all(plugins.soundpacks.map(pack => file.linkDirs(pack.dir, path.join(soundsPath, pack.id), false)));
};
var keys = ['chat-incoming', 'chat-outgoing', 'notification'];
Sounds.getUserSoundMap = async function getUserSoundMap(uid) {
const [defaultMapping, userSettings] = await Promise.all([
Meta.configs.getFields(keys),
user.getSettings(uid),
]);
userSettings.notification = userSettings.notificationSound;
userSettings['chat-incoming'] = userSettings.incomingChatSound;
userSettings['chat-outgoing'] = userSettings.outgoingChatSound;
const soundMapping = {};
keys.forEach(function (key) {
if (userSettings[key] || userSettings[key] === '') {
soundMapping[key] = userSettings[key] || '';
} else {
soundMapping[key] = defaultMapping[key] || '';
}
});
return soundMapping;
};

@ -216,35 +216,6 @@ Data.getModules = async function getModules(pluginData) {
return modules;
};
Data.getSoundpack = async function getSoundpack(pluginData) {
var spack = pluginData.soundpack;
if (!spack || !spack.dir || !spack.sounds) {
return;
}
var soundpack = {};
soundpack.name = spack.name || pluginData.name;
soundpack.id = pluginData.id;
soundpack.dir = path.join(pluginData.path, spack.dir);
soundpack.sounds = {};
async function processSoundPack(name) {
const soundFile = spack.sounds[name];
const exists = await file.exists(path.join(soundpack.dir, soundFile));
if (!exists) {
winston.warn('[plugins] Sound file not found: ' + soundFile);
return;
}
soundpack.sounds[name] = soundFile;
}
await Promise.all(Object.keys(spack.sounds).map(key => processSoundPack(key)));
const len = Object.keys(soundpack.sounds).length;
winston.verbose('[plugins] Found ' + len + ' sound file(s) for plugin ' + pluginData.id);
return soundpack;
};
Data.getLanguageData = async function getLanguageData(pluginData) {
if (typeof pluginData.languages !== 'string') {
return;

@ -36,7 +36,6 @@ Plugins.clientScripts = [];
Plugins.acpScripts = [];
Plugins.libraryPaths = [];
Plugins.versionWarning = [];
Plugins.soundpacks = [];
Plugins.languageData = {};
Plugins.loadedPlugins = [];

@ -37,9 +37,6 @@ module.exports = function (Plugins) {
modules: function (next) {
Plugins.data.getModules(pluginData, next);
},
soundpack: function (next) {
Plugins.data.getSoundpack(pluginData, next);
},
languageData: function (next) {
Plugins.data.getLanguageData(pluginData, next);
},
@ -63,9 +60,6 @@ module.exports = function (Plugins) {
add(Plugins.clientScripts, results.clientScripts);
add(Plugins.acpScripts, results.acpScripts);
Object.assign(meta.js.scripts.modules, results.modules || {});
if (results.soundpack) {
Plugins.soundpacks.push(results.soundpack);
}
if (results.languageData) {
Plugins.languageData.languages = _.union(Plugins.languageData.languages, results.languageData.languages);
Plugins.languageData.namespaces = _.union(Plugins.languageData.namespaces, results.languageData.namespaces);
@ -81,7 +75,6 @@ module.exports = function (Plugins) {
'admin js bundle': ['acpScripts'],
'client side styles': ['cssFiles', 'lessFiles'],
'admin control panel styles': ['cssFiles', 'lessFiles', 'acpLessFiles'],
sounds: ['soundpack'],
languages: ['languageData'],
};
@ -97,9 +90,6 @@ module.exports = function (Plugins) {
case 'acpLessFiles':
Plugins[field].length = 0;
break;
case 'soundpack':
Plugins.soundpacks.length = 0;
break;
case 'languageData':
Plugins.languageData.languages = [];
Plugins.languageData.namespaces = [];
@ -132,7 +122,7 @@ module.exports = function (Plugins) {
try {
registerHooks(pluginData);
await registerPluginAssets(pluginData, ['soundpack']);
await registerPluginAssets(pluginData);
} catch (err) {
winston.error(err.stack);
winston.verbose('[plugins] Could not load plugin : ' + pluginData.id);

@ -40,7 +40,6 @@ module.exports = function (app, middleware, controllers) {
helpers.setupAdminPageRoute(app, '/admin/settings/user', middleware, middlewares, controllers.admin.settings.user);
helpers.setupAdminPageRoute(app, '/admin/settings/post', middleware, middlewares, controllers.admin.settings.post);
helpers.setupAdminPageRoute(app, '/admin/settings/languages', middleware, middlewares, controllers.admin.settings.languages);
helpers.setupAdminPageRoute(app, '/admin/settings/sounds', middleware, middlewares, controllers.admin.settings.sounds);
helpers.setupAdminPageRoute(app, '/admin/settings/navigation', middleware, middlewares, controllers.admin.settings.navigation);
helpers.setupAdminPageRoute(app, '/admin/settings/homepage', middleware, middlewares, controllers.admin.settings.homepage);
helpers.setupAdminPageRoute(app, '/admin/settings/social', middleware, middlewares, controllers.admin.settings.social);
@ -82,7 +81,6 @@ function apiRoutes(router, middleware, controllers) {
router.post('/api/admin/uploadTouchIcon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadTouchIcon));
router.post('/api/admin/uploadlogo', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadLogo));
router.post('/api/admin/uploadOgImage', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadOgImage));
router.post('/api/admin/upload/sound', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadSound));
router.post('/api/admin/upload/file', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadFile));
router.post('/api/admin/uploadDefaultAvatar', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadDefaultAvatar));
}

@ -15,7 +15,6 @@ const privileges = require('../privileges');
const SocketModules = module.exports;
SocketModules.chats = {};
SocketModules.sounds = {};
SocketModules.settings = {};
/* Chat */
@ -290,9 +289,4 @@ SocketModules.chats.getIP = async function (socket, mid) {
return await Messaging.getMessageField(mid, 'ip');
};
/* Sounds */
SocketModules.sounds.getUserSoundMap = async function getUserSoundMap(socket) {
return await meta.sounds.getUserSoundMap(socket.uid);
};
require('../promisify')(SocketModules);

@ -0,0 +1,11 @@
'use strict';
const db = require('../../database');
module.exports = {
name: 'Disable nodebb-plugin-soundpack-default',
timestamp: Date.UTC(2020, 8, 6),
method: async function () {
await db.sortedSetRemove('plugins:active', 'nodebb-plugin-soundpack-default');
},
};

@ -118,9 +118,6 @@ module.exports = function (User) {
topicSearchEnabled: data.topicSearchEnabled,
homePageRoute: ((data.homePageRoute === 'custom' ? data.homePageCustom : data.homePageRoute) || '').replace(/^\//, ''),
scrollToMyPost: data.scrollToMyPost,
notificationSound: data.notificationSound,
incomingChatSound: data.incomingChatSound,
outgoingChatSound: data.outgoingChatSound,
upvoteNotifFreq: data.upvoteNotifFreq,
bootswatchSkin: data.bootswatchSkin,
categoryWatchState: data.categoryWatchState,

@ -52,7 +52,6 @@
<li><a href="{relative_path}/admin/settings/chat">[[admin/menu:settings/chat]]</a></li>
<li><a href="{relative_path}/admin/settings/pagination">[[admin/menu:settings/pagination]]</a></li>
<li><a href="{relative_path}/admin/settings/notifications">[[admin/menu:settings/notifications]]</a></li>
<li><a href="{relative_path}/admin/settings/sounds">[[admin/menu:settings/sounds]]</a></li>
<li><a href="{relative_path}/admin/settings/social">[[admin/menu:settings/social]]</a></li>
<li><a href="{relative_path}/admin/settings/cookies">[[admin/menu:settings/cookies]]</a></li>
<li><a href="{relative_path}/admin/settings/web-crawler">[[admin/menu:settings/web-crawler]]</a></li>

@ -1,97 +0,0 @@
<div class="sounds settings row">
<div class="col-xs-12">
<form role="form">
<div class="row">
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/sounds:notifications]]</div>
<div class="col-sm-10 col-xs-12">
<label for="notification">[[admin/settings/sounds:notifications]]</label>
<div class="row">
<div class="form-group col-xs-9">
<select class="form-control" id="notification" data-field="notification">
<option value="">[[user:no-sound]]</option>
<!-- BEGIN notification-sound -->
<optgroup label="{notification-sound.name}">
<!-- BEGIN notification-sound.sounds -->
<option value="{notification-sound.sounds.value}" <!-- IF notification-sound.sounds.selected -->selected<!-- ENDIF notification-sound.sounds.selected -->>
{notification-sound.sounds.name}
</option>
<!-- END notification-sound.sounds -->
</optgroup>
<!-- END notification-sound -->
</select>
</div>
<div class="btn-group col-xs-3">
<button type="button" class="form-control btn btn-sm btn-default" data-action="play"><span class="hidden-xs">[[admin/settings/sounds:play-sound]] </span><i class="fa fa-play"></i></button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/sounds:chat-messages]]</div>
<div class="col-sm-10 col-xs-12">
<label for="chat-incoming">[[admin/settings/sounds:incoming-message]]</label>
<div class="row">
<div class="form-group col-xs-9">
<select class="form-control" id="chat-incoming" data-field="chat-incoming">
<option value="">[[user:no-sound]]</option>
<!-- BEGIN chat-incoming-sound -->
<optgroup label="{chat-incoming-sound.name}">
<!-- BEGIN chat-incoming-sound.sounds -->
<option value="{chat-incoming-sound.sounds.value}" <!-- IF chat-incoming-sound.sounds.selected -->selected<!-- ENDIF chat-incoming-sound.sounds.selected -->>
{chat-incoming-sound.sounds.name}
</option>
<!-- END chat-incoming-sound.sounds -->
</optgroup>
<!-- END chat-incoming-sound -->
</select>
</div>
<div class="btn-group col-xs-3">
<button type="button" class="form-control btn btn-sm btn-default" data-action="play"><span class="hidden-xs">[[admin/settings/sounds:play-sound]] </span><i class="fa fa-play"></i></button>
</div>
</div>
<label for="chat-outgoing">[[admin/settings/sounds:outgoing-message]]</label>
<div class="row">
<div class="form-group col-xs-9">
<select class="form-control" id="chat-outgoing" data-field="chat-outgoing">
<option value="">[[user:no-sound]]</option>
<!-- BEGIN chat-outgoing-sound -->
<optgroup label="{chat-outgoing-sound.name}">
<!-- BEGIN chat-outgoing-sound.sounds -->
<option value="{chat-outgoing-sound.sounds.value}" <!-- IF chat-outgoing-sound.sounds.selected -->selected<!-- ENDIF chat-outgoing-sound.sounds.selected -->>
{chat-outgoing-sound.sounds.name}
</option>
<!-- END chat-outgoing-sound.sounds -->
</optgroup>
<!-- END chat-outgoing-sound -->
</select>
</div>
<div class="btn-group col-xs-3">
<button type="button" class="form-control btn btn-sm btn-default" data-action="play"><span class="hidden-xs">[[admin/settings/sounds:play-sound]] </span><i class="fa fa-play"></i></button>
</div>
</div>
<div class="input-group">
<span class="input-group-btn">
<input
data-action="upload"
data-title="Upload Sound"
data-route="{config.relative_path}/api/admin/upload/sound"
data-accept="audio/*"
type="button"
class="btn btn-primary"
value="[[admin/settings/sounds:upload-new-sound]]"
></input>
</span>
</div>
</div>
</div>
</form>
</div>
</div>
<button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
<i class="material-icons">save</i>
</button>

@ -103,7 +103,6 @@ async function initializeNodeBB() {
middleware: middleware,
});
await routes(app, middleware);
await meta.sounds.addUploads();
await meta.blacklist.load();
await flags.init();
}

@ -220,20 +220,4 @@ describe('Build', function (done) {
done();
});
});
it('should build sounds', function (done) {
build.build(['sounds'], function (err) {
assert.ifError(err);
var mapFile = path.join(__dirname, '../build/public/sounds/fileMap.json');
assert(file.existsSync(mapFile));
var fileMap = JSON.parse(fs.readFileSync(mapFile));
assert.strictEqual(fileMap['Default | Deedle-dum'], 'nodebb-plugin-soundpack-default/notification.mp3');
var deebleDumFile = path.join(__dirname, '../build/public/sounds/nodebb-plugin-soundpack-default/notification.mp3');
assert(file.existsSync(deebleDumFile));
done();
});
});
});

@ -496,15 +496,6 @@ describe('Admin Controllers', function () {
});
});
it('should load /admin/settings/sounds', function (done) {
request(nconf.get('url') + '/api/admin/settings/sounds', { jar: jar, json: true }, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(body);
done();
});
});
it('should load /admin/manage/categories', function (done) {
request(nconf.get('url') + '/api/admin/manage/categories', { jar: jar, json: true }, function (err, res, body) {
assert.ifError(err);

@ -463,21 +463,6 @@ describe('meta', function () {
});
});
describe('sounds', function () {
var socketModules = require('../src/socket.io/modules');
it('should getUserMap', function (done) {
socketModules.sounds.getUserSoundMap({ uid: 1 }, null, function (err, data) {
assert.ifError(err);
assert(data.hasOwnProperty('chat-incoming'));
assert(data.hasOwnProperty('chat-outgoing'));
assert(data.hasOwnProperty('notification'));
done();
});
});
});
describe('debugFork', function () {
var oldArgv;
before(function () {

@ -193,7 +193,6 @@ async function setupMockDefaults() {
'test/uploads/category',
'test/uploads/files',
'test/uploads/system',
'test/uploads/sounds',
'test/uploads/profile',
];
for (const folder of folders) {
@ -229,7 +228,6 @@ async function enableDefaultPlugins() {
const testPlugins = Array.isArray(nconf.get('test_plugins')) ? nconf.get('test_plugins') : [];
const defaultEnabled = [
'nodebb-plugin-dbsearch',
'nodebb-plugin-soundpack-default',
'nodebb-widget-essentials',
].concat(testPlugins);

@ -497,7 +497,7 @@ describe('socket.io', function () {
var data = [
{ name: 'nodebb-theme-persona', order: 0 },
{ name: 'nodebb-plugin-dbsearch', order: 1 },
{ name: 'nodebb-plugin-soundpack-default', order: 2 },
{ name: 'nodebb-plugin-markdown', order: 2 },
{ ignoreme: 'wrong data' },
];
socketAdmin.plugins.orderActivePlugins({ uid: adminUid }, data, function (err) {

@ -347,25 +347,6 @@ describe('Upload Controllers', function () {
});
});
it('should fail to upload invalid sound file', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/admin/upload/sound', path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 500);
assert.equal(body.error, '[[error:invalid-data]]');
done();
});
});
it('should upload sound file', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/admin/upload/sound', path.join(__dirname, '../test/files/test.wav'), { }, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(body);
done();
});
});
it('should upload default avatar', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadDefaultAvatar', path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token, function (err, res, body) {
assert.ifError(err);

@ -1641,9 +1641,6 @@ describe('User', function () {
restrictChat: 0,
followTopicsOnCreate: 1,
followTopicsOnReply: 1,
notificationSound: '',
incomingChatSound: '',
outgoingChatSound: '',
},
};
socketUser.saveSettings({ uid: testUid }, data, function (err) {

Loading…
Cancel
Save