diff --git a/web/src/components/ChatInfoPanel.tsx b/web/src/components/ChatInfoPanel.tsx index ac4aab8..0cb8c36 100644 --- a/web/src/components/ChatInfoPanel.tsx +++ b/web/src/components/ChatInfoPanel.tsx @@ -611,7 +611,7 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) { } }} > - Leave chat + {chat.type === "channel" ? "Leave channel" : "Leave chat"} ) : null} diff --git a/web/src/components/MessageComposer.tsx b/web/src/components/MessageComposer.tsx index 0c3841a..10a99a1 100644 --- a/web/src/components/MessageComposer.tsx +++ b/web/src/components/MessageComposer.tsx @@ -9,6 +9,7 @@ type RecordingState = "idle" | "recording" | "locked"; export function MessageComposer() { const activeChatId = useChatStore((s) => s.activeChatId); + const chats = useChatStore((s) => s.chats); const me = useAuthStore((s) => s.me); const draftsByChat = useChatStore((s) => s.draftsByChat); const setDraft = useChatStore((s) => s.setDraft); @@ -52,6 +53,12 @@ export function MessageComposer() { const [recordSeconds, setRecordSeconds] = useState(0); const [dragHint, setDragHint] = useState<"idle" | "lock" | "cancel">("idle"); const hasTextToSend = text.trim().length > 0; + const activeChat = chats.find((chat) => chat.id === activeChatId); + const canSendInActiveChat = Boolean( + activeChatId && + activeChat && + (activeChat.type !== "channel" || activeChat.my_role === "owner" || activeChat.my_role === "admin" || activeChat.is_saved) + ); useEffect(() => { recordingStateRef.current = recordingState; @@ -146,7 +153,7 @@ export function MessageComposer() { } async function handleSend() { - if (!activeChatId || !text.trim() || !me) { + if (!activeChatId || !text.trim() || !me || !canSendInActiveChat) { return; } const clientMessageId = makeClientMessageId(); @@ -205,7 +212,7 @@ export function MessageComposer() { messageType: "file" | "image" | "video" | "audio" | "voice" | "circle_video" = "file", waveformPoints?: number[] | null ) { - if (!activeChatId || !me) { + if (!activeChatId || !me || !canSendInActiveChat) { return; } setIsUploading(true); @@ -303,7 +310,7 @@ export function MessageComposer() { } async function startRecord() { - if (recordingState !== "idle") { + if (recordingState !== "idle" || !canSendInActiveChat) { return false; } try { @@ -694,11 +701,17 @@ export function MessageComposer() { ) : null} + {!canSendInActiveChat && activeChat?.type === "channel" ? ( +
+ Read-only channel: only owners and admins can post. +
+ ) : null} +
@@ -765,9 +779,10 @@ export function MessageComposer() {