feat: add private media dashboard slice
This commit is contained in:
1 parent
8d4eae7ab5
commit
768470204b
8 files changed
+688
No files matched your search
@@ -0,0 +1,45 @@
|
||||
import type { MediaItem } from '../../../../../packages/api-contracts/src/index.js';
|
||||
import { mediaConversation, mediaType } from './filters.js';
|
||||
|
||||
interface MediaCardProps {
|
||||
item: MediaItem;
|
||||
isRevealed: boolean;
|
||||
onToggleReveal(): void;
|
||||
}
|
||||
|
||||
function formatMediaDate(timestamp: number): string {
|
||||
return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(timestamp);
|
||||
}
|
||||
|
||||
export function MediaCard({ item, isRevealed, onToggleReveal }: MediaCardProps) {
|
||||
return (
|
||||
<article className="media-card">
|
||||
<div className="media-preview">
|
||||
<img
|
||||
alt={`Media from ${item.sender}`}
|
||||
className={isRevealed ? 'media-image' : 'media-image is-blurred'}
|
||||
loading="lazy"
|
||||
src={item.urlPath}
|
||||
/>
|
||||
{!isRevealed ? <span className="privacy-label">Private media hidden</span> : null}
|
||||
</div>
|
||||
<div className="media-card-body">
|
||||
<div>
|
||||
<strong>{item.sender}</strong>
|
||||
<span>{mediaConversation(item)}</span>
|
||||
</div>
|
||||
<dl>
|
||||
<div><dt>Type</dt><dd>{mediaType(item) === 'gif' ? 'GIF' : 'Image'}</dd></div>
|
||||
<div><dt>Received</dt><dd>{formatMediaDate(item.timestamp)}</dd></div>
|
||||
</dl>
|
||||
<button
|
||||
className="button secondary media-reveal"
|
||||
onClick={onToggleReveal}
|
||||
type="button"
|
||||
>
|
||||
{isRevealed ? `Hide media from ${item.sender}` : `Reveal media from ${item.sender}`}
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user