diff options
29 files changed, 344 insertions, 246 deletions
diff --git a/activities/views/timelines.py b/activities/views/timelines.py index ae01a45..02afc2c 100644 --- a/activities/views/timelines.py +++ b/activities/views/timelines.py @@ -40,7 +40,7 @@ class Home(FormView): ) .select_related("subject_post", "subject_post__author") .prefetch_related("subject_post__attachments") - .order_by("-created")[:100] + .order_by("-created")[:50] ) context["interactions"] = PostInteraction.get_event_interactions( context["events"], self.request.identity @@ -68,7 +68,7 @@ class Local(TemplateView): Post.objects.filter(visibility=Post.Visibilities.public, author__local=True) .select_related("author") .prefetch_related("attachments") - .order_by("-created")[:100] + .order_by("-created")[:50] ) context["current_page"] = "local" return context @@ -85,7 +85,7 @@ class Federated(TemplateView): Post.objects.filter(visibility=Post.Visibilities.public) .select_related("author") .prefetch_related("attachments") - .order_by("-created")[:100] + .order_by("-created")[:50] ) context["current_page"] = "federated" return context diff --git a/core/models/config.py b/core/models/config.py index 8a2e40b..19ac85d 100644 --- a/core/models/config.py +++ b/core/models/config.py @@ -100,6 +100,7 @@ class Config(models.Model): site_name: str = "takahē" highlight_color: str = "#449c8c" + post_length: int = 500 identity_max_age: int = 24 * 60 * 60 class UserOptions(pydantic.BaseModel): diff --git a/static/css/style.css b/static/css/style.css index b3495b5..fba7f97 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -16,6 +16,7 @@ figure, blockquote, dl, dd, +fieldset, menu { margin: 0; padding: 0; @@ -166,6 +167,9 @@ header menu a.identity { border-right: 0; text-align: right; padding-right: 10px; + background: var(--color-bg-menu); + border-radius: 0 5px 0 0; + width: 250px; } header menu a i { @@ -188,26 +192,47 @@ header menu a small { } nav { - display: flex; - height: 40px; - background: var(--color-bg-menu); + padding: 10px 10px 20px 0; +} + +nav h3 { + text-transform: uppercase; + font-weight: bold; + font-size: 90%; + padding: 15px 18px 7px 16px; +} + +nav h3:first-child { + padding-top: 0; } nav a { display: block; color: var(--color-text-dull); - text-transform: uppercase; - font-weight: bold; - padding: 9px 18px 9px 18px; + padding: 7px 18px 7px 13px; + border-left: 3px solid transparent; } nav a.selected { color: var(--color-text-main); - border-bottom: 3px solid var(--color-highlight); + background: var(--color-bg-main); + border-radius: 0 5px 5px 0; } nav a:hover { color: var(--color-text-main); + border-left: 3px solid var(--color-highlight); +} + +nav a.selected:hover { + border-left: 3px solid transparent; +} + +nav a i { + width: 20px; + text-align: center; + margin-right: 4px; + display: inline-block; } /* Left-right columns */ @@ -225,6 +250,7 @@ nav a:hover { .right-column { width: 250px; background: var(--color-bg-menu); + border-radius: 0 0 5px 0; } .right-column h2 { @@ -237,22 +263,16 @@ nav a:hover { /* Icon menus */ -.icon-menu { - display: flex; - flex-wrap: wrap; - padding: 30px 0 0 30px; -} +.icon-menu {} .icon-menu>a { - margin: 0px 40px 40px 0; + display: block; + margin: 0px 0 20px 0; background: var(--color-bg-box); box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); - width: 370px; - height: 100px; - line-height: 100px; color: inherit; text-decoration: none; - padding: 0 20px; + padding: 10px 20px; border: 2px solid rgba(255, 255, 255, 0); border-radius: 3px; } @@ -291,8 +311,21 @@ nav a:hover { /* Forms */ -form { - padding: 20px 40px 20px 30px; +fieldset { + border: 0; + background: var(--color-bg-box); + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); + margin: 25px 0 45px 0; + padding: 5px 15px; +} + +fieldset legend { + position: relative; + top: -15px; + left: -15px; + font-weight: bold; + text-transform: uppercase; + color: var(--color-text-dull); } .right-column form, @@ -316,10 +349,16 @@ form p { } form .field { - margin: 25px 0 25px 0; - background: var(--color-bg-box); - box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); - padding: 10px 10px; + margin: 0 0 25px 0; + display: flex; +} + +form .field:last-of-type { + margin-bottom: 10px; +} + +form .field .label-input { + flex-grow: 1; } .right-column form .field { @@ -334,6 +373,7 @@ form label { text-transform: uppercase; font-size: 100%; font-weight: bold; + margin: 0 0 5px 0; } form label small { @@ -349,7 +389,7 @@ form label small { form .help { color: var(--color-text-dull); font-size: 90%; - margin: 2px 0 6px 0; + margin: -5px 0 5px 0; } form .errorlist { @@ -422,9 +462,16 @@ form input[type=submit]:hover { background: var(--color-button-main-hover); } +form img.preview { + max-height: 100%; + max-width: 100px; + margin: 0 0 0 20px; + align-self: center; +} + form .buttons { text-align: right; - margin: 25px 0 15px 0; + margin: -20px 0 15px 0; } .right-column form .buttons { @@ -459,6 +506,12 @@ form .button.toggle { background: var(--color-bg-main); } +form button.left, +form .button.left { + float: left; + margin: 0 5px 0 0; +} + form button.toggle.enabled, form .button.toggle.enabled { background: var(--color-highlight); @@ -661,3 +714,37 @@ h1.identity small { font-size: 20px; } } + + +@media (max-width: 700px) { + header menu a.identity { + width: 50px; + padding: 10px 10px 0 0; + } + + .right-column { + width: 50px; + } + + .right-column nav { + padding-right: 0; + } + + .right-column nav a { + font-size: 0; + padding: 10px 0 10px 10px; + } + + .right-column nav a i { + font-size: 22px; + } + + .right-column h3 { + visibility: hidden; + } + + .right-column h2, + .right-column .compose { + display: none; + } +} diff --git a/templates/activities/_home_menu.html b/templates/activities/_home_menu.html index c88a1d7..db441a2 100644 --- a/templates/activities/_home_menu.html +++ b/templates/activities/_home_menu.html @@ -1,6 +1,27 @@ <nav> - <a href="/" {% if current_page == "home" %}class="selected"{% endif %}>Home</a> - <a href="/notifications/" {% if current_page == "notifications" %}class="selected"{% endif %}>Notifications</a> - <a href="/local/" {% if current_page == "local" %}class="selected"{% endif %}>Local</a> - <a href="/federated/" {% if current_page == "federated" %}class="selected"{% endif %}>Federated</a> + <a href="/" {% if current_page == "home" %}class="selected"{% endif %}> + <i class="fa-solid fa-home"></i> Home + </a> + <a href="/notifications/" {% if current_page == "notifications" %}class="selected"{% endif %}> + <i class="fa-solid fa-at"></i> Notifications + </a> + <a href="/local/" {% if current_page == "local" %}class="selected"{% endif %}> + <i class="fa-solid fa-city"></i> Local + </a> + <a href="/federated/" {% if current_page == "federated" %}class="selected"{% endif %}> + <i class="fa-solid fa-globe"></i> Federated + </a> </nav> + +{% if current_page == "home" %} + <h2>Compose</h2> + <form action="/compose/" method="POST" class="compose"> + {% csrf_token %} + {{ form.text }} + {{ form.content_warning }} + <div class="buttons"> + <span class="button toggle" _="on click toggle .enabled then toggle .hidden on #id_content_warning">CW</span> + <button>{% if config_identity.toot_mode %}Toot!{% else %}Post{% endif %}</button> + </div> + </form> +{% endif %} diff --git a/templates/activities/compose.html b/templates/activities/compose.html index dfa6d1e..55b4eb3 100644 --- a/templates/activities/compose.html +++ b/templates/activities/compose.html @@ -3,15 +3,14 @@ {% block title %}Compose{% endblock %} {% block content %} - <nav> - <a href="." class="selected">Compose</a> - </nav> - <form action="." method="POST"> {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} + <fieldset> + <legend>Content</legend> + {% include "forms/_field.html" with field=form.text %} + {% include "forms/_field.html" with field=form.content_warning %} + {% include "forms/_field.html" with field=form.visibility %} + </fieldset> <div class="buttons"> <button>{% if config_identity.toot_mode %}Toot!{% else %}Post{% endif %}</button> </div> diff --git a/templates/activities/federated.html b/templates/activities/federated.html index b6143c3..4b57b9d 100644 --- a/templates/activities/federated.html +++ b/templates/activities/federated.html @@ -3,19 +3,9 @@ {% block title %}Federated Timeline{% endblock %} {% block content %} - {% include "activities/_home_menu.html" %} - - <section class="columns"> - <div class="left-column"> - {% for post in posts %} - {% include "activities/_post.html" %} - {% empty %} - No posts yet. - {% endfor %} - </div> - <div class="right-column"> - <h2>?</h2> - </div> - - </section> + {% for post in posts %} + {% include "activities/_post.html" %} + {% empty %} + No posts yet. + {% endfor %} {% endblock %} diff --git a/templates/activities/home.html b/templates/activities/home.html index 08e338e..5171842 100644 --- a/templates/activities/home.html +++ b/templates/activities/home.html @@ -3,39 +3,18 @@ {% block title %}Home{% endblock %} {% block content %} - {% include "activities/_home_menu.html" %} - - <section class="columns"> - - <div class="left-column"> - {% for event in events %} - {% if event.type == "post" %} - {% include "activities/_post.html" with post=event.subject_post %} - {% elif event.type == "boost" %} - <div class="boost-banner"> - <a href="{{ event.subject_identity.urls.view }}"> - {{ event.subject_identity.name_or_handle }} - </a> boosted - </div> - {% include "activities/_post.html" with post=event.subject_post %} - {% endif %} - {% empty %} - Nothing to show yet. - {% endfor %} - </div> - - <div class="right-column"> - <h2>Compose</h2> - <form action="/compose/" method="POST" class="compose"> - {% csrf_token %} - {{ form.text }} - {{ form.content_warning }} - <div class="buttons"> - <span class="button toggle" _="on click toggle .enabled then toggle .hidden on #id_content_warning">CW</span> - <button>{% if config_identity.toot_mode %}Toot!{% else %}Post{% endif %}</button> - </div> - </form> - </div> - - </section> + {% for event in events %} + {% if event.type == "post" %} + {% include "activities/_post.html" with post=event.subject_post %} + {% elif event.type == "boost" %} + <div class="boost-banner"> + <a href="{{ event.subject_identity.urls.view }}"> + {{ event.subject_identity.name_or_handle }} + </a> boosted + </div> + {% include "activities/_post.html" with post=event.subject_post %} + {% endif %} + {% empty %} + Nothing to show yet. + {% endfor %} {% endblock %} diff --git a/templates/activities/local.html b/templates/activities/local.html index 520a0ce..79ce9a3 100644 --- a/templates/activities/local.html +++ b/templates/activities/local.html @@ -3,19 +3,9 @@ {% block title %}Local Timeline{% endblock %} {% block content %} - {% include "activities/_home_menu.html" %} - - <section class="columns"> - <div class="left-column"> - {% for post in posts %} - {% include "activities/_post.html" %} - {% empty %} - No posts yet. - {% endfor %} - </div> - <div class="right-column"> - <h2>?</h2> - </div> - - </section> + {% for post in posts %} + {% include "activities/_post.html" %} + {% empty %} + No posts yet. + {% endfor %} {% endblock %} diff --git a/templates/activities/notifications.html b/templates/activities/notifications.html index c071a49..9bf66bb 100644 --- a/templates/activities/notifications.html +++ b/templates/activities/notifications.html @@ -3,20 +3,9 @@ {% block title %}Notifications{% endblock %} {% block content %} - {% include "activities/_home_menu.html" %} - - <section class="columns"> - <div class="left-column"> - {% for event in events %} - {% include "activities/_event.html" %} - {% empty %} - No events yet. - {% endfor %} - </div> - - <div class="right-column"> - <h2>?</h2> - </div> - - </section> + {% for event in events %} + {% include "activities/_event.html" %} + {% empty %} + No events yet. + {% endfor %} {% endblock %} diff --git a/templates/admin/_menu.html b/templates/admin/_menu.html deleted file mode 100644 index 8f0bc60..0000000 --- a/templates/admin/_menu.html +++ /dev/null @@ -1,6 +0,0 @@ -<nav> - <a href="{% url "admin_basic" %}" {% if section == "basic" %}class="selected"{% endif %}>Basic</a> - <a href="{% url "admin_domains" %}" {% if section == "domains" %}class="selected"{% endif %}>Domains</a> - <a href="{% url "admin_users" %}" {% if section == "users" %}class="selected"{% endif %}>Users</a> - <a href="{% url "admin_identities" %}" {% if section == "identities" %}class="selected"{% endif %}>Identities</a> -</nav> diff --git a/templates/admin/domain_create.html b/templates/admin/domain_create.html index 09dbc23..dcc57fa 100644 --- a/templates/admin/domain_create.html +++ b/templates/admin/domain_create.html @@ -1,11 +1,8 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} {% block title %}Add Domain - Admin{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} <form action="." method="POST"> <h1>Add A Domain</h1> <p> @@ -28,12 +25,17 @@ service domain. </p> {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} + <fieldset> + <legend>Domain Details</legend> + {% include "forms/_field.html" with field=form.domain %} + {% include "forms/_field.html" with field=form.service_domain %} + </fieldset> + <fieldset> + <legend>Access Control</legend> + {% include "forms/_field.html" with field=form.public %} + </fieldset> <div class="buttons"> - <a href="{{ domain.urls.delete }}" class="button delete">Delete</a> - <button>Save</button> + <button>Create</button> </div> </form> {% endblock %} diff --git a/templates/admin/domain_delete.html b/templates/admin/domain_delete.html index d47a673..5d077a5 100644 --- a/templates/admin/domain_delete.html +++ b/templates/admin/domain_delete.html @@ -1,12 +1,8 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} {% block title %}Delete {{ domain.domain }} - Admin{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} - <form action="." method="POST"> {% csrf_token %} @@ -28,6 +24,5 @@ <button class="delete">Confirm Deletion</button> </div> {% endif %} - </form> {% endblock %} diff --git a/templates/admin/domain_edit.html b/templates/admin/domain_edit.html index 64e195c..59bb8a2 100644 --- a/templates/admin/domain_edit.html +++ b/templates/admin/domain_edit.html @@ -1,16 +1,19 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}{{ domain.domain }} - Admin{% endblock %} +{% block subtitle %}{{ domain.domain }}{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} <form action="." method="POST"> {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} + <fieldset> + <legend>Domain Details</legend> + {% include "forms/_field.html" with field=form.domain %} + {% include "forms/_field.html" with field=form.service_domain %} + </fieldset> + <fieldset> + <legend>Access Control</legend> + {% include "forms/_field.html" with field=form.public %} + </fieldset> <div class="buttons"> <a href="{{ domain.urls.delete }}" class="button delete">Delete</a> <button>Save</button> diff --git a/templates/admin/domains.html b/templates/admin/domains.html index b7925da..bb7d8e4 100644 --- a/templates/admin/domains.html +++ b/templates/admin/domains.html @@ -1,11 +1,8 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}{{ section.title }} - Admin{% endblock %} +{% block subtitle %}Domains{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} <section class="icon-menu"> {% for domain in domains %} <a class="option" href="{{ domain.urls.edit }}"> diff --git a/templates/admin/identities.html b/templates/admin/identities.html index 86e70db..556e915 100644 --- a/templates/admin/identities.html +++ b/templates/admin/identities.html @@ -1,14 +1,9 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}Identities - Admin{% endblock %} +{% block subtitle %}Identities{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} - <form> - <p> - Please use the <a href="/djadmin/users/identity/">Django Admin</a> for now. - </p> - </form> + <p> + Please use the <a href="/djadmin/users/identity/">Django Admin</a> for now. + </p> {% endblock %} diff --git a/templates/admin/settings.html b/templates/admin/settings.html deleted file mode 100644 index e031347..0000000 --- a/templates/admin/settings.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "base.html" %} - -{% block title %}{{ section.title }} - Admin{% endblock %} - -{% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} - <form action="." method="POST"> - {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} - <div class="buttons"> - <button>Save</button> - </div> - </form> -{% endblock %} diff --git a/templates/admin/users.html b/templates/admin/users.html index 0b75b88..f2dc864 100644 --- a/templates/admin/users.html +++ b/templates/admin/users.html @@ -1,14 +1,9 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}Users - Admin{% endblock %} +{% block subtitle %}Users{% endblock %} {% block content %} - {% block menu %} - {% include "admin/_menu.html" %} - {% endblock %} - <form> - <p> - Please use the <a href="/djadmin/users/user/">Django Admin</a> for now. - </p> - </form> + <p> + Please use the <a href="/djadmin/users/user/">Django Admin</a> for now. + </p> {% endblock %} diff --git a/templates/base.html b/templates/base.html index 616d5b6..31bbc7b 100644 --- a/templates/base.html +++ b/templates/base.html @@ -31,14 +31,12 @@ <a href="/compose/" title="Compose" {% if top_section == "compose" %}class="selected"{% endif %}> <i class="fa-solid fa-feather"></i> Compose </a> + <a href="#" title="Search" {% if top_section == "search" %}class="selected"{% endif %}> + <i class="fa-solid fa-search"></i> Search + </a> <a href="{% url "settings" %}" title="Settings" {% if top_section == "settings" %}class="selected"{% endif %}> <i class="fa-solid fa-gear"></i> Settings </a> - {% if request.user.admin %} - <a href="{% url "admin" %}" title="Admin" {% if top_section == "admin" %}class="selected"{% endif %}> - <i class="fa-solid fa-toolbox"></i> Admin - </a> - {% endif %} <div class="gap"></div> <a href="/identity/select/" class="identity"> {% if not request.identity %} @@ -61,7 +59,18 @@ </menu> </header> - {% block content %} + {% block full_content %} + <div class="columns"> + <div class="left-column"> + {% block content %} + {% endblock %} + </div> + <div class="right-column"> + {% block right_content %} + {% include "activities/_home_menu.html" %} + {% endblock %} + </div> + </div> {% endblock %} </main> diff --git a/templates/forms/_field.html b/templates/forms/_field.html index 740432d..595546d 100644 --- a/templates/forms/_field.html +++ b/templates/forms/_field.html @@ -1,13 +1,18 @@ <div class="field"> - <label for="{{ field.id_for_label }}"> - {{ field.label }} - {% if field.field.required %}<small>(Required)</small>{% endif %} - </label> - {% if field.help_text %} - <p class="help"> - {{ field.help_text|linebreaksbr }} - </p> + <div class="label-input"> + <label for="{{ field.id_for_label }}"> + {{ field.label }} + {% if field.field.required %}<small>(Required)</small>{% endif %} + </label> + {% if field.help_text %} + <p class="help"> + {{ field.help_text|linebreaksbr }} + </p> + {% endif %} + {{ field.errors }} + {{ field }} + </div> + {% if preview %} + <img class="preview" src="{{ preview }}"> {% endif %} - {{ field.errors }} - {{ field }} </div> diff --git a/templates/identity/_identity_menu.html b/templates/identity/_menu.html index fff70cb..fff70cb 100644 --- a/templates/identity/_identity_menu.html +++ b/templates/identity/_menu.html diff --git a/templates/identity/base.html b/templates/identity/base.html new file mode 100644 index 0000000..baff37f --- /dev/null +++ b/templates/identity/base.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block title %}{% block subtitle %}{% endblock %} - Settings{% endblock %} + +{% block right_content %} + {% include "identity/_menu.html" %} +{% endblock %} diff --git a/templates/identity/create.html b/templates/identity/create.html index c69b55f..fbdd66c 100644 --- a/templates/identity/create.html +++ b/templates/identity/create.html @@ -1,17 +1,19 @@ -{% extends "base.html" %} +{% extends "identity/base.html" %} {% block title %}Create Identity{% endblock %} {% block content %} - {% include "identity/_identity_menu.html" %} <form action="." method="POST"> <h1>Create New Identity</h1> <p>You can have multiple identities - they are totally separate, and share nothing apart from your login details. Use them for alternates, projects, and more.</p> {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} + <fieldset> + <legend>Identity Details</legend> + {% include "forms/_field.html" with field=form.username %} + {% include "forms/_field.html" with field=form.domain %} + {% include "forms/_field.html" with field=form.name %} + </fieldset> <div class="buttons"> <button>Create</button> </div> diff --git a/templates/identity/select.html b/templates/identity/select.html index d9959ab..c4fb569 100644 --- a/templates/identity/select.html +++ b/templates/identity/select.html @@ -1,18 +1,12 @@ -{% extends "base.html" %} -{% load static %} +{% extends "identity/base.html" %} {% block title %}Select Identity{% endblock %} {% block content %} - {% include "identity/_identity_menu.html" %} <section class="icon-menu"> {% for identity in identities %} <a class="option" href="{{ identity.urls.activate }}"> - {% if identity.icon_uri %} - <img src="{{ identity.icon_uri }}"> - {% else %} - <img src="{% static "img/unknown-icon-128.png" %}"> - {% endif %} + <img src="{{ identity.local_icon_url }}"> <span class="handle"> {{ identity.name_or_handle }} <small>@{{ identity.handle }}</small> diff --git a/templates/settings/_menu.html b/templates/settings/_menu.html index 4f71651..e2dc70b 100644 --- a/templates/settings/_menu.html +++ b/templates/settings/_menu.html @@ -1,5 +1,28 @@ <nav> - <a href="{% url "settings_profile" %}" {% if section == "profile" %}class="selected"{% endif %}>Profile</a> - <a href="#" {% if section == "interface" %}class="selected"{% endif %}>Interface</a> - <a href="#" {% if section == "filtering" %}class="selected"{% endif %}>Filtering</a> + <h3>Identity</h3> + <a href="{% url "settings_profile" %}" {% if section == "profile" %}class="selected"{% endif %}> + <i class="fa-solid fa-user"></i> Profile + </a> + <a href="{% url "settings_interface" %}" {% if section == "interface" %}class="selected"{% endif %}> + <i class="fa-solid fa-display"></i> Interface + </a> + {% if request.user.admin %} + <h3>Account</h3> + <a href="#" {% if section == "login" %}class="selected"{% endif %}> + <i class="fa-solid fa-key"></i> Login & Security + </a> + <h3>Administration</h3> + <a href="{% url "admin_basic" %}" {% if section == "basic" %}class="selected"{% endif %}> + <i class="fa-solid fa-book"></i> Basic + </a> + <a href="{% url "admin_domains" %}" {% if section == "domains" %}class="selected"{% endif %}> + <i class="fa-solid fa-globe"></i> Domains + </a> + <a href="{% url "admin_users" %}" {% if section == "users" %}class="selected"{% endif %}> + <i class="fa-solid fa-users"></i> Users + </a> + <a href="{% url "admin_identities" %}" {% if section == "identities" %}class="selected"{% endif %}> + <i class="fa-solid fa-id-card"></i> Identities + </a> + {% endif %} </nav> diff --git a/templates/settings/base.html b/templates/settings/base.html new file mode 100644 index 0000000..d5efa69 --- /dev/null +++ b/templates/settings/base.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block title %}{% block subtitle %}{% endblock %} - Settings{% endblock %} + +{% block right_content %} + {% include "settings/_menu.html" %} +{% endblock %} diff --git a/templates/settings/profile.html b/templates/settings/profile.html index 1a7c29f..5c00557 100644 --- a/templates/settings/profile.html +++ b/templates/settings/profile.html @@ -1,18 +1,22 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}Profile - Settings{% endblock %} +{% block subtitle %}Profile{% endblock %} {% block content %} - {% block menu %} - {% include "settings/_menu.html" %} - {% endblock %} <form action="." method="POST" enctype="multipart/form-data" > {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} - {% endfor %} + <fieldset> + <legend>Details</legend> + {% include "forms/_field.html" with field=form.name %} + {% include "forms/_field.html" with field=form.summary %} + </fieldset> + <fieldset> + <legend>Images</legend> + {% include "forms/_field.html" with field=form.icon preview=request.identity.icon.url %} + {% include "forms/_field.html" with field=form.image preview=request.identity.image.url %} + </fieldset> <div class="buttons"> - <a href="{{ request.identity.urls.view }}" class="button secondary">View Profile</a> + <a href="{{ request.identity.urls.view }}" class="button secondary left">View Profile</a> <button>Save</button> </div> </form> diff --git a/templates/settings/settings.html b/templates/settings/settings.html index 016eebb..a933627 100644 --- a/templates/settings/settings.html +++ b/templates/settings/settings.html @@ -1,15 +1,17 @@ -{% extends "base.html" %} +{% extends "settings/base.html" %} -{% block title %}{{ section.title }} - Settings{% endblock %} +{% block subtitle %}{{ section.title }}{% endblock %} {% block content %} - {% block menu %} - {% include "settings/_menu.html" %} - {% endblock %} <form action="." method="POST"> {% csrf_token %} - {% for field in form %} - {% include "forms/_field.html" %} + {% for title, fields in fieldsets.items %} + <fieldset> + <legend>{{ title }}</legend> + {% for field in fields %} + {% include "forms/_field.html" %} + {% endfor %} + </fieldset> {% endfor %} <div class="buttons"> <button>Save</button> diff --git a/users/views/admin.py b/users/views/admin.py index 165572c..9476417 100644 --- a/users/views/admin.py +++ b/users/views/admin.py @@ -24,7 +24,6 @@ class AdminSettingsPage(SettingsPage): at the bottom of the page. Don't add this to a URL directly - subclass! """ - template_name = "admin/settings.html" options_class = Config.SystemOptions def load_config(self): @@ -47,6 +46,15 @@ class BasicPage(AdminSettingsPage): "title": "Highlight Color", "help_text": "Used for logo background and other highlights", }, + "post_length": { + "title": "Maximum Post Length", + "help_text": "The maximum number of characters allowed per post", + }, + } + + layout = { + "Branding": ["site_name", "highlight_color"], + "Posts": ["post_length"], } diff --git a/users/views/settings.py b/users/views/settings.py index c3c166b..88e4cd3 100644 --- a/users/views/settings.py +++ b/users/views/settings.py @@ -1,5 +1,5 @@ from functools import partial -from typing import ClassVar, Dict +from typing import ClassVar, Dict, List from django import forms from django.shortcuts import redirect @@ -27,6 +27,7 @@ class SettingsPage(FormView): template_name = "settings/settings.html" section: ClassVar[str] options: Dict[str, Dict[str, str]] + layout: Dict[str, List[str]] def get_form_class(self): # Create the fields dict from the config object @@ -42,6 +43,8 @@ class SettingsPage(FormView): ) elif config_field.type_ is str: form_field = forms.CharField + elif config_field.type_ is int: + form_field = forms.IntegerField else: raise ValueError(f"Cannot render settings type {config_field.type_}") fields[key] = form_field( @@ -68,6 +71,10 @@ class SettingsPage(FormView): def get_context_data(self): context = super().get_context_data() context["section"] = self.section + # Gather fields into fieldsets + context["fieldsets"] = {} + for title, fields in self.layout.items(): + context["fieldsets"][title] = [context["form"][field] for field in fields] return context def form_valid(self, form): @@ -87,10 +94,12 @@ class InterfacePage(SettingsPage): options = { "toot_mode": { "title": "I Will Toot As I Please", - "help_text": "If enabled, changes all 'Post' buttons to 'Toot!'", + "help_text": "Changes all 'Post' buttons to 'Toot!'", } } + layout = {"Posting": ["toot_mode"]} + @method_decorator(identity_required, name="dispatch") class ProfilePage(FormView): @@ -102,9 +111,18 @@ class ProfilePage(FormView): class form_class(forms.Form): name = forms.CharField(max_length=500) - summary = forms.CharField(widget=forms.Textarea, required=False) - icon = forms.ImageField(required=False) - image = forms.ImageField(required=False) + summary = forms.CharField( + widget=forms.Textarea, + required=False, + help_text="Describe you and your interests", + label="Bio", + ) + icon = forms.ImageField( + required=False, help_text="Shown next to all your posts and activities" + ) + image = forms.ImageField( + required=False, help_text="Shown at the top of your profile" + ) def get_initial(self): return { |