user page redesign: misc tweaks

* separate source protocol from user in user labels
* make bridged protocol labels generic
* other visual tweaks

for #442
pull/671/head
Ryan Barrett 2023-10-10 21:19:26 -07:00
rodzic cc62d4cdb1
commit f37baeba58
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
8 zmienionych plików z 66 dodań i 52 usunięć

Wyświetl plik

@ -472,10 +472,7 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
return f"""\
<a class="h-card u-author" href="{self.web_url()}">
<img src="{img}" class="profile">
<span class="logo" title="{self.__class__.__name__}">{self.LOGO_HTML}</span>
{self.name()}
</a>
"""
{self.name()}</a>"""
class Object(StringIdModel):

Wyświetl plik

@ -30,6 +30,16 @@ with app.test_request_context('/'):
logger = logging.getLogger(__name__)
TEMPLATE_VARS = {
'as2': as2,
'g': g,
'isinstance': isinstance,
'logs': logs,
'PROTOCOLS': PROTOCOLS,
'set': set,
'util': util,
}
def load_user(protocol, id):
"""Loads the current request's user into `g.user`.
@ -101,13 +111,10 @@ def web_user_redirects(**kwargs):
def profile(protocol, id):
load_user(protocol, id)
query = Object.query(OR(Object.users == g.user.key,
Object.notify == g.user.key))
query = Object.query(Object.users == g.user.key)
objects, before, after = fetch_objects(query, by=Object.updated)
num_followers, num_following = count_followers()
return render_template('profile.html', logs=logs, util=util, g=g, **locals())
return render_template('profile.html', **TEMPLATE_VARS, **locals())
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/home')
@ -116,8 +123,7 @@ def home(protocol, id):
query = Object.query(Object.feed == g.user.key)
objects, before, after = fetch_objects(query, by=Object.created)
return render_template('home.html', logs=logs, util=util, g=g, **locals())
return render_template('home.html', **TEMPLATE_VARS, **locals())
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/notifications')
@ -126,8 +132,7 @@ def notifications(protocol, id):
query = Object.query(Object.notify == g.user.key)
objects, before, after = fetch_objects(query, by=Object.updated)
return render_template('notifications.html', logs=logs, util=util, g=g, **locals())
return render_template('notifications.html', **TEMPLATE_VARS, **locals())
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/<any(followers,following):collection>')
@ -139,10 +144,8 @@ def followers_or_following(protocol, id, collection):
return render_template(
f'{collection}.html',
address=request.args.get('address'),
as2=as2,
follow_url=request.values.get('url'),
g=g,
util=util,
**TEMPLATE_VARS,
**locals(),
)
@ -202,7 +205,7 @@ def feed(protocol, id):
# syntax. maybe a fediverse kwarg down through the call chain?
if format == 'html':
entries = [microformats2.object_to_html(a) for a in activities]
return render_template('feed.html', util=util, g=g, **locals())
return render_template('feed.html', **TEMPLATE_VARS, **locals())
elif format == 'atom':
body = atom.activities_to_atom(activities, actor=actor, title=title,
request_url=request.url)

Wyświetl plik

