Keep e621 metadata on downloaded posts; clear up account roles
Roles: - JakeBreathild is now staff + superuser (the real account); the 'jake' smoke-test account was demoted to a regular user - /me exposes is_superuser and the account page shows an admin badge e621 metadata: - MediaItem gains e621_post_id and e621_data (trimmed post payload: tags by category, rating, score, favourites, comments, sources, description, pools, relationships, file info, uploader) - Download to Library accepts the post payload from the SPA and stores it; the item's custom rating is seeded from the e621 rating when empty - Library detail shows an e621 metadata card: link to the in-app post, score/favourites/comments, taxonomy-coloured tags, DText description, sources and pools; grid cards get an e621 badge and fall back to the e621 rating for their colour (display_rating) - Guest visibility now also considers e621 tags, so downloaded explicit content is hidden from anonymous visitors
This commit is contained in:
@@ -21,6 +21,7 @@ export function MediaCard({ item }: { item: MediaItem }) {
|
||||
item.kind === "video"
|
||||
? `/api/files/${item.j_id}/thumbnail/`
|
||||
: `/api/files/${item.j_id}/raw/`;
|
||||
const rating = item.display_rating;
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -34,14 +35,22 @@ export function MediaCard({ item }: { item: MediaItem }) {
|
||||
loading="lazy"
|
||||
className="h-full w-full object-cover transition duration-200 group-hover:scale-[1.03]"
|
||||
/>
|
||||
{item.rating ? (
|
||||
{rating ? (
|
||||
<span
|
||||
className={cn(
|
||||
"absolute left-2 top-2 rounded-full border px-2 py-0.5 font-mono text-[11px] font-medium",
|
||||
ratingStyles[item.rating],
|
||||
ratingStyles[rating],
|
||||
)}
|
||||
>
|
||||
{ratingLabels[item.rating]}
|
||||
{ratingLabels[rating]}
|
||||
</span>
|
||||
) : null}
|
||||
{item.e621_post_id ? (
|
||||
<span
|
||||
className="absolute left-2 top-8 rounded-sm bg-ctp-lavender/90 px-1.5 py-0.5 font-mono text-[10px] font-medium text-ctp-crust"
|
||||
title={`e621 post #${item.e621_post_id}`}
|
||||
>
|
||||
e621
|
||||
</span>
|
||||
) : null}
|
||||
<span className="absolute right-2 top-2 rounded-sm bg-ctp-crust/80 px-1.5 py-0.5 font-mono text-[10px] uppercase text-ctp-overlay1">
|
||||
|
||||
@@ -33,17 +33,19 @@ export function TagChip({
|
||||
onClick?: () => void;
|
||||
}) {
|
||||
const style = TAG_STYLES[category ?? "unknown"] ?? TAG_STYLES.unknown;
|
||||
const className = cn(
|
||||
"rounded border px-1.5 py-0.5 font-mono text-[11px] transition",
|
||||
style,
|
||||
);
|
||||
const label = count !== undefined ? `${tag} (${count})` : tag;
|
||||
|
||||
if (!onClick) {
|
||||
return <span className={className}>{label}</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
"rounded border px-1.5 py-0.5 font-mono text-[11px] transition",
|
||||
style,
|
||||
)}
|
||||
>
|
||||
{tag}
|
||||
{count !== undefined ? ` (${count})` : ""}
|
||||
<button type="button" onClick={onClick} className={className}>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user