feat(desktop): view-once image attachments (sender toggle + recipient lightbox + tombstone)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
ArrowRightIcon,
|
||||
ChevronDownIcon,
|
||||
ChevronUpIcon,
|
||||
EyeOffIcon,
|
||||
PlusIcon,
|
||||
PollIcon,
|
||||
ReplyIcon,
|
||||
@@ -183,6 +184,10 @@ export function ConversationPage() {
|
||||
const [mentionState, setMentionState] = useState<{ query: string; start: number } | null>(null);
|
||||
const [emojiOpen, setEmojiOpen] = useState(false);
|
||||
const [gifPickerOpen, setGifPickerOpen] = useState(false);
|
||||
// Sticky toggle: when on, the next image(s) sent are marked view-once.
|
||||
// Auto-clears on a successful send so the composer doesn't accidentally
|
||||
// burn the message-after-next.
|
||||
const [viewOnceNext, setViewOnceNext] = useState(false);
|
||||
const pins = usePinnedMessages(id);
|
||||
const [pinnedPanelOpen, setPinnedPanelOpen] = useState(false);
|
||||
const pinnedIds = useMemo(() => new Set(pins.map((p) => p.messageId)), [pins]);
|
||||
@@ -536,10 +541,13 @@ export function ConversationPage() {
|
||||
setSending(true);
|
||||
setSendError(null);
|
||||
try {
|
||||
await send(text, attachments, replyTo?.id ?? null);
|
||||
await send(text, attachments, replyTo?.id ?? null, { viewOnce: viewOnceNext });
|
||||
setText('');
|
||||
setAttachments([]);
|
||||
setReplyTo(null);
|
||||
// Reset the sticky view-once flag so it only applies to the message
|
||||
// the user explicitly armed it for — Snapchat / WhatsApp parity.
|
||||
setViewOnceNext(false);
|
||||
if (fileInputRef.current) fileInputRef.current.value = '';
|
||||
setStickToBottom(true);
|
||||
notifyStopTyping();
|
||||
@@ -1012,6 +1020,20 @@ export function ConversationPage() {
|
||||
onPick={(gif) => void handleGifPick(gif)}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setViewOnceNext((v) => !v)}
|
||||
aria-pressed={viewOnceNext}
|
||||
title={viewOnceNext ? 'Nächstes Bild: einmal ansehen' : 'Nächstes Bild: normal'}
|
||||
className={
|
||||
'flex h-9 w-9 cursor-pointer items-center justify-center rounded-md transition ' +
|
||||
(viewOnceNext
|
||||
? 'bg-accent/20 text-accent'
|
||||
: 'text-fg-muted hover:bg-surface-3 hover:text-fg')
|
||||
}
|
||||
>
|
||||
<EyeOffIcon className="h-4 w-4" />
|
||||
</button>
|
||||
<VoiceRecorder
|
||||
disabled={sending}
|
||||
onComplete={async (file) => {
|
||||
|
||||
Reference in New Issue
Block a user