fix
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
ImageIcon,
|
||||
Loader2,
|
||||
LogOut,
|
||||
MapPin,
|
||||
Mic,
|
||||
Paperclip,
|
||||
Pin,
|
||||
@@ -60,6 +61,8 @@ import { InlineEditableTitle } from '@/components/chat/inline-editable-title';
|
||||
import { RepliedMessagePreview, scrollToChatMessage } from '@/components/chat/replied-message-preview';
|
||||
import { TypingIndicator } from '@/components/chat/typing-indicator';
|
||||
import { VoiceMessagePlayer } from '@/components/chat/voice-message-player';
|
||||
import { ChatLocationCard } from '@/components/chat/chat-location-card';
|
||||
import { ChatLocationShareDialog, type ChatLocationSharePayload } from '@/components/chat/chat-location-share-dialog';
|
||||
import { ChatVideoCaptureDialog, type ChatVideoCaptureMode } from '@/components/chat/chat-video-capture-dialog';
|
||||
import { ChatVideoNotePlayer } from '@/components/chat/chat-video-note-player';
|
||||
import { ChatVideoPlayer } from '@/components/chat/chat-video-player';
|
||||
@@ -145,6 +148,7 @@ import {
|
||||
detectChatMessageType,
|
||||
fileIconLabel,
|
||||
formatFileSize,
|
||||
parseLocationMetadata,
|
||||
parseMessageMetadata,
|
||||
resolveChatContentType
|
||||
} from '@/lib/chat-media';
|
||||
@@ -320,6 +324,7 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
|
||||
const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);
|
||||
const [videoCaptureOpen, setVideoCaptureOpen] = useState(false);
|
||||
const [videoCaptureMode, setVideoCaptureMode] = useState<ChatVideoCaptureMode>('note');
|
||||
const [locationShareOpen, setLocationShareOpen] = useState(false);
|
||||
|
||||
const mediaComposer = useChatMediaComposer();
|
||||
|
||||
@@ -1344,6 +1349,57 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function sendLocation(payload: ChatLocationSharePayload) {
|
||||
if (!token || !activeRoomId || !activeRoom || sending) return;
|
||||
setSending(true);
|
||||
try {
|
||||
const content =
|
||||
payload.label?.trim() ||
|
||||
payload.address?.trim() ||
|
||||
`${payload.latitude.toFixed(6)}, ${payload.longitude.toFixed(6)}`;
|
||||
const metadataJson = JSON.stringify({
|
||||
latitude: payload.latitude,
|
||||
longitude: payload.longitude,
|
||||
address: payload.address,
|
||||
label: payload.label
|
||||
});
|
||||
|
||||
let messageContent = content;
|
||||
let isEncrypted = false;
|
||||
if (activeRoomIsE2E) {
|
||||
messageContent = await encryptOutgoing({
|
||||
kind: 'location',
|
||||
text: content,
|
||||
latitude: payload.latitude,
|
||||
longitude: payload.longitude,
|
||||
address: payload.address,
|
||||
label: payload.label
|
||||
});
|
||||
isEncrypted = true;
|
||||
}
|
||||
|
||||
const message = await sendChatMessage(
|
||||
activeRoomId,
|
||||
{
|
||||
type: 'LOCATION',
|
||||
content: messageContent,
|
||||
isEncrypted,
|
||||
metadataJson: activeRoomIsE2E ? undefined : metadataJson,
|
||||
replyToId: replyToMessage?.id
|
||||
},
|
||||
token
|
||||
);
|
||||
appendMessage(message);
|
||||
setLocationShareOpen(false);
|
||||
setReplyToMessage(null);
|
||||
void loadGroup();
|
||||
} catch (error) {
|
||||
showToast(getApiErrorMessage(error, 'Не удалось отправить геопозицию') ?? 'Ошибка');
|
||||
} finally {
|
||||
setSending(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadChatFile(file: File, options?: { voice?: boolean; videoNote?: boolean; durationMs?: number }) {
|
||||
if (!token || !activeRoomId || !activeRoom) return;
|
||||
const contentType = resolveChatContentType(file);
|
||||
@@ -2051,6 +2107,22 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : message.type === 'LOCATION' ? (
|
||||
(() => {
|
||||
const locationMeta = parseLocationMetadata(message.metadataJson, e2ePayload);
|
||||
if (!locationMeta || locationMeta.latitude == null || locationMeta.longitude == null) {
|
||||
return <p className="text-sm text-[#667085]">Геопозиция недоступна</p>;
|
||||
}
|
||||
return (
|
||||
<ChatLocationCard
|
||||
latitude={locationMeta.latitude}
|
||||
longitude={locationMeta.longitude}
|
||||
address={locationMeta.address}
|
||||
label={locationMeta.label}
|
||||
variant={mine ? 'mine' : 'theirs'}
|
||||
/>
|
||||
);
|
||||
})()
|
||||
) : message.storageKey ? (
|
||||
(() => {
|
||||
if (isAlbumGroup) {
|
||||
@@ -2337,6 +2409,18 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
|
||||
<Button size="sm" variant="ghost" className="h-10 w-10 rounded-xl p-0" onClick={() => fileInputRef.current?.click()}>
|
||||
<Paperclip className="h-4 w-4" />
|
||||
</Button>
|
||||
{!activeRoomIsBot ? (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="h-10 w-10 rounded-xl p-0"
|
||||
onClick={() => setLocationShareOpen(true)}
|
||||
title="Отправить геопозицию"
|
||||
aria-label="Отправить геопозицию"
|
||||
>
|
||||
<MapPin className="h-4 w-4" />
|
||||
</Button>
|
||||
) : null}
|
||||
{!activeRoomIsE2E ? (
|
||||
<Button size="sm" variant="ghost" className="hidden h-10 w-10 rounded-xl p-0 sm:flex" onClick={() => setPollOpen(true)}>
|
||||
<BarChart3 className="h-4 w-4" />
|
||||
@@ -2465,6 +2549,14 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
|
||||
}}
|
||||
/>
|
||||
|
||||
<ChatLocationShareDialog
|
||||
open={locationShareOpen}
|
||||
sending={sending}
|
||||
onOpenChange={setLocationShareOpen}
|
||||
onSend={sendLocation}
|
||||
onLocateError={(message) => showToast(message)}
|
||||
/>
|
||||
|
||||
<ChatMediaComposeDialog
|
||||
open={mediaComposer.open}
|
||||
items={mediaComposer.items}
|
||||
|
||||
Reference in New Issue
Block a user