feat(web): fullscreen media preview/viewer and fix media context menu
Some checks failed
CI / test (push) Failing after 26s
Some checks failed
CI / test (push) Failing after 26s
This commit is contained in:
@@ -567,55 +567,62 @@ export function MessageComposer() {
|
||||
</div>
|
||||
|
||||
{selectedFile ? (
|
||||
<div className="mb-2 rounded-2xl border border-slate-700/80 bg-slate-900/95 p-3 text-sm shadow-xl">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-semibold">Send {selectedType === "image" || selectedType === "video" ? "Photo" : "File"}</p>
|
||||
<p className="text-xs text-slate-400">{selectedFile.name} • {formatBytes(selectedFile.size)}</p>
|
||||
<div className="fixed inset-0 z-[160] flex items-center justify-center bg-slate-950/80 p-3" onClick={cancelSelectedFile}>
|
||||
<div className="flex h-full w-full max-w-2xl flex-col rounded-2xl border border-slate-700/80 bg-slate-900/95 shadow-2xl" onClick={(event) => event.stopPropagation()}>
|
||||
<div className="flex items-center justify-between border-b border-slate-700/70 px-3 py-2">
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-sm font-semibold">Send {selectedType === "image" || selectedType === "video" ? "Photo" : "File"}</p>
|
||||
<p className="truncate text-xs text-slate-400">{selectedFile.name} • {formatBytes(selectedFile.size)}</p>
|
||||
</div>
|
||||
<button className="rounded bg-slate-700 px-2 py-1 text-xs" onClick={cancelSelectedFile} type="button">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
<button className="rounded bg-slate-700 px-2 py-1 text-xs" onClick={cancelSelectedFile} type="button">
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
{previewUrl && selectedType === "image" ? (
|
||||
<img className="mb-2 max-h-72 w-full rounded-xl object-contain" src={previewUrl} alt={selectedFile.name} />
|
||||
) : null}
|
||||
{previewUrl && selectedType === "video" ? (
|
||||
<video className="mb-2 max-h-72 w-full rounded-xl" src={previewUrl} controls muted />
|
||||
) : null}
|
||||
{!previewUrl ? (
|
||||
<div className="mb-2 rounded-lg border border-slate-700/80 bg-slate-800/60 px-3 py-2 text-xs text-slate-300">
|
||||
No preview available
|
||||
|
||||
<div className="tg-scrollbar min-h-0 flex-1 overflow-auto p-3">
|
||||
{previewUrl && selectedType === "image" ? (
|
||||
<img className="mx-auto max-h-[70vh] w-full rounded-xl object-contain" src={previewUrl} alt={selectedFile.name} />
|
||||
) : null}
|
||||
{previewUrl && selectedType === "video" ? (
|
||||
<video className="mx-auto max-h-[70vh] w-full rounded-xl" src={previewUrl} controls muted />
|
||||
) : null}
|
||||
{!previewUrl ? (
|
||||
<div className="rounded-lg border border-slate-700/80 bg-slate-800/60 px-3 py-2 text-xs text-slate-300">
|
||||
No preview available
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<input
|
||||
className="mb-2 w-full rounded-xl border border-slate-700/80 bg-slate-800/80 px-3 py-2 text-sm outline-none placeholder:text-slate-400 focus:border-sky-500"
|
||||
maxLength={1000}
|
||||
placeholder="Add a caption..."
|
||||
value={captionDraft}
|
||||
onChange={(event) => setCaptionDraft(event.target.value)}
|
||||
/>
|
||||
<div className="border-t border-slate-700/70 p-3">
|
||||
<input
|
||||
className="mb-2 w-full rounded-xl border border-slate-700/80 bg-slate-800/80 px-3 py-2 text-sm outline-none placeholder:text-slate-400 focus:border-sky-500"
|
||||
maxLength={1000}
|
||||
placeholder="Add a caption..."
|
||||
value={captionDraft}
|
||||
onChange={(event) => setCaptionDraft(event.target.value)}
|
||||
/>
|
||||
|
||||
{isUploading ? (
|
||||
<div className="mb-2">
|
||||
<div className="mb-1 text-xs text-slate-300">Uploading: {uploadProgress}%</div>
|
||||
<div className="h-2 rounded bg-slate-700">
|
||||
<div className="h-2 rounded bg-sky-500 transition-all" style={{ width: `${uploadProgress}%` }} />
|
||||
{isUploading ? (
|
||||
<div className="mb-2">
|
||||
<div className="mb-1 text-xs text-slate-300">Uploading: {uploadProgress}%</div>
|
||||
<div className="h-2 rounded bg-slate-700">
|
||||
<div className="h-2 rounded bg-sky-500 transition-all" style={{ width: `${uploadProgress}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-full rounded-xl bg-sky-500 px-3 py-2 font-semibold text-slate-950 disabled:opacity-50"
|
||||
onClick={() => void sendSelectedFile()}
|
||||
disabled={isUploading}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
<button className="w-full rounded-xl bg-slate-700 px-3 py-2 disabled:opacity-50" onClick={cancelSelectedFile} disabled={isUploading}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-full rounded-xl bg-sky-500 px-3 py-2 font-semibold text-slate-950 disabled:opacity-50"
|
||||
onClick={() => void sendSelectedFile()}
|
||||
disabled={isUploading}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
<button className="w-full rounded-xl bg-slate-700 px-3 py-2 disabled:opacity-50" onClick={cancelSelectedFile} disabled={isUploading}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user