v3: various minor visual fixes
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 39s

This commit is contained in:
khannurien
2026-06-28 17:00:44 +00:00
parent fae25f3e6c
commit 324bff3133
12 changed files with 46 additions and 15 deletions

View File

@@ -1022,6 +1022,13 @@
overflow: hidden;
text-overflow: ellipsis;
}
a.global-player-title {
color: inherit;
text-decoration: none;
}
a.global-player-title:hover {
text-decoration: underline;
}
.global-player-body {
display: grid;
grid-template-rows: 1fr;
@@ -4972,8 +4979,10 @@ body.has-fab .page-content {
border-radius: 7px;
background: transparent;
color: var(--color-text);
font-size: 0.9rem;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
white-space: nowrap;
cursor: pointer;
transition: background 0.12s;

View File

@@ -176,11 +176,11 @@ function App() {
<CategoriesProvider>
<BrowserRouter>
<AppRoutes />
<GlobalPlayer />
</BrowserRouter>
</CategoriesProvider>
</FollowProvider>
</WSProvider>
<GlobalPlayer />
</PlayerProvider>
</AuthProvider>
</ThemeProvider>

View File

@@ -59,6 +59,7 @@ export function DumpCard(
<RichContentCard
richContent={dump.richContent}
compact
dumpHref={dumpUrl(dump)}
thumbnailOverrideUrl={dump.thumbnailMime
? dumpThumbnailUrl(dump, token)
: undefined}

View File

@@ -1,7 +1,7 @@
import { useContext, useEffect, useState } from "react";
import type { Dump } from "../model.ts";
import { formatBytes } from "../utils/format.ts";
import { dumpFileUrl, dumpThumbnailUrl } from "../utils/urls.ts";
import { dumpFileUrl, dumpThumbnailUrl, dumpUrl } from "../utils/urls.ts";
import { useAuth } from "../hooks/useAuth.ts";
import { IconPause, IconPlay, MediaPlayer } from "./MediaPlayer.tsx";
import { PlayerContext } from "../contexts/PlayerContext.ts";
@@ -45,7 +45,7 @@ function AudioFilePreview(
const handlePlayBtn = () => {
if (isActive) togglePlay();
else play({ kind: "file", fileUrl, mimeType: mime, title: dump.title });
else play({ kind: "file", fileUrl, mimeType: mime, title: dump.title, dumpHref: dumpUrl(dump) });
};
const handleWaveformClick = (e: React.MouseEvent<Element>) => {
@@ -59,7 +59,7 @@ function AudioFilePreview(
} else {
// Start playing and seek once it loads — seekTo after play() is a no-op
// until MediaPlayer mounts; the fraction is best-effort on first click
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title });
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title, dumpHref: dumpUrl(dump) });
}
};
@@ -178,7 +178,7 @@ export default function FilePreview(
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title });
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title, dumpHref: dumpUrl(dump) });
}}
>
<VideoThumb src={thumbUrl} fallback={mimeIcon(mime)} />
@@ -196,7 +196,7 @@ export default function FilePreview(
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title });
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title, dumpHref: dumpUrl(dump) });
}}
>
{thumbOverride

View File

@@ -1,4 +1,5 @@
import { useContext, useEffect, useRef, useState } from "react";
import { Link } from "react-router";
import { PlayerContext } from "../contexts/PlayerContext.ts";
import { MediaPlayer } from "./MediaPlayer.tsx";
@@ -75,7 +76,13 @@ export function GlobalPlayer() {
ref={ref}
>
<div className="global-player-header">
<span className="global-player-title">{title}</span>
{current.dumpHref
? (
<Link to={current.dumpHref} className="global-player-title">
{title}
</Link>
)
: <span className="global-player-title">{title}</span>}
<button
type="button"
className="btn btn--ghost"

View File

@@ -162,6 +162,7 @@ export function JournalCard(
embedUrl,
title: dump.richContent?.title,
type: dump.richContent?.type ?? "unknown",
dumpHref: dumpUrl(dump),
})
: handleNavigate}
>

