Added basic profile editing support

This commit is contained in:
Thomas Mathews 2022-12-24 08:01:36 -08:00
parent 153d69f33d
commit 1b4d539eef
7 changed files with 108 additions and 25 deletions

View file

@ -440,15 +440,6 @@ details.cw summary {
textarea.post-input {
display: block;
width: 100%;
border: none;
background: transparent;
color: var(--clrText);
font-size: var(--fsEnlarged);
font-family: var(--ffDefault);
margin: 10px 0;
padding: 0;
box-sizing: border-box;
resize: vertical;
}
.post-tools {
@ -513,6 +504,45 @@ label[role="profile-nip5"] {
height: 100%;
}
/* Profile Editor */
#profile-editor header {
margin-bottom: 15px;
}
#profile-editor textarea {
margin: 15px 0;
}
/* Inputs */
.block {
display: block;
}
.w100 {
width: 100%;
}
input[type="text"] {
background: transparent;
border: none;
color: var(--clrText);
font-size: var(--fsNormal);
padding: 15px;
border-bottom: 3px white solid;
box-sizing: border-box;
}
textarea {
border: none;
background: transparent;
color: var(--clrText);
font-size: var(--fsEnlarged);
font-family: var(--ffDefault);
margin: 10px 0;
padding: 0;
box-sizing: border-box;
resize: vertical;
}
@media (prefers-color-scheme: dark) {
.icon.svg {
filter: invert(1);

1
icon/edit-profile.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M223.1 256c70.7 0 128-57.31 128-128s-57.3-128-128-128C153.3 0 96 57.31 96 128S153.3 256 223.1 256zM274.7 304H173.3C77.61 304 0 381.7 0 477.4C0 496.5 15.52 512 34.66 512h286.4c-1.246-5.531-1.43-11.31-.2832-17.04l14.28-71.41c1.943-9.723 6.676-18.56 13.68-25.56l45.72-45.72C363.3 322.4 321.2 304 274.7 304zM371.4 420.6c-2.514 2.512-4.227 5.715-4.924 9.203l-14.28 71.41c-1.258 6.289 4.293 11.84 10.59 10.59l71.42-14.29c3.482-.6992 6.682-2.406 9.195-4.922l125.3-125.3l-72.01-72.01L371.4 420.6zM629.5 255.7l-21.1-21.11c-14.06-14.06-36.85-14.06-50.91 0l-38.13 38.14l72.01 72.01l38.13-38.13C643.5 292.5 643.5 269.7 629.5 255.7z"/></svg>

After

Width:  |  Height:  |  Size: 867 B

View file

@ -137,6 +137,9 @@
<button class="icon" title="Message User" role="message-user">
<img class="icon" src="icon/message-user.svg"/></button>
-->
<button class="icon hide" role="edit-profile"
onclick="show_profile_editor()" title="Edit Profile">
<img class="icon svg" src="icon/edit-profile.svg"/></button>
<button class="icon" role="copy-pk"
data-pk="" onclick="click_copy_pk(this)" title="Copy Public Key">
<img class="icon svg" src="icon/pubkey.svg"/></button>
@ -193,6 +196,26 @@
</div>
</div>
<div id="profile-editor" class="modal closed">
<div class="modal-content">
<header>
<label>Update Profile</label>
<button class="icon" onclick="close_modal(this)">
<img class="icon svg" src="icon/close-modal.svg"/>
</button>
</header>
<div>
<input type="text" class="block w100" name="name" placeholder="Name"/>
<input type="text" class="block w100" name="picture" placeholder="Picture URL"/>
<input type="text" class="block w100" name="nip05" placeholder="nip05"/>
<textarea name="about" class="block w100" placeholder="A bit about you."></textarea>
<button class="action float-right" onclick="click_update_profile()">
Update
</button>
</div>
</div>
</div>
<div id="faqs" class="modal scrollable closed">
<button class="icon modal-floating-close-btn" onclick="close_modal(this)">
<img class="icon svg" src="icon/close-modal.svg"/>

View file

@ -62,22 +62,18 @@ function broadcast_event(ev) {
DAMUS.pool.send(["EVENT", ev])
}
async function update_profile() {
const kind = 0
const created_at = new_creation_time()
const pubkey = await get_pubkey()
const content = JSON.stringify({
name: "test",
about: "Testing",
picture: "",
nip05: ""
})
let ev = { pubkey, content, created_at, kind }
async function update_profile(profile={}) {
let ev = {
kind: KIND_METADATA,
created_at: new_creation_time(),
pubkey: DAMUS.pubkey,
content: JSON.stringify(profile),
tags: [],
};
ev.id = await nostrjs.calculate_id(ev)
ev = await sign_event(ev)
model_get_my_relay(DAMUS, );
// TODO add error checking on updating profile
broadcast_event(ev);
return ev;
}
async function sign_event(ev) {

View file

@ -89,6 +89,7 @@ async function webapp_init() {
pool.on("event", on_pool_event);
pool.on("notice", on_pool_notice);
pool.on("eose", on_pool_eose);
pool.on("ok", on_pool_ok);
// Load all events from storage and re-process them so that apply correct
// effects.
@ -199,6 +200,10 @@ function on_pool_event(relay, sub_id, ev) {
model_process_event(model, relay, ev);
}
function on_pool_ok(relay, evid, status) {
log_debug(`OK(${relay.url}): ${evid} = '${status}'`);
}
function fetch_profiles(pool, relay, pubkeys) {
log_debug(`(${relay.url}) fetching '${pubkeys.length} profiles'`);
pool.subscribe(SID_PROFILES, [{

View file

@ -250,8 +250,7 @@ Relay.prototype.send = async function relay_send(data) {
this.ws.send(JSON.stringify(data))
}
function handle_nostr_message(relay, msg)
{
function handle_nostr_message(relay, msg) {
let data
try {
data = JSON.parse(msg.data)
@ -269,6 +268,8 @@ function handle_nostr_message(relay, msg)
return relay.onfn.eose && relay.onfn.eose(data[1])
case "NOTICE":
return relay.onfn.notice && relay.onfn.notice(...data.slice(1))
case "OK":
return relay.onfn.ok && relay.onfn.ok(...data.slice(1));
}
}
}

View file

@ -317,6 +317,8 @@ function view_update_profile(model, pubkey) {
el_desc.classList.toggle("hide", !profile.about);
find_node("button[role='copy-pk']", el).dataset.pk = pubkey;
find_node("button[role='edit-profile']", el)
.classList.toggle("hide", pubkey != model.pubkey);
const btn_follow = find_node("button[role='follow-user']", el)
btn_follow.dataset.pk = pubkey;
@ -324,3 +326,28 @@ function view_update_profile(model, pubkey) {
btn_follow.innerText = contact_is_friend(DAMUS.contacts, pubkey) ? "Unfollow" : "Follow";
btn_follow.classList.toggle("hide", pubkey == DAMUS.pubkey);
}
const PROFILE_FIELDS = ['name', 'picture', 'nip05', 'about'];
function show_profile_editor() {
const p = DAMUS.profiles[DAMUS.pubkey];
const el = find_node("#profile-editor");
el.classList.remove("closed");
for (const key of PROFILE_FIELDS) {
find_node(`[name='${key}']`, el).value = p[key];
}
}
function click_update_profile() {
const el = find_node("#profile-editor");
const btn = find_node("button.action", el);
const p = {
name: find_node("input[name='name']", el).value,
picture: find_node("input[name='picture']", el).value,
nip05: find_node("input[name='nip05']", el).value,
about: find_node("textarea[name='about']", el).value,
};
update_profile(p);
close_modal(el);
// TODO show toast that say's "broadcasted!"
}