From a784d10fffca6689c68fa2b116bb43eef835ff26 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 14 Oct 2020 10:02:02 -0400 Subject: [PATCH] refactor: api module returns promise, error-first cb if cb passed in no more separate onSuccess onError callbacks /cc @baris --- public/src/admin/manage/admins-mods.js | 8 +-- public/src/admin/manage/categories.js | 16 ++---- public/src/admin/manage/category.js | 22 ++------ public/src/admin/manage/group.js | 4 +- public/src/admin/manage/groups.js | 2 +- public/src/admin/manage/uploads.js | 4 +- public/src/admin/manage/users.js | 64 ++++++++-------------- public/src/client/account/edit.js | 4 +- public/src/client/account/edit/email.js | 4 +- public/src/client/account/edit/password.js | 34 ++++++------ public/src/client/account/edit/username.js | 4 +- public/src/client/account/header.js | 8 +-- public/src/client/groups/details.js | 5 +- public/src/client/groups/list.js | 4 +- public/src/client/groups/memberlist.js | 8 +-- public/src/modules/api.js | 45 +++++++++------ 16 files changed, 103 insertions(+), 133 deletions(-) diff --git a/public/src/admin/manage/admins-mods.js b/public/src/admin/manage/admins-mods.js index 403baa16525d..9f451f61f3b3 100644 --- a/public/src/admin/manage/admins-mods.js +++ b/public/src/admin/manage/admins-mods.js @@ -44,7 +44,7 @@ define('admin/manage/admins-mods', [ }); autocomplete.user($('#global-mod-search'), function (ev, ui) { - api.put('/groups/global-moderators/membership/' + ui.item.user.uid, undefined, () => { + api.put('/groups/global-moderators/membership/' + ui.item.user.uid, () => { app.alertSuccess('[[admin/manage/users:alerts.make-global-mod-success]]'); $('#global-mod-search').val(''); @@ -56,7 +56,7 @@ define('admin/manage/admins-mods', [ $('.global-moderator-area').prepend(html); $('#no-global-mods-warning').addClass('hidden'); }); - }, 'default'); + }); }); $('.global-moderator-area').on('click', '.remove-user-icon', function () { @@ -65,13 +65,13 @@ define('admin/manage/admins-mods', [ bootbox.confirm('[[admin/manage/users:alerts.confirm-remove-global-mod]]', function (confirm) { if (confirm) { - api.del('/groups/global-moderators/membership/' + uid, undefined, () => { + api.del('/groups/global-moderators/membership/' + uid).then(() => { app.alertSuccess('[[admin/manage/users:alerts.remove-global-mod-success]]'); userCard.remove(); if (!$('.global-moderator-area').children().length) { $('#no-global-mods-warning').removeClass('hidden'); } - }, 'default'); + }); } }); }); diff --git a/public/src/admin/manage/categories.js b/public/src/admin/manage/categories.js index 6d6228d2cf7e..ad1d8465398c 100644 --- a/public/src/admin/manage/categories.js +++ b/public/src/admin/manage/categories.js @@ -196,15 +196,9 @@ define('admin/manage/categories', [ }; Categories.toggle = function (cids, disabled) { - var requests = cids.map(function (cid) { - return api.put('/categories/' + cid, { - disabled: disabled ? 1 : 0, - }); - }); - - $.when(requests).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + Promise.all(cids.map(cid => api.put('/categories/' + cid, { + disabled: disabled ? 1 : 0, + }))); }; function itemDidAdd(e) { @@ -234,9 +228,7 @@ define('admin/manage/categories', [ newCategoryId = -1; - Object.keys(modified).forEach(function (cid) { - api.put('/categories/' + cid, modified[cid]); - }); + Object.keys(modified).map(cid => api.put('/categories/' + cid, modified[cid])); } } diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 51f3f8b0e62e..c02414fb54ed 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -49,17 +49,15 @@ define('admin/manage/category', [ } var cid = ajaxify.data.category.cid; - api.put('/categories/' + cid, updateHash, (res) => { + api.put('/categories/' + cid, updateHash).then((res) => { app.flags._unsaved = false; app.alert({ title: 'Updated Categories', message: 'Category "' + res.name + '" was successfully updated.', type: 'success', - timeout: 2000, + timeout: 5000, }); updateHash = {}; - }, (err) => { - app.alertError(err.status.message); }); return false; @@ -98,15 +96,13 @@ define('admin/manage/category', [ }); }, 1000); - api.del('/categories/' + ajaxify.data.category.cid, undefined, () => { + api.del('/categories/' + ajaxify.data.category.cid).then(() => { if (intervalId) { clearInterval(intervalId); } modal.modal('hide'); app.alertSuccess('[[admin/manage/categories:alert.purge-success]]'); ajaxify.go('admin/manage/categories'); - }, (err) => { - app.alertError(err.status.message); }); return false; @@ -215,12 +211,10 @@ define('admin/manage/category', [ $('button[data-action="removeParent"]').on('click', function () { api.put('/categories/' + ajaxify.data.category.cid, { parentCid: 0, - }, () => { + }).then(() => { $('button[data-action="removeParent"]').parent().addClass('hide'); $('button[data-action="changeParent"]').parent().addClass('hide'); $('button[data-action="setParent"]').removeClass('hide'); - }, (err) => { - app.alertError(err.message); }); }); $('button[data-action="toggle"]').on('click', function () { @@ -228,12 +222,10 @@ define('admin/manage/category', [ var disabled = $this.attr('data-disabled') === '1'; api.put('/categories/' + ajaxify.data.category.cid, { disabled: disabled ? 0 : 1, - }, () => { + }).then(() => { $this.translateText(!disabled ? '[[admin/manage/categories:enable]]' : '[[admin/manage/categories:disable]]'); $this.toggleClass('btn-primary', !disabled).toggleClass('btn-danger', disabled); $this.attr('data-disabled', disabled ? 0 : 1); - }, (err) => { - app.alertError(err.message); }); }); }; @@ -285,7 +277,7 @@ define('admin/manage/category', [ categorySelector.modal(categories, function (parentCid) { api.put('/categories/' + ajaxify.data.category.cid, { parentCid: parentCid, - }, () => { + }).then(() => { var parent = allCategories.filter(function (category) { return category && parseInt(category.cid, 10) === parseInt(parentCid, 10); }); @@ -295,8 +287,6 @@ define('admin/manage/category', [ $('button[data-action="setParent"]').addClass('hide'); var buttonHtml = ' ' + parent.name; $('button[data-action="changeParent"]').html(buttonHtml).parent().removeClass('hide'); - }, (err) => { - app.alertError(err.message); }); }); }); diff --git a/public/src/admin/manage/group.js b/public/src/admin/manage/group.js index 1cf6cd1935ff..8eaa88a9200c 100644 --- a/public/src/admin/manage/group.js +++ b/public/src/admin/manage/group.js @@ -128,9 +128,9 @@ define('admin/manage/group', [ if (!confirm) { return; } - api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + uid, undefined, () => { + api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + uid).then(() => { userRow.slideUp().remove(); - }, 'default'); + }); }); break; default: diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index cfa3e6969966..6a3b36324fdd 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -44,7 +44,7 @@ define('admin/manage/groups', [ ajaxify.go('admin/manage/groups/' + response.name); }); createModal.modal('hide'); - }, (err) => { + }).catch((err) => { if (!utils.hasLanguageKey(err.status.message)) { err.status.message = '[[admin/manage/groups:alerts.create-failure]]'; } diff --git a/public/src/admin/manage/uploads.js b/public/src/admin/manage/uploads.js index 997ce9c91aac..7380f2b2d890 100644 --- a/public/src/admin/manage/uploads.js +++ b/public/src/admin/manage/uploads.js @@ -24,9 +24,9 @@ define('admin/manage/uploads', ['uploader', 'api'], function (uploader, api) { api.del('/files', { path: file.attr('data-path'), - }, () => { + }).then(() => { file.remove(); - }, 'default'); + }); }); }); }; diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index 4317a40753dc..2505978faee1 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -40,7 +40,7 @@ define('admin/manage/users', [ $('.users-table [component="user/select/single"]:checked').parents('.user-row').remove(); } - // use onSuccess/onFail instead + // use onSuccess instead function done(successMessage, className, flag) { return function (err) { if (err) { @@ -62,10 +62,6 @@ define('admin/manage/users', [ unselectAll(); } - function onFail(err) { - app.alertError(err.message); - } - $('[component="user/select/all"]').on('click', function () { $('.users-table [component="user/select/single"]').prop('checked', $(this).is(':checked')); }); @@ -89,12 +85,12 @@ define('admin/manage/users', [ modal.on('shown.bs.modal', function () { autocomplete.group(modal.find('.group-search'), function (ev, ui) { var uid = $(ev.target).attr('data-uid'); - api.put('/groups/' + ui.item.group.slug + '/membership/' + uid, undefined, () => { + api.put('/groups/' + ui.item.group.slug + '/membership/' + uid, undefined).then(() => { ui.item.group.nameEscaped = translator.escape(ui.item.group.displayName); app.parseAndTranslate('admin/partials/manage_user_groups', { users: [{ groups: [ui.item.group] }] }, function (html) { $('[data-uid=' + uid + '] .group-area').append(html.find('.group-area').html()); }); - }, 'default'); + }); }); }); modal.on('click', '.group-area a', function () { @@ -104,9 +100,9 @@ define('admin/manage/users', [ var groupCard = $(this).parents('[data-group-name]'); var groupName = groupCard.attr('data-group-name'); var uid = $(this).parents('[data-uid]').attr('data-uid'); - api.del('/groups/' + slugify(groupName) + '/membership/' + uid, undefined, () => { + api.del('/groups/' + slugify(groupName) + '/membership/' + uid).then(() => { groupCard.remove(); - }, 'default'); + }); return false; }); }); @@ -122,17 +118,11 @@ define('admin/manage/users', [ bootbox.confirm((uids.length > 1 ? '[[admin/manage/users:alerts.confirm-ban-multi]]' : '[[admin/manage/users:alerts.confirm-ban]]'), function (confirm) { if (confirm) { - var requests = uids.map(function (uid) { + Promise.all(uids.map(function (uid) { return api.put('/users/' + uid + '/ban'); + })).then(() => { + onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true); }); - - $.when(requests) - .done(function () { - onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true); - }) - .fail(function (ev) { - onFail(ev.responseJSON.status); - }); } }); }); @@ -164,19 +154,14 @@ define('admin/manage/users', [ }, {}); var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0; - var requests = uids.map(function (uid) { + Promise.all(uids.map(function (uid) { return api.put('/users/' + uid + '/ban', { until: until, reason: formData.reason, }); + })).then(() => { + onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true); }); - - $.when(requests) - .done(function () { - onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true); - }).fail(function (ev) { - onFail(ev.responseJSON.status); - }); }, }, }, @@ -191,16 +176,11 @@ define('admin/manage/users', [ return false; // specifically to keep the menu open } - var requests = uids.map(function (uid) { + Promise.all(uids.map(function (uid) { return api.delete('/users/' + uid + '/ban'); + })).then(() => { + onSuccess('[[admin/manage/users:alerts.unban-success]]', '.ban', false); }); - - $.when(requests) - .done(function () { - onSuccess('[[admin/manage/users:alerts.unban-success]]', '.ban', false); - }).fail(function (ev) { - onFail(ev.responseJSON.status); - }); }); $('.reset-lockout').on('click', function () { @@ -388,13 +368,15 @@ define('admin/manage/users', [ password: password, }; - api.post('/users', user, () => { - modal.modal('hide'); - modal.on('hidden.bs.modal', function () { - ajaxify.refresh(); - }); - app.alertSuccess('[[admin/manage/users:alerts.create-success]]'); - }, err => errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.status.message + ']]').removeClass('hidden')); + api.post('/users', user) + .then(() => { + modal.modal('hide'); + modal.on('hidden.bs.modal', function () { + ajaxify.refresh(); + }); + app.alertSuccess('[[admin/manage/users:alerts.create-success]]'); + }) + .catch(err => errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.status.message + ']]').removeClass('hidden')); } handleSearch(); diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index 7c5e0cb95cdc..6db92ea4bbdb 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -47,7 +47,7 @@ define('forum/account/edit', [ $(window).trigger('action:profile.update', userData); - api.put('/users/' + userData.uid, userData, (res) => { + api.put('/users/' + userData.uid, userData).then((res) => { app.alertSuccess('[[user:profile-update-success]]'); if (res.picture) { @@ -55,7 +55,7 @@ define('forum/account/edit', [ } updateHeader(res.picture); - }, 'default'); + }); return false; } diff --git a/public/src/client/account/edit/email.js b/public/src/client/account/edit/email.js index c5f685e1a1cd..a21be3f46ba0 100644 --- a/public/src/client/account/edit/email.js +++ b/public/src/client/account/edit/email.js @@ -26,10 +26,10 @@ define('forum/account/edit/email', ['forum/account/header', 'api'], function (he var btn = $(this); btn.addClass('disabled').find('i').removeClass('hide'); - api.put('/users/' + userData.uid, userData, (res) => { + api.put('/users/' + userData.uid, userData).then((res) => { btn.removeClass('disabled').find('i').addClass('hide'); ajaxify.go('user/' + res.userslug + '/edit'); - }, 'default'); + }); return false; }); diff --git a/public/src/client/account/edit/password.js b/public/src/client/account/edit/password.js index e6c8ee2fd447..99b8cdde7188 100644 --- a/public/src/client/account/edit/password.js +++ b/public/src/client/account/edit/password.js @@ -71,22 +71,24 @@ define('forum/account/edit/password', [ api.put('/users/' + ajaxify.data.theirid + '/password', { currentPassword: currentPassword.val(), newPassword: password.val(), - }, () => { - if (parseInt(app.user.uid, 10) === parseInt(ajaxify.data.uid, 10)) { - window.location.href = config.relative_path + '/login'; - } else { - ajaxify.go('user/' + ajaxify.data.userslug + '/edit'); - } - }, 'default').always(() => { - btn.removeClass('disabled').find('i').addClass('hide'); - currentPassword.val(''); - password.val(''); - password_confirm.val(''); - password_notify.parent().removeClass('show-success show-danger'); - password_confirm_notify.parent().removeClass('show-success show-danger'); - passwordsmatch = false; - passwordvalid = false; - }); + }) + .then(() => { + if (parseInt(app.user.uid, 10) === parseInt(ajaxify.data.uid, 10)) { + window.location.href = config.relative_path + '/login'; + } else { + ajaxify.go('user/' + ajaxify.data.userslug + '/edit'); + } + }) + .finally(() => { + btn.removeClass('disabled').find('i').addClass('hide'); + currentPassword.val(''); + password.val(''); + password_confirm.val(''); + password_notify.parent().removeClass('show-success show-danger'); + password_confirm_notify.parent().removeClass('show-success show-danger'); + passwordsmatch = false; + passwordvalid = false; + }); } else { if (!passwordsmatch) { app.alertError('[[user:change_password_error_match]]'); diff --git a/public/src/client/account/edit/username.js b/public/src/client/account/edit/username.js index a40d5d0598b4..56bc52c6192e 100644 --- a/public/src/client/account/edit/username.js +++ b/public/src/client/account/edit/username.js @@ -26,7 +26,7 @@ define('forum/account/edit/username', [ var btn = $(this); btn.addClass('disabled').find('i').removeClass('hide'); - api.put('/users/' + userData.uid, userData, (res) => { + api.put('/users/' + userData.uid, userData).then((res) => { btn.removeClass('disabled').find('i').addClass('hide'); var userslug = slugify(userData.username); if (userData.username && userslug && parseInt(userData.uid, 10) === parseInt(app.user.uid, 10)) { @@ -38,7 +38,7 @@ define('forum/account/edit/username', [ } ajaxify.go('user/' + userslug + '/edit'); - }, 'default'); + }); return false; }); diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 2d350b329c9a..316e6a409c20 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -152,13 +152,13 @@ define('forum/account/header', [ api.put('/users/' + theirid + '/ban', { until: until, reason: formData.reason || '', - }, () => { + }).then(() => { if (typeof onSuccess === 'function') { return onSuccess(); } ajaxify.refresh(); - }, 'default'); + }); }, }, }, @@ -167,9 +167,9 @@ define('forum/account/header', [ } function unbanAccount() { - api.del('/users/' + ajaxify.data.theirid + '/ban', undefined, () => { + api.del('/users/' + ajaxify.data.theirid + '/ban').then(() => { ajaxify.refresh(); - }, 'default'); + }); } function flagAccount() { diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index 1253b5dfc766..493750b671c4 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -106,13 +106,14 @@ define('forum/groups/details', [ break; case 'join': // intentional fall-throughs! - api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined, () => ajaxify.refresh(), 'default'); + api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(() => ajaxify.refresh()); break; case 'leave': - api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined, () => ajaxify.refresh(), 'default'); + api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(() => ajaxify.refresh()); break; + // TODO (14/10/2020): rewrite these to use api module and merge with above 2 case blocks case 'accept': // intentional fall-throughs! case 'reject': case 'issueInvite': diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 506411e74d59..e0fc142f91dc 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -14,9 +14,9 @@ define('forum/groups/list', [ if (name && name.length) { api.post('/groups', { name: name, - }, (res) => { + }).then((res) => { ajaxify.go('groups/' + res.slug); - }, 'default'); + }); } }); }); diff --git a/public/src/client/groups/memberlist.js b/public/src/client/groups/memberlist.js index 6206a4c33556..3952aab30043 100644 --- a/public/src/client/groups/memberlist.js +++ b/public/src/client/groups/memberlist.js @@ -82,13 +82,7 @@ define('forum/groups/memberlist', ['api'], function (api) { if (groupName === 'administrators') { socket.emit('admin.user.makeAdmins', uids, done); } else { - var requests = uids.map(function (uid) { - return api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + uid); - }); - - $.when(requests) - .done(done) - .fail('default'); + Promise.all(uids.map(uid => api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + uid))).then(done); } } diff --git a/public/src/modules/api.js b/public/src/modules/api.js index 26796c07df5b..2776b8ee747c 100644 --- a/public/src/modules/api.js +++ b/public/src/modules/api.js @@ -4,24 +4,33 @@ define('api', () => { const api = {}; const baseUrl = config.relative_path + '/api/v3'; - function call(options, onSuccess, onError) { - $.ajax(Object.assign({ - headers: { - 'x-csrf-token': config.csrf_token, - }, - }, options)) - .done((res) => { - if (onSuccess) { - onSuccess(res.response); - } - }) - .fail((ev) => { - if (onError === 'default') { - app.alertError(ev.responseJSON.status.message); - } else if (onError) { - onError(ev.responseJSON); - } - }); + function call(options, callback) { + return new Promise((resolve, reject) => { + $.ajax(Object.assign({ + headers: { + 'x-csrf-token': config.csrf_token, + }, + }, options)) + .done((res) => { + resolve(res.response); + + if (callback) { + callback(undefined, res.response); + } + }) + .fail((ev) => { + const error = new Error(ev.responseJSON.status.message); + reject(error); + + if (!utils.hasLanguageKey(ev.responseJSON.status.message)) { + app.alertError(ev.responseJSON.status.message); + } + + if (callback) { + callback(error); + } + }); + }); } api.get = (route, payload, onSuccess, onError) => call({