diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index a927d108bb..e7057e3f89 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -706,6 +706,7 @@ receiveAnnouncementFromInstance: "インスタンスからのお知らせを受
 emailNotification: "メール通知"
 inChannelSearch: "チャンネル内検索"
 useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開く"
+typingUsers: "{users}が入力中"
 
 _email:
   _follow:
diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue
index fa9aeff8af..7849095ba8 100644
--- a/src/client/components/post-form.vue
+++ b/src/client/components/post-form.vue
@@ -70,6 +70,7 @@ import * as os from '@/os';
 import { selectFile } from '@/scripts/select-file';
 import { notePostInterruptors, postFormActions } from '@/store';
 import { isMobile } from '@/scripts/is-mobile';
+import { throttle } from 'throttle-debounce';
 
 export default defineComponent({
 	components: {
@@ -144,6 +145,11 @@ export default defineComponent({
 			quoteId: null,
 			recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
 			imeText: '',
+			typing: throttle(3000, () => {
+				if (this.channel) {
+					os.stream.send('typingOnChannel', { channel: this.channel.id });
+				}
+			}),
 			postFormActions,
 			faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
 		};
@@ -434,10 +440,12 @@ export default defineComponent({
 		onKeydown(e: KeyboardEvent) {
 			if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
 			if (e.which === 27) this.$emit('esc');
+			this.typing();
 		},
 
 		onCompositionUpdate(e: CompositionEvent) {
 			this.imeText = e.data;
+			this.typing();
 		},
 
 		onCompositionEnd(e: CompositionEvent) {
diff --git a/src/client/ui/chat/date-separated-list.vue b/src/client/ui/chat/date-separated-list.vue
index b209330656..65deb9e1c2 100644
--- a/src/client/ui/chat/date-separated-list.vue
+++ b/src/client/ui/chat/date-separated-list.vue
@@ -32,7 +32,7 @@ export default defineComponent({
 			});
 		}
 
-		return h(TransitionGroup, {
+		return h(this.reversed ? 'div' : TransitionGroup, {
 			class: 'hmjzthxl',
 			name: this.reversed ? 'list-reversed' : 'list',
 			tag: 'div',
diff --git a/src/client/ui/chat/index.vue b/src/client/ui/chat/index.vue
index dd3c82d8ba..0ee32833a8 100644
--- a/src/client/ui/chat/index.vue
+++ b/src/client/ui/chat/index.vue
@@ -114,14 +114,9 @@
 				
 			
 		
-		
-			
-			
-		
-		
+
+		
+		
 	
 
 	
@@ -143,7 +138,6 @@ import XWidgets from './widgets.vue';
 import XCommon from '../_common_/common.vue';
 import XSide from './side.vue';
 import XTimeline from './timeline.vue';
-import XPostForm from './post-form.vue';
 import XHeaderClock from './header-clock.vue';
 import * as os from '@/os';
 import { router } from '@/router';
@@ -159,7 +153,6 @@ export default defineComponent({
 		XWidgets,
 		XSide, // NOTE: dynamic importするとAsyncComponentWrapperが間に入るせいでref取得できなくて面倒になる
 		XTimeline,
-		XPostForm,
 		XHeaderClock,
 	},
 
@@ -584,16 +577,6 @@ export default defineComponent({
 				}
 			}
 		}
-
-		> .footer {
-			padding: 0 16px 16px 16px;
-		}
-
-		> .body {
-			flex: 1;
-			min-width: 0;
-			overflow: auto;
-		}
 	}
 
 	> .side {
diff --git a/src/client/ui/chat/note.vue b/src/client/ui/chat/note.vue
index 4e4a303c36..315f5c91e3 100644
--- a/src/client/ui/chat/note.vue
+++ b/src/client/ui/chat/note.vue
@@ -1010,7 +1010,7 @@ export default defineComponent({
 			flex-shrink: 0;
 			display: block;
 			position: sticky;
-			top: 12px;
+			top: 0;
 			margin: 0 14px 0 0;
 			width: 46px;
 			height: 46px;
diff --git a/src/client/ui/chat/post-form.vue b/src/client/ui/chat/post-form.vue
index 38fe48cc62..b0a31b097d 100644
--- a/src/client/ui/chat/post-form.vue
+++ b/src/client/ui/chat/post-form.vue
@@ -65,6 +65,7 @@ import * as os from '@/os';
 import { selectFile } from '@/scripts/select-file';
 import { notePostInterruptors, postFormActions } from '@/store';
 import { isMobile } from '@/scripts/is-mobile';
+import { throttle } from 'throttle-debounce';
 
 export default defineComponent({
 	components: {
@@ -131,6 +132,11 @@ export default defineComponent({
 			quoteId: null,
 			recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
 			imeText: '',
+			typing: throttle(3000, () => {
+				if (this.channel) {
+					os.stream.send('typingOnChannel', { channel: this.channel });
+				}
+			}),
 			postFormActions,
 			faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
 		};
@@ -421,10 +427,12 @@ export default defineComponent({
 		onKeydown(e: KeyboardEvent) {
 			if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
 			if (e.which === 27) this.$emit('esc');
+			this.typing();
 		},
 
 		onCompositionUpdate(e: CompositionEvent) {
 			this.imeText = e.data;
+			this.typing();
 		},
 
 		onCompositionEnd(e: CompositionEvent) {
diff --git a/src/client/ui/chat/timeline.vue b/src/client/ui/chat/timeline.vue
index f96a48a776..12cb7af7d2 100644
--- a/src/client/ui/chat/timeline.vue
+++ b/src/client/ui/chat/timeline.vue
@@ -1,8 +1,22 @@
 
-
+
+	
+
+
+
+	
+		
+			
+				{{ user.username }}
+			
+		
+		
+	
+	
+