profile: support kind 0 metadata events
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/pr/woodpecker Pipeline was successful Details

Added simple profile form to the setting view to send kind 0
metdata such as: name, about and picture.
OFF0 2 years ago
parent 0047c0bdc0
commit dd1076489f
Signed by: offbyn
GPG Key ID: 94A2F643C51F37FA

@ -45,6 +45,7 @@ label {
input[type="password"], input[type="password"],
input[type="text"], input[type="text"],
input[type="url"],
textarea { textarea {
background: var(--bgcolor-textinput); background: var(--bgcolor-textinput);
border: .2rem solid #b7b7b7; border: .2rem solid #b7b7b7;
@ -55,11 +56,16 @@ textarea {
} }
input[type="password"]:focus, input[type="password"]:focus,
input[type="text"]:focus, input[type="text"]:focus,
input[type="url"]:focus,
textarea:focus { textarea:focus {
border-color: var(--focus-border-color); border-color: var(--focus-border-color);
outline-offset: var(--focus-outline-offset); outline-offset: var(--focus-outline-offset);
outline: var(--focus-outline); outline: var(--focus-outline);
} }
input:invalid {
outline: 2px solid var(--bgcolor-danger);
outline-offset: var(--focus-outline-offset);
}
textarea { textarea {
/* max-height: 64vh; */ /* max-height: 64vh; */
min-height: 20px; min-height: 20px;
@ -137,11 +143,6 @@ button:disabled {
cursor: default; cursor: default;
} }
.inline-text {
display: inline-block;
padding: 0 1ch;
}
.form-status { .form-status {
flex-basis: 100%; flex-basis: 100%;
flex-grow: 1; flex-grow: 1;

@ -59,6 +59,18 @@
<input type="text" name="username" id="username" placeholder="username"> <input type="text" name="username" id="username" placeholder="username">
<button type="button" name="publish-username" tabindex="0">publish</button> <button type="button" name="publish-username" tabindex="0">publish</button>
</div> --> </div> -->
<form action="#" name="profile" autocomplete="new-password">
<label for="profile_name">name</label>
<input type="text" name="name" id="profile_name" autocomplete="off" pattern="[a-zA-Z_0-9][a-zA-Z_\-0-9]+[a-zA-Z_0-9]">
<label for="profile_about">about</label>
<textarea name="about" id="profile_about"></textarea>
<label for="profile_picture">picture</label>
<input type="url" name="picture" id="profile_picture" placeholder="https://your.domain/image.png">
<div class="buttons">
<small id="profilestatus" class="form-status" hidden></small>
<button type="submit" name="publish" tabindex="0" disabled>publish</button>
</div>
</form>
<form action="#" name="settings" autocomplete="new-password"> <form action="#" name="settings" autocomplete="new-password">
<label for="pubkey">public-key</label> <label for="pubkey">public-key</label>
<input type="text" id="pubkey" autocomplete="off"> <input type="text" id="pubkey" autocomplete="off">
@ -72,7 +84,6 @@
<div class="buttons"> <div class="buttons">
<small id="keystatus" class="form-status" hidden></small> <small id="keystatus" class="form-status" hidden></small>
<button type="button" name="generate" tabindex="0">new</button> <button type="button" name="generate" tabindex="0">new</button>
<span class="inline-text"></span>
<button type="button" name="import" tabindex="0" disabled>save</button> <button type="button" name="import" tabindex="0" disabled>save</button>
</div> </div>
</form> </form>

@ -660,3 +660,49 @@ document.body.addEventListener('click', (e) => {
hideNewMessage(true); hideNewMessage(true);
} }
}); });
// profile
const profileForm = document.querySelector('form[name="profile"]');
const profileSubmit = profileForm.querySelector('button[type="submit"]');
const profileStatus = document.querySelector('#profilestatus');
const onProfileError = err => {
profileStatus.hidden = false;
profileStatus.textContent = err.message
};
profileForm.addEventListener('input', (e) => {
if (e.target.nodeName === 'TEXTAREA') {
updateElemHeight(e.target);
}
const form = new FormData(profileForm);
const name = form.get('name');
const about = form.get('about');
const picture = form.get('picture');
profileSubmit.disabled = !(name || about || picture);
});
profileForm.addEventListener('submit', async (e) => {
e.preventDefault();
const form = new FormData(profileForm);
const privatekey = localStorage.getItem('private_key');
const newProfile = {
kind: 0,
pubkey,
content: JSON.stringify(Object.fromEntries(form)),
created_at: Math.floor(Date.now() * 0.001),
tags: [],
};
const sig = await signEvent(newProfile, privatekey).catch(console.error);
if (sig) {
const ev = await pool.publish({...newProfile, sig}, (status, url) => {
if (status === 0) {
console.info(`publish request sent to ${url}`);
}
if (status === 1) {
profileStatus.textContent = 'profile metadata successfully published';
profileStatus.hidden = false;
profileSubmit.disabled = true;
}
}).catch(console.error);
}
});

Loading…
Cancel
Save