mirror of
https://github.com/jointakahe/takahe.git
synced 2024-11-25 16:51:00 +00:00
Fallback avatars in about 500 bytes. (#269)
Also create a new re-usable identity banner template. Fix super long handles (closes #270)
This commit is contained in:
parent
d32a686eb1
commit
dab8dd59a7
9 changed files with 159 additions and 93 deletions
|
@ -438,7 +438,7 @@ p.authorization-code {
|
||||||
|
|
||||||
.icon-menu .option {
|
.icon-menu .option {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0px 0 20px 0;
|
margin: 0 0 20px 0;
|
||||||
background: var(--color-bg-box);
|
background: var(--color-bg-box);
|
||||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1);
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -457,6 +457,10 @@ p.authorization-code {
|
||||||
color: var(--color-text-dull);
|
color: var(--color-text-dull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-menu .option-actions {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-menu .option.empty:hover,
|
.icon-menu .option.empty:hover,
|
||||||
.icon-menu .option.static:hover {
|
.icon-menu .option.static:hover {
|
||||||
border: 2px solid rgba(255, 255, 255, 0);
|
border: 2px solid rgba(255, 255, 255, 0);
|
||||||
|
@ -482,8 +486,20 @@ p.authorization-code {
|
||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-menu .option .handle {
|
.icon-menu .option.hashtags {
|
||||||
margin-right: 20px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu .option.hashtags .tag {
|
||||||
|
min-width: 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu .option.hashtags .count {
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-menu .option .pill {
|
.icon-menu .option .pill {
|
||||||
|
@ -500,16 +516,10 @@ p.authorization-code {
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-menu .option time {
|
.icon-menu .option time {
|
||||||
float: right;
|
|
||||||
color: var(--color-text-duller);
|
color: var(--color-text-duller);
|
||||||
margin: 14px 0 0 0;
|
margin: 14px 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-menu .option .right {
|
|
||||||
display: inline-block;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-menu .option button {
|
.icon-menu .option button {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
@ -1015,6 +1025,34 @@ table.metadata td .emoji {
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Identity banner */
|
||||||
|
|
||||||
|
.identity-banner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.identity-banner .handle {
|
||||||
|
display: block;
|
||||||
|
padding: 0 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.identity-banner .handle .link,
|
||||||
|
.identity-banner .handle .small {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.identity-banner .avatar-link {
|
||||||
|
line-height: 0; /* Fixes a bit of extra padding on the bottom of the link. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Posts */
|
/* Posts */
|
||||||
|
|
||||||
.post {
|
.post {
|
||||||
|
@ -1043,31 +1081,24 @@ form .post {
|
||||||
.post .icon {
|
.post .icon {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
width: auto;
|
width: auto;
|
||||||
float: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post.mini .icon {
|
.post.mini .icon {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
width: auto;
|
width: auto;
|
||||||
float: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post .emoji {
|
.post .emoji {
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post .handle {
|
.post .post-banner {
|
||||||
display: block;
|
display: flex;
|
||||||
padding: 7px 0 0 64px;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.post.mini .handle {
|
|
||||||
padding: 7px 0 0 36px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post time {
|
.post time {
|
||||||
display: block;
|
display: block;
|
||||||
float: right;
|
|
||||||
color: var(--color-text-duller);
|
color: var(--color-text-duller);
|
||||||
width: 65px;
|
width: 65px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
8
static/js/minidenticons.min.js
vendored
Normal file
8
static/js/minidenticons.min.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
function identicon(t,e=50,i=50){const n=t.split("").reduce(((t,e)=>16777619*((t^e.charCodeAt(0))>>>0)),2166136261);const s=n/16777619%18*20;return[...Array(t?25:0)].reduce(((t,e,i)=>n%(16-i%15)<4?t+`<rect x="${i>14?7-~~(i/5):~~(i/5)}" y="${i%5}" width="1" height="1"/>`:t),`<svg viewBox="-1.5 -1.5 8 8" xmlns="http://www.w3.org/2000/svg" fill="hsl(${s} ${e}% ${i}%)">`)+"</svg>"}
|
||||||
|
function generate_avatar(handle) {
|
||||||
|
element.src = URL.createObjectURL(
|
||||||
|
new Blob([identicon(handle)], {
|
||||||
|
type: 'image/svg+xml;charset=utf8'
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
{% load activity_tags %}
|
{% load activity_tags %}
|
||||||
<div class="post user" data-takahe-id="{{ identity.id }}">
|
<div class="post user" data-takahe-id="{{ identity.id }}">
|
||||||
|
|
||||||
<a href="{{ identity.urls.view }}">
|
{% include "identity/_identity_banner.html" with identity=identity %}
|
||||||
<img src="{{ identity.local_icon_url.relative }}" class="icon" alt="Avatar for {{ identity.name_or_handle }}" loading="lazy">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% if created %}
|
{% if created %}
|
||||||
<time>
|
<time>
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
{% load activity_tags %}
|
{% load activity_tags %}
|
||||||
<div class="post {% if reply %}reply{% endif %} {{ post.summary_class }}" data-takahe-id="{{ post.id }}" role="article" tabindex="0">
|
<div class="post {% if reply %}reply{% endif %} {{ post.summary_class }}" data-takahe-id="{{ post.id }}" role="article" tabindex="0">
|
||||||
|
|
||||||
<a href="{{ post.author.urls.view }}" tabindex="-1">
|
<div class="post-banner">
|
||||||
<img src="{{ post.author.local_icon_url.relative }}" class="icon" loading="lazy">
|
{% include "identity/_identity_banner.html" with identity=post.author %}
|
||||||
</a>
|
<div>
|
||||||
|
|
||||||
<time _="on click go url {% if link_original %}{{ post.url }}{% else %}{{ post.urls.view }}{% endif %} then halt">
|
<time _="on click go url {% if link_original %}{{ post.url }}{% else %}{{ post.urls.view }}{% endif %} then halt">
|
||||||
{% if post.visibility == 0 %}
|
{% if post.visibility == 0 %}
|
||||||
<i class="visibility fa-solid fa-earth-oceania" title="Public" aria-label="public"></i>
|
<i class="visibility fa-solid fa-earth-oceania" title="Public" aria-label="public"></i>
|
||||||
|
@ -24,10 +23,8 @@
|
||||||
<a href="{% if link_original %}{{ post.url }}{% else %}{{ post.urls.view }}{% endif %}" title="{{ post.created }}">{{ post.created | timedeltashort }}</a>
|
<a href="{% if link_original %}{{ post.url }}{% else %}{{ post.urls.view }}{% endif %}" title="{{ post.created }}">{{ post.created | timedeltashort }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</time>
|
</time>
|
||||||
|
</div>
|
||||||
<a href="{{ post.author.urls.view }}" class="handle">
|
</div>
|
||||||
<span class="link">{{ post.author.html_name_or_handle }}</span> <small>@{{ post.author.handle }}</small>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% if post.summary %}
|
{% if post.summary %}
|
||||||
{% if config_identity.expand_linked_cws %}
|
{% if config_identity.expand_linked_cws %}
|
||||||
|
|
|
@ -16,13 +16,11 @@
|
||||||
|
|
||||||
<section class="icon-menu">
|
<section class="icon-menu">
|
||||||
{% for identity in page_obj %}
|
{% for identity in page_obj %}
|
||||||
<a class="option" href="{{ identity.urls.view }}">
|
<a class="option " href="{{ identity.urls.view }}">
|
||||||
<img src="{{ identity.local_icon_url.relative }}" loading="lazy">
|
<div class="option-content">
|
||||||
<span class="handle">
|
{% include "identity/_identity_banner.html" with identity=identity link_avatar=False link_handle=False %}
|
||||||
{{ identity.html_name_or_handle }}
|
</div>
|
||||||
<small>@{{ identity.handle }}</small>
|
<div class="option-actions">
|
||||||
</span>
|
|
||||||
|
|
||||||
{% if identity.id in outbound_ids %}
|
{% if identity.id in outbound_ids %}
|
||||||
<span class="pill">Following</span>
|
<span class="pill">Following</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -30,7 +28,6 @@
|
||||||
<span class="pill">Follows You</span>
|
<span class="pill">Follows You</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="right">
|
|
||||||
{% if inbound %}
|
{% if inbound %}
|
||||||
<form action="{{ identity.urls.action }}" method="POST" class="follow">
|
<form action="{{ identity.urls.action }}" method="POST" class="follow">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@ -43,7 +40,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<time>{{ identity.follow_date | timedeltashort }} ago</time>
|
<time>{{ identity.follow_date | timedeltashort }} ago</time>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="icon-menu">
|
<section class="icon-menu">
|
||||||
{% for hashtag in page_obj %}
|
{% for hashtag in page_obj %}
|
||||||
<a class="option" href="{{ hashtag.urls.admin_edit }}">
|
<a class="option hashtags" href="{{ hashtag.urls.admin_edit }}">
|
||||||
|
<div class="tag">
|
||||||
<i class="fa-solid fa-hashtag"></i>
|
<i class="fa-solid fa-hashtag"></i>
|
||||||
<span class="handle">
|
<span class="handle">
|
||||||
{{ hashtag.display_name }}
|
{{ hashtag.display_name }}
|
||||||
|
@ -13,22 +14,25 @@
|
||||||
{% if hashtag.public %}Public{% elif hashtag.public is None %}Unreviewed{% else %}Private{% endif %}
|
{% if hashtag.public %}Public{% elif hashtag.public is None %}Unreviewed{% else %}Private{% endif %}
|
||||||
</small>
|
</small>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
{% if hashtag.stats %}
|
{% if hashtag.stats %}
|
||||||
|
<div class="count">
|
||||||
<span class="handle">
|
<span class="handle">
|
||||||
<small>Total:</small>
|
|
||||||
{{ hashtag.stats.total }}
|
{{ hashtag.stats.total }}
|
||||||
|
<small>Total</small>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if hashtag.aliases %}
|
{% if hashtag.aliases %}
|
||||||
|
<div class="count">
|
||||||
<span class="handle">
|
<span class="handle">
|
||||||
<small>Aliases:</small>
|
|
||||||
{% for alias in hashtag.aliases %}
|
{% for alias in hashtag.aliases %}
|
||||||
{{ alias }}{% if not forloop.last %}, {% endif %}
|
{{ alias }}{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<small>Aliases</small>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<p class="option empty">There are no hashtags yet.</p>
|
<p class="option empty">There are no hashtags yet.</p>
|
||||||
|
|
|
@ -20,16 +20,14 @@
|
||||||
<section class="icon-menu">
|
<section class="icon-menu">
|
||||||
{% for identity in page_obj %}
|
{% for identity in page_obj %}
|
||||||
<a class="option" href="{{ identity.urls.admin_edit }}">
|
<a class="option" href="{{ identity.urls.admin_edit }}">
|
||||||
<img src="{{ identity.local_icon_url.relative }}" class="icon" alt="Avatar for {{ identity.name_or_handle }}" loading="lazy">
|
<div class="option-content">
|
||||||
<span class="handle">
|
{% include "identity/_identity_banner.html" with identity=identity link_avatar=False link_handle=False %}
|
||||||
{{ identity.html_name_or_handle }}
|
</div>
|
||||||
<small>
|
<div class="option-actions">
|
||||||
{{ identity.handle }}
|
|
||||||
</small>
|
|
||||||
</span>
|
|
||||||
{% if identity.banned %}
|
{% if identity.banned %}
|
||||||
<span class="pill bad">Banned</span>
|
<span class="pill bad">Banned</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<p class="option empty">
|
<p class="option empty">
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<link rel="shortcut icon" href="{{ config.site_icon }}">
|
<link rel="shortcut icon" href="{{ config.site_icon }}">
|
||||||
<script src="{% static "js/hyperscript.min.js" %}"></script>
|
<script src="{% static "js/hyperscript.min.js" %}"></script>
|
||||||
<script src="{% static "js/htmx.min.js" %}"></script>
|
<script src="{% static "js/htmx.min.js" %}"></script>
|
||||||
|
<script src="{% static "js/minidenticons.min.js" %}"></script>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
--color-highlight: {{ config.highlight_color }};
|
--color-highlight: {{ config.highlight_color }};
|
||||||
|
|
33
templates/identity/_identity_banner.html
Normal file
33
templates/identity/_identity_banner.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<div class="identity-banner">
|
||||||
|
{% if link_avatar is False %}
|
||||||
|
<div class="avatar-link">
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ identity.urls.view }}" tabindex="-1" class="avatar-link">
|
||||||
|
{% endif %}
|
||||||
|
<img
|
||||||
|
src="{{ identity.local_icon_url.relative }}"
|
||||||
|
class="icon"
|
||||||
|
alt="Avatar for {{ identity.name_or_handle }}"
|
||||||
|
loading="lazy"
|
||||||
|
data-handle="{{ identity.name_or_handle }}"
|
||||||
|
_="on error set my.src to generate_avatar(@data-handle)"
|
||||||
|
>
|
||||||
|
{% if link_avatar is False%}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if link_handle is False%}
|
||||||
|
<div class="handle">
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ identity.urls.view }}" class="handle">
|
||||||
|
{% endif %}
|
||||||
|
<div class="link">{{ identity.html_name_or_handle }}</div>
|
||||||
|
<small>@{{ identity.handle }}</small>
|
||||||
|
{% if link_handle is False %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
Loading…
Reference in a new issue