View File

@@ -22,10 +22,13 @@ interface RichContentCardProps {
compact?: boolean;
/** Overrides richContent.thumbnailUrl with a custom dump thumbnail, if set. */
thumbnailOverrideUrl?: string;
/** Link back to the owning dump, surfaced as the global player's title. */
dumpHref?: string;
}
export default function RichContentCard(
{ richContent, compact = false, thumbnailOverrideUrl }: RichContentCardProps,
{ richContent, compact = false, thumbnailOverrideUrl, dumpHref }:
RichContentCardProps,
) {
const { play, current, playing } = useContext(PlayerContext);
const thumbnailSrc = thumbnailOverrideUrl ??
@@ -52,6 +55,7 @@ export default function RichContentCard(
embedUrl: richContent.embedUrl!,
title: richContent.title,
type: richContent.type,
dumpHref,
});
}}
aria-label={isPlaying ? "Pause" : "Play"}
@@ -113,6 +117,7 @@ export default function RichContentCard(
embedUrl: richContent.embedUrl!,
title: richContent.title,
type: richContent.type,
dumpHref,
})}
aria-label="Play"
>

View File

@@ -1,8 +1,8 @@
import { createContext } from "react";
export type PlayerItem =
| { kind: "embed"; embedUrl: string; title?: string; type: string }
| { kind: "file"; fileUrl: string; mimeType: string; title?: string };
| { kind: "embed"; embedUrl: string; title?: string; type: string; dumpHref?: string }
| { kind: "file"; fileUrl: string; mimeType: string; title?: string; dumpHref?: string };
export interface PlayerContextValue {
// Playback state — readable by any consumer

View File

@@ -462,6 +462,7 @@ export function Dump() {
? (
<RichContentCard
richContent={dump.richContent}
dumpHref={dumpUrl(dump)}
thumbnailOverrideUrl={dump.thumbnailMime
? dumpThumbnailUrl(dump, token)
: undefined}

View File

@@ -309,7 +309,9 @@
/* ── Category management chips / inline editor ───────────────────── */
[data-style="brutalist"] .category-chip,
[data-style="brutalist"] .category-editor,
[data-style="brutalist"] .category-editor-btn {
[data-style="brutalist"] .category-editor-btn,
[data-style="brutalist"] .dump-card-category-chip,
[data-style="brutalist"] .profile-role-chip {
border-radius: 0;
}

View File

@@ -492,7 +492,9 @@
[data-style="geocities"] .feed-tab,
[data-style="geocities"] .category-chip,
[data-style="geocities"] .category-editor,
[data-style="geocities"] .category-editor-btn {
[data-style="geocities"] .category-editor-btn,
[data-style="geocities"] .dump-card-category-chip,
[data-style="geocities"] .profile-role-chip {
border-radius: 0;
}

View File

@@ -245,6 +245,7 @@
[data-style="nyt"] .related-section-title,
[data-style="nyt"] .form-page-eyebrow,
[data-style="nyt"] .feed-sort-btn,
[data-style="nyt"] .category-switcher-option,
[data-style="nyt"] .follow-btn,
[data-style="nyt"] .playlist-badge,
[data-style="nyt"] .dump-card-private-badge,
@@ -529,7 +530,8 @@
[data-style="nyt"] .vote-btn,
[data-style="nyt"] .follow-btn,
[data-style="nyt"] .btn-add-playlist,
[data-style="nyt"] .invite-btn {
[data-style="nyt"] .invite-btn,
[data-style="nyt"] .profile-role-chip {
border-radius: 0;
border: none;
}
@@ -537,7 +539,8 @@
/* Category management chips / inline editor: squared, no accent glow. */
[data-style="nyt"] .category-chip,
[data-style="nyt"] .category-editor,
[data-style="nyt"] .category-editor-btn {
[data-style="nyt"] .category-editor-btn,
[data-style="nyt"] .dump-card-category-chip {
border-radius: 0;
}