feat(web): remove circle video compose flow from web client
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-03-08 21:35:58 +03:00
parent f3a00155d3
commit 119b423632
3 changed files with 5 additions and 32 deletions

View File

@@ -67,6 +67,8 @@ For `/health/ready` failure:
- `file` - `file`
- `circle_video` - `circle_video`
Note: `circle_video` is kept for API/mobile parity. Web client currently sends regular `video` (no circle compose UI).
### Message status events ### Message status events
- `message_delivered` - `message_delivered`

View File

@@ -24,7 +24,7 @@ Legend:
15. Typing Realtime - `DONE` (typing start/stop + recording voice start/stop + recording video start/stop in circle-video send flow) 15. Typing Realtime - `DONE` (typing start/stop + recording voice start/stop + recording video start/stop in circle-video send flow)
16. Media & Attachments - `DONE` (upload/preview/download/gallery; sticker/GIF inline media no longer opens photo viewer on click) 16. Media & Attachments - `DONE` (upload/preview/download/gallery; sticker/GIF inline media no longer opens photo viewer on click)
17. Voice Messages - `PARTIAL` (record/send/play/seek + global speed 1x/1.5x/2x; recorder uses improved mime priority for better duration metadata; backend media allowlist includes `audio/mp4`/`audio/x-m4a`; audio store tracks duration via `durationchange/seekable` fallback; websocket send/recorder stop race on fast chat switch is guarded; UX still being polished) 17. Voice Messages - `PARTIAL` (record/send/play/seek + global speed 1x/1.5x/2x; recorder uses improved mime priority for better duration metadata; backend media allowlist includes `audio/mp4`/`audio/x-m4a`; audio store tracks duration via `durationchange/seekable` fallback; websocket send/recorder stop race on fast chat switch is guarded; UX still being polished)
18. Circle Video Messages - `PARTIAL` (send/play present, recording UX basic) 18. Circle Video Messages - `PARTIAL` (mobile-priority only: backend type/realtime supported; web composer intentionally does not send circles)
19. Stickers - `PARTIAL` (web sticker picker with preset pack + favorites) 19. Stickers - `PARTIAL` (web sticker picker with preset pack + favorites)
20. GIF - `PARTIAL` (web GIF picker with Tenor search + preset fallback + favorites) 20. GIF - `PARTIAL` (web GIF picker with Tenor search + preset fallback + favorites)
21. Message History/Search - `DONE` (history/pagination/chat+global search) 21. Message History/Search - `DONE` (history/pagination/chat+global search)

View File

@@ -117,7 +117,6 @@ export function MessageComposer() {
const [uploadError, setUploadError] = useState<string | null>(null); const [uploadError, setUploadError] = useState<string | null>(null);
const [selectedFiles, setSelectedFiles] = useState<File[]>([]); const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const [selectedType, setSelectedType] = useState<"file" | "image" | "video" | "audio">("file"); const [selectedType, setSelectedType] = useState<"file" | "image" | "video" | "audio">("file");
const [sendAsCircle, setSendAsCircle] = useState(false);
const [previewUrl, setPreviewUrl] = useState<string | null>(null); const [previewUrl, setPreviewUrl] = useState<string | null>(null);
const [showAttachMenu, setShowAttachMenu] = useState(false); const [showAttachMenu, setShowAttachMenu] = useState(false);
const [showFormatMenu, setShowFormatMenu] = useState(false); const [showFormatMenu, setShowFormatMenu] = useState(false);
@@ -546,11 +545,7 @@ export function MessageComposer() {
} }
} }
async function handleUpload( async function handleUpload(file: File, messageType: "file" | "image" | "video" | "audio" | "voice" = "file", waveformPoints?: number[] | null) {
file: File,
messageType: "file" | "image" | "video" | "audio" | "voice" | "circle_video" = "file",
waveformPoints?: number[] | null
) {
if (!activeChatId || !me || !canSendInActiveChat) { if (!activeChatId || !me || !canSendInActiveChat) {
return; return;
} }
@@ -827,7 +822,6 @@ export function MessageComposer() {
setShowAttachMenu(false); setShowAttachMenu(false);
const fileType = inferType(files[0]); const fileType = inferType(files[0]);
setSelectedType(fileType); setSelectedType(fileType);
setSendAsCircle(false);
if (previewUrl) { if (previewUrl) {
URL.revokeObjectURL(previewUrl); URL.revokeObjectURL(previewUrl);
} }
@@ -842,12 +836,6 @@ export function MessageComposer() {
if (!selectedFiles.length || !activeChatId || !me) { if (!selectedFiles.length || !activeChatId || !me) {
return; return;
} }
const isCircleVideoFlow =
selectedFiles.length === 1 && inferType(selectedFiles[0]) === "video" && sendAsCircle;
if (isCircleVideoFlow) {
emitTypingStopIfActive();
sendRealtimeChatEvent("recording_video_start");
}
setIsUploading(true); setIsUploading(true);
setUploadError(null); setUploadError(null);
setUploadProgress(0); setUploadProgress(0);
@@ -886,8 +874,7 @@ export function MessageComposer() {
} else if (kindSet.size === 1) { } else if (kindSet.size === 1) {
inferredType = uploaded[0].kind; inferredType = uploaded[0].kind;
} }
const messageType = const messageType = inferredType;
inferredType === "video" && uploaded.length === 1 && sendAsCircle ? "circle_video" : inferredType;
const caption = captionDraft.trim() || null; const caption = captionDraft.trim() || null;
const clientMessageId = makeClientMessageId(); const clientMessageId = makeClientMessageId();
addOptimisticMessage({ addOptimisticMessage({
@@ -915,9 +902,6 @@ export function MessageComposer() {
} finally { } finally {
setIsUploading(false); setIsUploading(false);
setUploadProgress(0); setUploadProgress(0);
if (isCircleVideoFlow) {
sendRealtimeChatEvent("recording_video_stop");
}
} }
if (previewUrl) { if (previewUrl) {
URL.revokeObjectURL(previewUrl); URL.revokeObjectURL(previewUrl);
@@ -926,7 +910,6 @@ export function MessageComposer() {
setPreviewUrl(null); setPreviewUrl(null);
setCaptionDraft(""); setCaptionDraft("");
setSelectedType("file"); setSelectedType("file");
setSendAsCircle(false);
} }
function cancelSelectedFile() { function cancelSelectedFile() {
@@ -937,7 +920,6 @@ export function MessageComposer() {
setPreviewUrl(null); setPreviewUrl(null);
setCaptionDraft(""); setCaptionDraft("");
setSelectedType("file"); setSelectedType("file");
setSendAsCircle(false);
setUploadProgress(0); setUploadProgress(0);
setUploadError(null); setUploadError(null);
} }
@@ -1452,17 +1434,6 @@ export function MessageComposer() {
value={captionDraft} value={captionDraft}
onChange={(event) => setCaptionDraft(event.target.value)} onChange={(event) => setCaptionDraft(event.target.value)}
/> />
{selectedType === "video" && selectedFiles.length === 1 ? (
<label className="mb-2 flex items-center gap-2 text-xs text-slate-300">
<input
checked={sendAsCircle}
onChange={(event) => setSendAsCircle(event.target.checked)}
type="checkbox"
/>
Send as video message (circle)
</label>
) : null}
{isUploading ? ( {isUploading ? (
<div className="mb-2"> <div className="mb-2">
<div className="mb-1 text-xs text-slate-300">Uploading: {uploadProgress}%</div> <div className="mb-1 text-xs text-slate-300">Uploading: {uploadProgress}%</div>