@ -304,7 +304,7 @@ button[disabled]:hover {
border-radius: 1em;
}
.btn-home img, .logo {
.btn-home img, .logo, .logo img {
height: 1.1em;
margin-top: -.2em;
}
@ -328,7 +328,7 @@ button[disabled]:hover {
}
.tabs a {
border-bottom: 1px solid;
border-bottom: 1px solid lightgray;
background: linear-gradient(white, #e8e8e8);
padding-left: .5em;
padding-right: .5em;
@ -340,14 +340,23 @@ button[disabled]:hover {
text-decoration: none;
}
.tabs a.active-tab {
a.active-tab {
border-bottom: none;
border-left: 1px solid;
border-right: 1px solid;
border-left: 1px solid lightgray;
background: inherit;
color: inherit;
}
/* TODO: drop border-left above and switch to this once Firefix supports :has()
* https://caniuse.com/css-has
a:has(+ a.active-tab) {
border-right: 1px solid lightgray;
} */
a.active-tab + a {
border-left: 1px solid lightgray;
}
.disable-button, #bad-button {
border-color: red;
color: red;

Wyświetl plik

@ -25,7 +25,7 @@
{% endif %}
</li>
{% else %}
None yet. Check back soon!
<span class="big">None yet. Check back soon!</span>
{% endfor %}
</ul>

Wyświetl plik

@ -56,7 +56,7 @@
</div>
</li>
{% else %}
<li class="row">Nothing yet!</li>
<span class="big">None yet. Check back soon!</span>
{% endfor %}
</ul>

Wyświetl plik

@ -36,27 +36,38 @@
{% endif %}
<div class="row">
<span class="big">{{ g.user.user_link()|safe }}</span>
&middot;
{% if g.user.LABEL != 'activitypub' %}
bridged to
<nobr title="Fediverse address">
<img class="logo" src="/static/fediverse_logo.svg">
{{ g.user.ap_address() }}
</nobr>
<form method="post" action="/webmention-interactive">
<input name="source" type="hidden" value="{{ g.user.web_url() }}" />
&nbsp;
<button id="update-profile-button" type="submit"
title="Update profile from web site"
class="btn btn-default glyphicon glyphicon-refresh"></button>
</form>
{% endif %}
<span class="big">
{{ g.user.user_link()|safe }}
&middot;
<nobr>
<a href="{{ g.user.web_url() }}" title="{{ g.user.__class__.__name__ }}">
<span class="logo">{{ g.user.LOGO_HTML }}</span>
{{ g.user.handle_or_id() }}</a>
<!-- TODO: make this work with protocols other than Web -->
<form method="post" action="/webmention-interactive">
<input name="source" type="hidden" value="{{ g.user.web_url() }}" />
<button id="update-profile-button" type="submit" title="Update profile"
class="btn btn-default glyphicon glyphicon-refresh"></button>
</form>
</nobr>
&middot;
</span>
{% for proto in set(PROTOCOLS.values()) %}
{% if proto and not isinstance(g.user, proto)
and proto.LABEL not in ('atproto', 'ui') %}
<nobr title="{{ proto.__name__ }} (bridged)">
<span class="logo">{{ proto.LOGO_HTML|safe }}</span>
{{ g.user.ap_address() }}
</nobr>
{% endif %}
{% endfor %}
</div>
<!-- tabs -->
<div class="row tabs">
<a></a>
<a class="left-tab"></a>
<a href="{{ g.user.user_page_path() }}"
{% if tab == 'profile' %}class="active-tab"{% endif %}
>👤 Profile</a><a
@ -66,7 +77,7 @@
href="{{ g.user.user_page_path('notifications') }}"
{% if tab == 'notifications' %}class="active-tab"{% endif %}
>🔔 Notifications</a>
<a></a>
<a class="right-tab"></a>
</div>
{% block subtabs %}

Wyświetl plik

@ -34,9 +34,7 @@ class CommonTest(TestCase):
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://user.com/">
<img src="" class="profile">
<span class="logo" title="Web">🕸</span>
user.com
</a>""", common.pretty_link('https://user.com/'))
user.com</a>""", common.pretty_link('https://user.com/'))
def test_redirect_wrap_empty(self):
self.assertIsNone(common.redirect_wrap(None))

Wyświetl plik

@ -139,17 +139,13 @@ class UserTest(TestCase):
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://y.z/">
<img src="" class="profile">
<span class="logo" title="Web">🕸</span>
y.z
</a>""", g.user.user_link())
y.z</a>""", g.user.user_link())
g.user.obj = Object(id='a', as2=ACTOR)
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://y.z/">
<img src="https://user.com/me.jpg" class="profile">
<span class="logo" title="Web">🕸</span>
Mrs. Foo
</a>""", g.user.user_link())
<img src="https://user.com/me.jpg" class="profile">
Mrs. Foo</a>""", g.user.user_link())
def test_is_web_url(self):
for url in 'y.z', '//y.z', 'http://y.z', 'https://y.z':