diff --git a/external/lang b/external/lang
index 47182fb7112f82efa61ffe2856f25ca19c78b8c5..456777fcf68daaa3d1a5ceb6442f222cdc9e415d 160000
--- a/external/lang
+++ b/external/lang
@@ -1 +1 @@
-Subproject commit 47182fb7112f82efa61ffe2856f25ca19c78b8c5
+Subproject commit 456777fcf68daaa3d1a5ceb6442f222cdc9e415d
diff --git a/package.json b/package.json
index b6235533f360bbe6a12af29007b129797e2bb7de..3c7113141d0d61f47f3209a36f0e55d5b169bf96 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,7 @@
     "react-scroll": "^1.8.2",
     "react-tippy": "^1.4.0",
     "redux": "^4.1.0",
-    "revolt.js": "4.3.2-patch.1",
+    "revolt.js": "4.3.3-alpha.1",
     "rimraf": "^3.0.2",
     "sass": "^1.35.1",
     "shade-blend-color": "^1.0.0",
diff --git a/src/components/common/messaging/MessageBox.tsx b/src/components/common/messaging/MessageBox.tsx
index 86463d3a385966572b6eafcbdec36af8dec6f4ff..ea8391a5175e78086d6ac0a16ba0b5d42888c417 100644
--- a/src/components/common/messaging/MessageBox.tsx
+++ b/src/components/common/messaging/MessageBox.tsx
@@ -1,18 +1,23 @@
 import { ulid } from "ulid";
+import { Text } from "preact-i18n";
 import { Channel } from "revolt.js";
 import styled from "styled-components";
 import { defer } from "../../../lib/defer";
 import IconButton from "../../ui/IconButton";
-import { Send } from '@styled-icons/feather';
+import { Send, X } from '@styled-icons/feather';
 import { debounce } from "../../../lib/debounce";
 import Axios, { CancelTokenSource } from "axios";
 import { useTranslation } from "../../../lib/i18n";
 import { Reply } from "../../../redux/reducers/queue";
 import { connectState } from "../../../redux/connector";
+import { SoundContext } from "../../../context/Settings";
 import { WithDispatcher } from "../../../redux/reducers";
 import { takeError } from "../../../context/revoltjs/util";
 import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
+import AutoComplete, { useAutoComplete } from "../AutoComplete";
+import { ChannelPermission } from "revolt.js/dist/api/permissions";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
+import { useChannelPermission } from "../../../context/revoltjs/hooks";
 import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
 import { internalEmit, internalSubscribe } from "../../../lib/eventEmitter";
 import { useCallback, useContext, useEffect, useState } from "preact/hooks";
@@ -22,8 +27,6 @@ import { SingletonMessageRenderer, SMOOTH_SCROLL_ON_RECEIVE } from "../../../lib
 
 import ReplyBar from "./bars/ReplyBar";
 import FilePreview from './bars/FilePreview';
-import AutoComplete, { useAutoComplete } from "../AutoComplete";
-import { SoundContext } from "../../../context/Settings";
 
 type Props = WithDispatcher & {
     channel: Channel;
@@ -48,6 +51,14 @@ const Base = styled.div`
     }
 `;
 
+const Blocked = styled.div`
+    padding: 15px 0;
+    line-height: 20px;
+    user-select: none;
+    font-size: .875rem;
+    color: var(--tertiary-foreground);
+`;
+
 const Action = styled.div`
     display: grid;
     place-items: center;
@@ -65,6 +76,15 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
     const client = useContext(AppContext);
     const translate = useTranslation();
 
+    const permissions = useChannelPermission(channel._id);
+    if (!(permissions & ChannelPermission.SendMessage)) {
+        return (
+            <Base>
+                <Blocked><Text id="app.main.channel.misc.no_sending" /></Blocked>
+            </Base>
+        )
+    }
+
     function setMessage(content?: string) {
         if (content) {
             dispatcher({
@@ -272,7 +292,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
                 }} />
             <ReplyBar channel={channel._id} replies={replies} setReplies={setReplies} />
             <Base>
-                <Action>
+                { (permissions & ChannelPermission.UploadFiles) ? <Action>
                     <FileUploader
                         size={24}
                         behaviour='multi'
@@ -296,7 +316,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
                             }
                         }}
                     />
-                </Action>
+                </Action> : undefined }
                 <TextAreaAutoSize
                     autoFocus
                     hideBorder
@@ -338,11 +358,11 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
                     }}
                     onFocus={onFocus}
                     onBlur={onBlur} />
-                <Action>
+                { isTouchscreenDevice && <Action>
                     <IconButton onClick={send}>
                         <Send size={20} />
                     </IconButton>
-                </Action>
+                </Action> }
             </Base>
         </>
     )
diff --git a/yarn.lock b/yarn.lock
index 182a62772a6fbe06463038c378223f82cdce90cf..595a23ce5fe72c1019ed08c5c9680ea70b4f888c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3412,10 +3412,10 @@ reusify@^1.0.4:
   resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
   integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
 
-revolt.js@4.3.2-patch.1:
-  version "4.3.2-patch.1"
-  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.2-patch.1.tgz#0c4190f0a640951636c6f2577c9298418b06917f"
-  integrity sha512-XAu2JeYc2+OFLM56WktGT/4tAyvjibmNL5oGc5pPZEjl0DnoIxPE96CZPe+35ZCX9bEiuoX378Fwfmfe3uN7sw==
+revolt.js@4.3.3-alpha.1:
+  version "4.3.3-alpha.1"
+  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.1.tgz#b60a18e5cbe9f2c569e7f46974450931826e10d4"
+  integrity sha512-MxjTOWqg83cLYdpuqLCl3nOTD+jFxSSjrnvczuijam1YjeZ3IB27C6G4Qar3BwMn7B+zH8MgEDecW3YBmKBpIw==
   dependencies:
     "@insertish/mutable" "1.1.0"
     axios "^0.19.2"