Identity profile metadata input with dynamic form (#280)

This commit is contained in:
Michael Manfre 2022-12-27 18:56:50 -05:00 committed by GitHub
parent b63ad40f54
commit aa2ace9b68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 7 deletions

View file

@ -434,6 +434,7 @@ p.authorization-code {
font-size: 140%;
}
/* Icon menus */
.icon-menu .option {
@ -870,6 +871,35 @@ button:hover,
.right-column .button {
padding: 2px 6px;
}
form .field.multi-option {
margin-bottom: 10px;
}
form .field.multi-option {
margin-bottom: 10px;
}
form .option.option-row {
margin: 0px 0px 5px 0px;
}
.option-row .right {
float: right;
}
form .option-row .option-field {
vertical-align: middle;
display: inline-block;
line-height: normal;
width: 40%;
min-width: 30px;
padding-left: 0px;
padding-right: 7px;
}
form .option-row .right button {
vertical-align: middle;
margin-top: 0px;
margin-right: 5px;
}
/* Logged out homepage */
@ -933,6 +963,32 @@ h1.identity small {
margin: 0 0 10px 0;
}
.identity-metadata .metadata-pair {
display: block;
margin: 0px 0 10px 0;
background: var(--color-bg-box);
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1);
color: inherit;
text-decoration: none;
padding: 10px 20px;
border: 2px solid rgba(255, 255, 255, 0);
border-radius: 10px;
overflow: hidden;
}
.identity-metadata .metadata-pair .metadata-name {
display: inline-block;
min-width: 80px;
margin-right: 15px;
text-align: right;
color: var(--color-text-dull);
}
.identity-metadata .metadata-pair .metadata-name::after {
padding-left: 3px;
color: var(--color-text-dull);
}
.system-note {
background: var(--color-bg-menu);
color: var(--color-text-dull);
@ -1602,3 +1658,7 @@ form .post {
.debug-section .hidden {
display: none;
}
.field .hidden {
display: none;
}

View file

@ -0,0 +1,72 @@
{% with name_one=field_name_one|default:"name" name_two=field_name_two|default:"value" %}
<script type="text/hyperscript">
def {{ field.name }}.collect{{ field.name|title }}Fields()
set newdata to []
for item in <div.{{ field.name }}-row/>
get the (value of the first <input.{{ field.name }}-{{ name_one }}/> in item)
set n to it
get the (value of the last <input.{{ field.name }}-{{ name_two }}/> in item)
set val to it
if n != '' and val != '' then
append {'{{ name_one }}': n, '{{ name_two }}': val} to newdata
end
set #id_{{ field.name }}@value to newdata as JSON
end
def {{ field.name }}.addEmptyField()
get #blank_{{ field.name }}'s outerHTML
put it before #new_{{ field.name }}
get #new_{{ field.name }}'s previousSibling
set foo to it
set foo@id to ''
remove .hidden from foo
add .{{ field.name }}-row to foo
return foo
end
</script>
{% include "forms/_field.html" %}
<div class="field multi-option">
<section class="icon-menu">
<span id="new_{{ field.name }}" stlye="display: none"
_="on load
get the (value of #id_{{ field.name }}) as Object
set items to it
for item in items
set f to {{ field.name }}.addEmptyField()
set one to the first <input.{{ field.name }}-{{ name_one }}/> in f then
set one@value to item.{{ name_one }}
set two to the first <input.{{ field.name }}-{{ name_two }}/> in f then
set two@value to item.{{ name_two }}
end
"></span>
<div class="option">
<span class="option-field">
<button class="fa-solid fa-add" _="on click {{ field.name }}.addEmptyField() then halt"></button>
</span>
</div>
<div id="blank_{{ field.name }}" class="option option-row hidden">
<span class="option-field">
<input type=text class="{{ field.name }}-{{ name_one }}" name="{{ field.name }}_{{ name_one }}" value="">
</span>
<span class="option-field">
<input type=text class="{{ field.name }}-{{ name_two }}" name="{{ field.name }}_{{ name_two }}" value="">
</span>
<div class="right">
<button class="fa-solid fa-trash delete"
_="on click remove (closest parent .option)
then {{ field.name }}.collect{{ field.name|title }}Fields()
then halt" />
</div>
</div>
</section>
</div>
{% endwith %}

View file

@ -68,14 +68,14 @@
{% endif %}
{% if identity.metadata %}
<table class="metadata">
<div class="identity-metadata">
{% for entry in identity.safe_metadata %}
<tr>
<th>{{ entry.name }}</td>
<td>{{ entry.value }}</td>
</tr>
<div class="metadata-pair">
<span class="metadata-name">{{ entry.name }}</span>
<span class="metadata-value">{{ entry.value }}</span>
</div>
{% endfor %}
</table>
</div>
{% endif %}
{% if identity.local and identity.config_identity.visible_follows %}

View file

@ -3,15 +3,19 @@
{% block subtitle %}Profile{% endblock %}
{% block content %}
<form action="." method="POST" enctype="multipart/form-data" >
<form action="." method="POST" enctype="multipart/form-data"
_="on submit metadata.collectMetadataFields()">
{% csrf_token %}
<fieldset>
<legend>Details</legend>
{% include "forms/_field.html" with field=form.name %}
{% include "forms/_field.html" with field=form.summary %}
{% include "forms/_json_name_value_list.html" with field=form.metadata %}
{% include "forms/_field.html" with field=form.discoverable %}
{% include "forms/_field.html" with field=form.visible_follows %}
</fieldset>
<fieldset>
<legend>Images</legend>
{% include "forms/_field.html" with field=form.icon %}

View file

@ -47,6 +47,12 @@ class ProfilePage(FormView):
widget=forms.Select(choices=[(True, "Visible"), (False, "Hidden")]),
required=False,
)
metadata = forms.JSONField(
label="Profile Metadata Fields",
help_text="These values will appear on your profile below your Bio",
widget=forms.HiddenInput,
required=False,
)
def get_initial(self):
identity = self.request.identity
@ -57,6 +63,7 @@ class ProfilePage(FormView):
"image": identity.image and identity.image.url,
"discoverable": identity.discoverable,
"visible_follows": identity.config_identity.visible_follows,
"metadata": identity.metadata,
}
def form_valid(self, form):
@ -78,6 +85,9 @@ class ProfilePage(FormView):
image.name,
resize_image(image, size=(1500, 500)),
)
metadata = form.cleaned_data.get("metadata")
if metadata:
identity.metadata = metadata
identity.save()
identity.transition_perform(IdentityStates.edited)