Added settings.profile method and API to modify account ".name"

* Also added the needed framework for future value modifications
* TODO: send profile update notification to following servers
This commit is contained in:
Niko 2022-03-20 02:58:29 +01:00
parent 4a29977bb1
commit f6e673f795
9 changed files with 65 additions and 12 deletions

View File

@ -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) => {

View File

@ -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)

View File

@ -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 {

View File

@ -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% }

View File

@ -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) {

View File

@ -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;
},
},
},
}

View File

@ -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()">
<form class="flex center text-center width-max" style="max-width:35em"
onsubmit="return window._form.onSubmit()">
<input type="text" name="text" class="card-item width-max"
<input type="text" name="text" class="card-item center-f width-max"
placeholder="{.placeholder}" value="{.value}"
onkeyup="window._form.onTextInput(event)"/>
<a class="component icon button noback dark round flex disabled"
style="width: 2.5em;height: 2.5em;display: inline-block;"
style="display: inline-block; margin-left: .5em"
title="{s:form.save}" onclick="window._form.onSubmit()">
<div class="ic-container center flex size-max">
<div class="ic-container center flex size-max"
style="width: 2.5em;height: 2.5em">
<i class="center fa fa-check fa-fw"
style="font-size: 1.2em;"></i>
</div>

View File

@ -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',

View File

@ -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',