redesigned subscriptions with card layout

Replace cramped table layout with card-based design that works
better in narrow viewports and across different themes.
This commit is contained in:
lichenblankie 2026-03-26 21:51:58 -07:00
parent bfb8acf946
commit 59d2088498

View file

@ -685,32 +685,30 @@ def handle_subscriptions(msg=""):
subs = db.execute("SELECT * FROM subscriptions ORDER BY id DESC").fetchall() subs = db.execute("SELECT * FROM subscriptions ORDER BY id DESC").fetchall()
finally: finally:
return_db(db) return_db(db)
items = "" cards = ""
for s in subs: for s in subs:
auto_label = "on" if s["auto_sync"] else "off" auto_label = "on" if s["auto_sync"] else "off"
last = s["last_sync"] or "never" last = s["last_sync"] or "never"
items += ( cards += (
f'<tr>' f'<div style="border:1px solid #ddd;border-radius:4px;padding:0.9rem 1rem;margin-bottom:0.75rem">'
f'<td><b>{esc(s["name"] or "unknown")}</b><br><small>{esc(s["dest_hash"])}</small></td>' f'<div style="margin-bottom:0.4rem"><b>{esc(s["name"] or "unknown")}</b></div>'
f'<td>{esc(last)}</td>' f'<div><small>{esc(s["dest_hash"])}</small></div>'
f'<td>' f'<div style="margin-top:0.4rem;font-size:0.85rem;color:#606060">last sync: {esc(last)}</div>'
f'<form method="post" action="/subscriptions/autosync/{s["id"]}" style="display:inline">' f'<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-top:0.7rem">'
f'{_csrf_field()}<button>auto-sync: {auto_label}</button></form>'
f'</td>'
f'<td>'
f'<a href="/subscriptions/browse/{s["id"]}">browse</a>' f'<a href="/subscriptions/browse/{s["id"]}">browse</a>'
f'<form method="post" action="/subscriptions/sync/{s["id"]}" style="display:inline">' f'<form method="post" action="/subscriptions/sync/{s["id"]}" style="display:inline">'
f'{_csrf_field()}<button>sync now</button></form>' f'{_csrf_field()}<button>sync now</button></form>'
f'<form method="post" action="/subscriptions/autosync/{s["id"]}" style="display:inline">'
f'{_csrf_field()}<button>auto-sync: {auto_label}</button></form>'
f'<form method="post" action="/subscriptions/delete/{s["id"]}" style="display:inline">' f'<form method="post" action="/subscriptions/delete/{s["id"]}" style="display:inline">'
f'{_csrf_field()}<button>remove</button></form>' f'{_csrf_field()}<button>remove</button></form>'
f'</td>' f'</div>'
f'</tr>' f'</div>'
) )
table = "" listing = ""
if subs: if subs:
table = ( listing = (
f'<table><tr><th>instance</th><th>last sync</th><th>auto-sync</th><th>actions</th></tr>' f'{cards}'
f'{items}</table>'
f'<form method="post" action="/subscriptions/syncall">' f'<form method="post" action="/subscriptions/syncall">'
f'{_csrf_field()}<button>sync all</button></form>' f'{_csrf_field()}<button>sync all</button></form>'
) )
@ -722,7 +720,7 @@ def handle_subscriptions(msg=""):
f'<button>subscribe</button>' f'<button>subscribe</button>'
f'</form>' f'</form>'
f'<p>{msg}</p>' f'<p>{msg}</p>'
f'<hr>{table}' f'<hr>{listing}'
f'<br><a href="/">back</a>' f'<br><a href="/">back</a>'
) )