From d044c3223ea9dde59978a6f1e876108279cf8a7d Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 1 Oct 2020 14:09:44 -0400 Subject: [PATCH] feat(writeapi): abstracted ajax calls out to new api module --- public/src/admin/manage/categories.js | 18 ++---- public/src/admin/manage/category.js | 66 ++++++++-------------- public/src/admin/manage/groups.js | 20 +++---- public/src/admin/manage/users.js | 28 +++------ public/src/client/account/edit.js | 27 +++++---- public/src/client/account/edit/email.js | 15 ++--- public/src/client/account/edit/password.js | 19 ++----- public/src/client/account/edit/username.js | 13 +---- public/src/client/account/header.js | 38 ++++--------- public/src/client/groups/list.js | 21 ++----- public/src/modules/api.js | 45 +++++++++++++++ src/controllers/write/categories.js | 2 +- src/routes/write/groups.js | 1 + src/routes/write/users.js | 2 +- 14 files changed, 137 insertions(+), 178 deletions(-) create mode 100644 public/src/modules/api.js diff --git a/public/src/admin/manage/categories.js b/public/src/admin/manage/categories.js index 701024c842..6209112d7a 100644 --- a/public/src/admin/manage/categories.js +++ b/public/src/admin/manage/categories.js @@ -5,7 +5,9 @@ define('admin/manage/categories', [ 'translator', 'benchpress', 'categorySelector', -], function (serialize, translator, Benchpress, categorySelector) { + 'sortablejs', + 'api', +], function (serialize, translator, Benchpress, categorySelector, api) { var Categories = {}; var newCategoryId = -1; var sortables; @@ -196,12 +198,8 @@ define('admin/manage/categories', [ Categories.toggle = function (cids, disabled) { var requests = cids.map(function (cid) { - return $.ajax({ - url: config.relative_path + '/api/v1/categories/' + cid, - method: 'put', - data: { - disabled: disabled ? 1 : 0, - }, + return api.put('/categories/' + cid, { + disabled: disabled ? 1 : 0, }); }); @@ -238,11 +236,7 @@ define('admin/manage/categories', [ newCategoryId = -1; Object.keys(modified).forEach(function (cid) { - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + cid, - method: 'put', - data: modified[cid], - }); + api.put('/categories/' + cid, modified[cid]); }); } } diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 7887f197c9..8bec2edc21 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -6,7 +6,8 @@ define('admin/manage/category', [ 'admin/modules/colorpicker', 'categorySelector', 'benchpress', -], function (uploader, iconSelect, colorpicker, categorySelector, Benchpress) { + 'api', +], function (uploader, iconSelect, colorpicker, categorySelector, Benchpress, api) { var Category = {}; var updateHash = {}; @@ -54,21 +55,17 @@ define('admin/manage/category', [ } var cid = ajaxify.data.category.cid; - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + cid, - method: 'put', - data: updateHash, - }).done(function (res) { + api.put('/categories/' + cid, updateHash, (res) => { app.flags._unsaved = false; app.alert({ title: 'Updated Categories', - message: 'Category "' + res.response.name + '" was successfully updated.', + message: 'Category "' + res.name + '" was successfully updated.', type: 'success', timeout: 2000, }); updateHash = {}; - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); + }, (err) => { + app.alertError(err.status.message); }); return false; @@ -107,18 +104,15 @@ define('admin/manage/category', [ }); }, 1000); - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + ajaxify.data.category.cid, - method: 'delete', - }).done(function () { + api.del('/categories/' + ajaxify.data.category.cid, undefined, () => { if (intervalId) { clearInterval(intervalId); } modal.modal('hide'); app.alertSuccess('[[admin/manage/categories:alert.purge-success]]'); ajaxify.go('admin/manage/categories'); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); + }, (err) => { + app.alertError(err.status.message); }); return false; @@ -225,35 +219,27 @@ define('admin/manage/category', [ $('button[data-action="setParent"], button[data-action="changeParent"]').on('click', Category.launchParentSelector); $('button[data-action="removeParent"]').on('click', function () { - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + ajaxify.data.category.cid, - method: 'put', - data: { - parentCid: 0, - }, - }).done(function () { + api.put('/categories/' + ajaxify.data.category.cid, { + parentCid: 0, + }, () => { $('button[data-action="removeParent"]').parent().addClass('hide'); $('button[data-action="changeParent"]').parent().addClass('hide'); $('button[data-action="setParent"]').removeClass('hide'); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); + }, (err) => { + app.alertError(err.message); }); }); $('button[data-action="toggle"]').on('click', function () { var $this = $(this); var disabled = $this.attr('data-disabled') === '1'; - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + ajaxify.data.category.cid, - method: 'put', - data: { - disabled: disabled ? 0 : 1, - }, - }).done(function () { + api.put('/categories/' + ajaxify.data.category.cid, { + disabled: disabled ? 0 : 1, + }, () => { $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); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); + }, (err) => { + app.alertError(err.message); }); }); }; @@ -303,13 +289,9 @@ define('admin/manage/category', [ }); categorySelector.modal(categories, function (parentCid) { - $.ajax({ - url: config.relative_path + '/api/v1/categories/' + ajaxify.data.category.cid, - method: 'put', - data: { - parentCid: parentCid, - }, - }).done(function () { + api.put('/categories/' + ajaxify.data.category.cid, { + parentCid: parentCid, + }, () => { var parent = allCategories.filter(function (category) { return category && parseInt(category.cid, 10) === parseInt(parentCid, 10); }); @@ -319,8 +301,8 @@ define('admin/manage/category', [ $('button[data-action="setParent"]').addClass('hide'); var buttonHtml = ' ' + parent.name; $('button[data-action="changeParent"]').html(buttonHtml).parent().removeClass('hide'); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); + }, (err) => { + app.alertError(err.message); }); }); }); diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index 42c517c08c..cfa3e69699 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -1,9 +1,9 @@ 'use strict'; - define('admin/manage/groups', [ 'categorySelector', -], function (categorySelector) { + 'api', +], function (categorySelector, api) { var Groups = {}; var intervalId = 0; @@ -37,22 +37,18 @@ define('admin/manage/groups', [ hidden: $('#create-group-hidden').is(':checked') ? 1 : 0, }; - $.ajax({ - url: config.relative_path + '/api/v1/groups', - method: 'post', - data: submitObj, - }).done(function (res) { + api.post('/groups', submitObj, (response) => { createModalError.addClass('hide'); createGroupName.val(''); createModal.on('hidden.bs.modal', function () { - ajaxify.go('admin/manage/groups/' + res.response.name); + ajaxify.go('admin/manage/groups/' + response.name); }); createModal.modal('hide'); - }).fail(function (ev) { - if (utils.hasLanguageKey(ev.responseJSON.status.message)) { - ev.responseJSON.status.message = '[[admin/manage/groups:alerts.create-failure]]'; + }, (err) => { + if (!utils.hasLanguageKey(err.status.message)) { + err.status.message = '[[admin/manage/groups:alerts.create-failure]]'; } - createModalError.translateHtml(ev.responseJSON.status.message).removeClass('hide'); + createModalError.translateHtml(err.status.message).removeClass('hide'); }); }); diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index 3a3dd11fb8..b7cad08308 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -1,6 +1,6 @@ 'use strict'; -define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], function (translator, Benchpress, autocomplete) { +define('admin/manage/users', ['translator', 'benchpress', 'autocomplete', 'api'], function (translator, Benchpress, autocomplete, api) { var Users = {}; Users.init = function () { @@ -133,10 +133,7 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct 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) { - return $.ajax({ - url: config.relative_path + '/api/v1/users/' + uid + '/ban', - method: 'put', - }); + return api.put('/users/' + uid + '/ban'); }); $.when(requests) @@ -178,13 +175,9 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct 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) { - return $.ajax({ - url: config.relative_path + '/api/v1/users/' + uid + '/ban', - method: 'put', - data: { - until: until, - reason: formData.reason, - }, + return api.put('/users/' + uid + '/ban', { + until: until, + reason: formData.reason, }); }); @@ -209,10 +202,7 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct } var requests = uids.map(function (uid) { - return $.ajax({ - url: config.relative_path + '/api/v1/users/' + uid + '/ban', - method: 'delete', - }); + return api.delete('/users/' + uid + '/ban'); }); $.when(requests) @@ -408,15 +398,13 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct password: password, }; - $.post(config.relative_path + '/api/v1/users', user).done(function () { + api.post('/users', user, () => { modal.modal('hide'); modal.on('hidden.bs.modal', function () { ajaxify.refresh(); }); app.alertSuccess('[[admin/manage/users:alerts.create-success]]'); - }).fail(function (ev) { - return errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + ev.responseJSON.status.message + ']]').removeClass('d-none').addClass('d-block'); - }); + }, err => errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.status.message + ']]').removeClass('hidden')); } var timeoutId = 0; diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index b075a18302..ac3ab10b1a 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -1,7 +1,12 @@ 'use strict'; - -define('forum/account/edit', ['forum/account/header', 'translator', 'components', 'pictureCropper', 'benchpress'], function (header, translator, components, pictureCropper, Benchpress) { +define('forum/account/edit', [ + 'forum/account/header', + 'translator', + 'pictureCropper', + 'benchpress', + 'api', +], function (header, translator, pictureCropper, Benchpress, api) { var AccountEdit = {}; AccountEdit.init = function () { @@ -42,21 +47,15 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components' $(window).trigger('action:profile.update', userData); - $.ajax({ - url: config.relative_path + '/api/v1/users/' + userData.uid, - data: userData, - method: 'put', - }).done(function (res) { - app.alertSuccess('[[user:profile_update_success]]'); + api.put('/users/' + userData.uid, userData, (res) => { + app.alertSuccess('[[user:profile-update-success]]'); - if (res.response.picture) { - $('#user-current-picture').attr('src', res.response.picture); + if (res.picture) { + $('#user-current-picture').attr('src', res.picture); } - updateHeader(res.response.picture); - }).fail(function (ev) { - return app.alertError(ev.responseJSON.status.message); - }); + updateHeader(res.picture); + }, err => app.alertError(err.status.message)); return false; } diff --git a/public/src/client/account/edit/email.js b/public/src/client/account/edit/email.js index aa905f0824..7a1959dd6e 100644 --- a/public/src/client/account/edit/email.js +++ b/public/src/client/account/edit/email.js @@ -1,7 +1,6 @@ 'use strict'; - -define('forum/account/edit/email', ['forum/account/header'], function (header) { +define('forum/account/edit/email', ['forum/account/header', 'api'], function (header, api) { var AccountEditEmail = {}; AccountEditEmail.init = function () { @@ -27,16 +26,10 @@ define('forum/account/edit/email', ['forum/account/header'], function (header) { var btn = $(this); btn.addClass('disabled').find('i').removeClass('hide'); - $.ajax({ - url: config.relative_path + '/api/v1/users/' + userData.uid, - data: userData, - method: 'put', - }).done(function (res) { + api.put('/users/' + userData.uid, userData, (res) => { btn.removeClass('disabled').find('i').addClass('hide'); - ajaxify.go('user/' + res.response.userslug + '/edit'); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + ajaxify.go('user/' + res.userslug + '/edit'); + }, err => app.alertError(err.status.message)); return false; }); diff --git a/public/src/client/account/edit/password.js b/public/src/client/account/edit/password.js index fc6b9ef4d4..b3254967d9 100644 --- a/public/src/client/account/edit/password.js +++ b/public/src/client/account/edit/password.js @@ -1,7 +1,6 @@ 'use strict'; - -define('forum/account/edit/password', ['forum/account/header', 'translator', 'zxcvbn'], function (header, translator, zxcvbn) { +define('forum/account/edit/password', ['forum/account/header', 'translator', 'zxcvbn', 'api',], function (header, translator, zxcvbn, api) { var AccountEditPassword = {}; AccountEditPassword.init = function () { @@ -67,22 +66,16 @@ define('forum/account/edit/password', ['forum/account/header', 'translator', 'zx var btn = $(this); if (passwordvalid && passwordsmatch) { btn.addClass('disabled').find('i').removeClass('hide'); - $.ajax({ - url: config.relative_path + '/api/v1/users/' + ajaxify.data.theirid + '/password', - method: 'put', - data: { - currentPassword: currentPassword.val(), - newPassword: password.val(), - }, - }).done(function () { + 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'); } - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }).always(function () { + }, err => app.alertError(err.status.message)).always(() => { btn.removeClass('disabled').find('i').addClass('hide'); currentPassword.val(''); password.val(''); diff --git a/public/src/client/account/edit/username.js b/public/src/client/account/edit/username.js index 4cb60cf217..5a79f22587 100644 --- a/public/src/client/account/edit/username.js +++ b/public/src/client/account/edit/username.js @@ -1,7 +1,6 @@ 'use strict'; - -define('forum/account/edit/username', ['forum/account/header'], function (header) { +define('forum/account/edit/username', ['forum/account/header', 'api'], function (header, api) { var AccountEditUsername = {}; AccountEditUsername.init = function () { @@ -25,11 +24,7 @@ define('forum/account/edit/username', ['forum/account/header'], function (header var btn = $(this); btn.addClass('disabled').find('i').removeClass('hide'); - $.ajax({ - url: config.relative_path + '/api/v1/users/' + userData.uid, - data: userData, - method: 'put', - }).done(function (res) { + api.put('/users/' + userData.uid, userData, (res) => { btn.removeClass('disabled').find('i').addClass('hide'); var userslug = utils.slugify(userData.username); if (userData.username && userslug && parseInt(userData.uid, 10) === parseInt(app.user.uid, 10)) { @@ -41,9 +36,7 @@ define('forum/account/edit/username', ['forum/account/header'], function (header } ajaxify.go('user/' + userslug + '/edit'); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + }, err => app.alertError(err.status.message)); return false; }); diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 95315d2918..5185b580aa 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -8,7 +8,8 @@ define('forum/account/header', [ 'translator', 'benchpress', 'accounts/delete', -], function (coverPhoto, pictureCropper, components, translator, Benchpress, AccountsDelete) { + 'api', +], function (coverPhoto, pictureCropper, components, translator, Benchpress, AccountsDelete, api) { var AccountHeader = {}; var isAdminOrSelfOrGlobalMod; @@ -115,17 +116,11 @@ define('forum/account/header', [ } function toggleFollow(type) { - $.ajax({ - url: config.relative_path + '/api/v1/users/' + ajaxify.data.uid + '/follow', - method: type === 'follow' ? 'post' : 'delete', - }).done(function () { + api[type === 'follow' ? 'put' : 'delete']('/users/' + ajaxify.data.uid + '/follow', undefined, () => { components.get('account/follow').toggleClass('hide', type === 'follow'); components.get('account/unfollow').toggleClass('hide', type === 'unfollow'); app.alertSuccess('[[global:alert.' + type + ', ' + ajaxify.data.username + ']]'); - }).fail(function (ev) { - console.log(ev); - app.alertError(ev.responseJSON.status.message); - }); + }, err => app.alertError(err.status.message)); return false; } @@ -154,22 +149,16 @@ define('forum/account/header', [ var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0; - $.ajax({ - url: config.relative_path + '/api/v1/users/' + theirid + '/ban', - method: 'put', - data: { - until: until, - reason: formData.reason || '', - }, - }).done(function () { + api.put('/users/' + theirid + '/ban', { + until: until, + reason: formData.reason || '', + }, () => { if (typeof onSuccess === 'function') { return onSuccess(); } ajaxify.refresh(); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + }, err => app.alertError(err.status.message)); }, }, }, @@ -178,14 +167,9 @@ define('forum/account/header', [ } function unbanAccount() { - $.ajax({ - url: config.relative_path + '/api/v1/users/' + ajaxify.data.theirid + '/ban', - method: 'delete', - }).done(function () { + api.del('/users/' + ajaxify.data.theirid + '/ban', undefined, () => { ajaxify.refresh(); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + }, err => app.alertError(err.status.message)); } function flagAccount() { diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 0d7a7da4d3..f159674c33 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -1,7 +1,4 @@ -'use strict'; - - -define('forum/groups/list', ['forum/infinitescroll', 'benchpress'], function (infinitescroll, Benchpress) { +define('forum/groups/list', ['forum/infinitescroll', 'benchpress', 'api'], function (infinitescroll, Benchpress, api) { var Groups = {}; Groups.init = function () { @@ -11,17 +8,11 @@ define('forum/groups/list', ['forum/infinitescroll', 'benchpress'], function (in $('button[data-action="new"]').on('click', function () { bootbox.prompt('[[groups:new-group.group_name]]', function (name) { if (name && name.length) { - $.ajax({ - url: config.relative_path + '/api/v1/groups', - method: 'post', - data: { - name: name, - }, - }).done(function (res) { - ajaxify.go('groups/' + res.response.slug); - }).fail(function (ev) { - app.alertError(ev.responseJSON.status.message); - }); + api.post('/groups', { + name: name, + }, (res) => { + ajaxify.go('groups/' + res.slug); + }, err => app.alertError(err.status.message)); } }); }); diff --git a/public/src/modules/api.js b/public/src/modules/api.js new file mode 100644 index 0000000000..8b268d2620 --- /dev/null +++ b/public/src/modules/api.js @@ -0,0 +1,45 @@ +const baseUrl = config.relative_path + '/api/v1'; + +function call(options, onSuccess, onError) { + $.ajax(options) + .done((res) => { + if (onSuccess) { + onSuccess(res.response); + } + }) + .fail((ev) => { + if (onError) { + onError(ev.responseJSON); + } + }); +} + +export function get(route, payload, onSuccess, onError) { + return call({ + url: baseUrl + route + '?' + $.param(payload), + }, onSuccess, onError); +} + +export function post(route, payload, onSuccess, onError) { + return call({ + url: baseUrl + route, + method: 'post', + data: payload, + }, onSuccess, onError); +} + +export function put(route, payload, onSuccess, onError) { + return call({ + url: baseUrl + route, + method: 'put', + data: payload, + }, onSuccess, onError); +} + +export function del(route, payload, onSuccess, onError) { + return call({ + url: baseUrl + route, + method: 'delete', + data: payload, + }, onSuccess, onError); +} diff --git a/src/controllers/write/categories.js b/src/controllers/write/categories.js index 7643ec027b..dcd0f862ec 100644 --- a/src/controllers/write/categories.js +++ b/src/controllers/write/categories.js @@ -24,7 +24,7 @@ Categories.update = async (req, res) => { Categories.delete = async (req, res) => { const name = await categories.getCategoryField(req.params.cid, 'name'); - await Categories.purge(req.params.cid, req.user.uid); + await categories.purge(req.params.cid, req.user.uid); await events.log({ type: 'category-purge', uid: req.user.uid, diff --git a/src/routes/write/groups.js b/src/routes/write/groups.js index 0811a38038..1356299a7c 100644 --- a/src/routes/write/groups.js +++ b/src/routes/write/groups.js @@ -11,6 +11,7 @@ module.exports = function () { const middlewares = [middleware.authenticate]; setupApiRoute(router, '/', middleware, [...middlewares, middleware.checkRequired.bind(null, ['name']), middleware.exposePrivilegeSet], 'post', controllers.write.groups.create); + // setupApiRoute(router, '/:slug', middleware, [...middlewares, middleware.exposePrivilegeSet], 'delete', controllers.write.groups.delete); // app.delete('/:slug', apiMiddleware.requireUser, middleware.exposeGroupName, apiMiddleware.validateGroup, apiMiddleware.requireGroupOwner, function(req, res) { // Groups.destroy(res.locals.groupName, function(err) { diff --git a/src/routes/write/users.js b/src/routes/write/users.js index 6fa3aad485..c2740e423e 100644 --- a/src/routes/write/users.js +++ b/src/routes/write/users.js @@ -23,7 +23,7 @@ function authenticatedRoutes() { setupApiRoute(router, '/:uid/password', middleware, [...middlewares, middleware.checkRequired.bind(null, ['newPassword'])], 'put', controllers.write.users.changePassword); - setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'post', controllers.write.users.follow); + setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'put', controllers.write.users.follow); setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'delete', controllers.write.users.unfollow); setupApiRoute(router, '/:uid/ban', middleware, [...middlewares, middleware.exposePrivileges], 'put', controllers.write.users.ban);