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%; font-size: 140%;
} }
/* Icon menus */ /* Icon menus */
.icon-menu .option { .icon-menu .option {
@ -870,6 +871,35 @@ button:hover,
.right-column .button { .right-column .button {
padding: 2px 6px; 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 */ /* Logged out homepage */
@ -933,6 +963,32 @@ h1.identity small {
margin: 0 0 10px 0; 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 { .system-note {
background: var(--color-bg-menu); background: var(--color-bg-menu);
color: var(--color-text-dull); color: var(--color-text-dull);
@ -1602,3 +1658,7 @@ form .post {
.debug-section .hidden { .debug-section .hidden {
display: none; 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 %} {% endif %}
{% if identity.metadata %} {% if identity.metadata %}
<table class="metadata"> <div class="identity-metadata">
{% for entry in identity.safe_metadata %} {% for entry in identity.safe_metadata %}
<tr> <div class="metadata-pair">
<th>{{ entry.name }}</td> <span class="metadata-name">{{ entry.name }}</span>
<td>{{ entry.value }}</td> <span class="metadata-value">{{ entry.value }}</span>
</tr> </div>
{% endfor %} {% endfor %}
</table> </div>
{% endif %} {% endif %}
{% if identity.local and identity.config_identity.visible_follows %} {% if identity.local and identity.config_identity.visible_follows %}

View file

@ -3,15 +3,19 @@
{% block subtitle %}Profile{% endblock %} {% block subtitle %}Profile{% endblock %}
{% block content %} {% block content %}
<form action="." method="POST" enctype="multipart/form-data" > <form action="." method="POST" enctype="multipart/form-data"
_="on submit metadata.collectMetadataFields()">
{% csrf_token %} {% csrf_token %}
<fieldset> <fieldset>
<legend>Details</legend> <legend>Details</legend>
{% include "forms/_field.html" with field=form.name %} {% include "forms/_field.html" with field=form.name %}
{% include "forms/_field.html" with field=form.summary %} {% 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.discoverable %}
{% include "forms/_field.html" with field=form.visible_follows %} {% include "forms/_field.html" with field=form.visible_follows %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>Images</legend> <legend>Images</legend>
{% include "forms/_field.html" with field=form.icon %} {% 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")]), widget=forms.Select(choices=[(True, "Visible"), (False, "Hidden")]),
required=False, 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): def get_initial(self):
identity = self.request.identity identity = self.request.identity
@ -57,6 +63,7 @@ class ProfilePage(FormView):
"image": identity.image and identity.image.url, "image": identity.image and identity.image.url,
"discoverable": identity.discoverable, "discoverable": identity.discoverable,
"visible_follows": identity.config_identity.visible_follows, "visible_follows": identity.config_identity.visible_follows,
"metadata": identity.metadata,
} }
def form_valid(self, form): def form_valid(self, form):
@ -78,6 +85,9 @@ class ProfilePage(FormView):
image.name, image.name,
resize_image(image, size=(1500, 500)), resize_image(image, size=(1500, 500)),
) )
metadata = form.cleaned_data.get("metadata")
if metadata:
identity.metadata = metadata
identity.save() identity.save()
identity.transition_perform(IdentityStates.edited) identity.transition_perform(IdentityStates.edited)