diff --git a/api/src/api/me.js b/api/src/api/me.js index 2c8479c..3cb347a 100644 --- a/api/src/api/me.js +++ b/api/src/api/me.js @@ -217,6 +217,24 @@ module.exports = { delete data.account.username return res.json(data) }], + post: [auth.enforceSession, async (req, res) => { + if (req.body.field === undefined || + req.body.value === undefined) + return res.status(400).json({ error: 'invalid_params' }) + + const pfilter = { + id: apID(res.locals.user.username), + type: "Person", + } + if (req.body.field === 'name') { + if (req.body.value.match(/^[a-zA-Z0-9\_\s]+$/)) { + await db.table.objects().updateOne(pfilter, + { $set: { name: [req.body.value.trim()] }}) + return res.json({ result: 1 }) + } + } + return res.status(400).json({ error: 'invalid_params' }) + }], }, pending_follows: { get: [auth.enforceSession, async (req, res) => { diff --git a/api/src/server.js b/api/src/server.js index 4fb9e26..f963ab7 100644 --- a/api/src/server.js +++ b/api/src/server.js @@ -73,6 +73,7 @@ app.on('apex-inbox', activity.federation.inbox) .post(api.me.quizs.post) /* ALL */ app.route(api.v1('/me/profile')) .get(api.me.profile.get) + .post(api.me.profile.post) /* POST */ app.route(api.v1('/accounts/follow')).post(api.accounts.follow.post) /* POST */ app.route(api.v1('/accounts/unfollow')).post(api.accounts.unfollow.post) /* POST */ app.route(api.v1('/accounts/block')).post(api.accounts.block.post) diff --git a/web/src/app/css/app.css b/web/src/app/css/app.css index df9b4f2..ce986c3 100644 --- a/web/src/app/css/app.css +++ b/web/src/app/css/app.css @@ -229,7 +229,8 @@ main { padding: .5em !important; } .overlay #input-text { - margin-top: 3em; + max-width: var(--content_max_width); + margin: 3em auto; } .button span { diff --git a/web/src/app/css/base.css b/web/src/app/css/base.css index 0dc8ec1..2e71e38 100644 --- a/web/src/app/css/base.css +++ b/web/src/app/css/base.css @@ -15,6 +15,7 @@ body { .flex > .center { margin: auto } .flex > .center-v { margin: auto 0 } .flex > .center-h { margin: 0 auto } +.flex > .center-f { margin: auto !important } .width-max { width: 100% } .height-max { height: 100% } diff --git a/web/src/app/js/base.js b/web/src/app/js/base.js index 12ae317..36a0515 100644 --- a/web/src/app/js/base.js +++ b/web/src/app/js/base.js @@ -237,6 +237,7 @@ function capitalize(s) { return s.charAt(0).toUpperCase() + s.substr(1) } function randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min) } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } async function waitUntil(cback, ticks, ts) { + ticks = ticks || 10; ts = ts || 1000; var i = 0; while (i < ticks) { diff --git a/web/src/app/js/pages/settings.js b/web/src/app/js/pages/settings.js index a49ab3a..7c42143 100644 --- a/web/src/app/js/pages/settings.js +++ b/web/src/app/js/pages/settings.js @@ -46,10 +46,31 @@ app.pages.settings = { action: 'page().actions.profile.changeName.save()', }, { dark: true, removable: true }); }, - save: function() { - console.log('save'); + save: async function() { + const result = await page().actions.profile + .change('name', window._form.value); + if (result) { + page().data.profile.account + .name = window._form.value.trim(); + page().paint.profile(); + } + return result; }, }, + change: async function(field, value) { + document.activeElement.blur(); + var res = 0; const p = { field, value }; + http.post('/api/v1/me/profile', p, function(json) { + if (json.result === 1) + res = true; + else { + app.toast.error(s('app.error.invalid_params')) + res = false; + } + }); + await waitUntil(function(){ return res !== 0 }); + return res; + }, }, }, } diff --git a/web/src/app/js/templates/overlay/input.html b/web/src/app/js/templates/overlay/input.html index 36f5f6d..8c1eba5 100644 --- a/web/src/app/js/templates/overlay/input.html +++ b/web/src/app/js/templates/overlay/input.html @@ -2,25 +2,31 @@ window._form = { onSubmit: function() { + if (!window._form.onValidate()) + return false; + window._form._onSubmit(); + return false; + }, + _onSubmit: async function() { let result; if ('{.action}' === '{::action}'.replace('::', '.')) result = false; - else result = eval('{.action}'); - if (result === undefined) - result = false; + else result = await eval('{.action}'); if (result === true) { setTimeout(function() { app.overlay.remove('{.oid}'); delete window._form; - }, 10); + }, 2); } - return false; }, onValidate: function(value) { + value = value || window._form.value; return value !== window._form.initialValue + && value !== null && value.trim() !== ''; }, onTextInput: function(e) { + window._form.value = e.target.value; const asubmit = document.querySelector('#input-text *[onclick*="onSubmit"]'); if (window._form.onValidate(e.target.value)) { asubmit.querySelector('.fa-check').style.color = '#51aa14'; @@ -30,6 +36,7 @@ window._form = { asubmit.classList.add('disabled'); } }, + value: null, initialValue: null, }; @@ -39,7 +46,7 @@ window._onOverlayRemove = function() { const el = document.querySelector('#input-{.type}'); if (el !== null) { - el.removeAttribute('style'); + el.style.removeProperty('display'); if ('{.type}' === 'text') { const text = el.querySelector('input[type="text"]'); window._form.initialValue = text.value; @@ -53,13 +60,14 @@ if (el !== null) { class="panel flex" onclick="event.stopPropagation()">
- -
+
diff --git a/web/src/config/lang/en.php b/web/src/config/lang/en.php index af6519f..39b7d0e 100644 --- a/web/src/config/lang/en.php +++ b/web/src/config/lang/en.php @@ -55,6 +55,7 @@ $strings = [ 'already_following' => 'This person has already accepted being your crush', ], 'error' => [ + 'invalid_params' => 'The field values provided are not valid.', 'unknown_error' => 'We are sorry, an unknown error has ocurred.', 'follow_pending' => 'This person has not yet accepted to be your crush', 'follow_rejected_max' => 'You have reached the limit of crush requests on this person', diff --git a/web/src/config/lang/es.php b/web/src/config/lang/es.php index b9292e5..01b0648 100644 --- a/web/src/config/lang/es.php +++ b/web/src/config/lang/es.php @@ -55,6 +55,7 @@ $strings = [ 'already_following' => 'Esta persona ya te ha aceptado como su crush', ], 'error' => [ + 'invalid_params' => 'Los valores de los campos introducidos no son válidos.', 'unknown_error' => 'Lo sentimos, ha ocurrido un error inesperado.', 'follow_pending' => 'Esta persona todavía no ha aceptado ser tu crush', 'follow_rejected_max' => 'Has alcanzado el límite de peticiones de crush para esta persona',