diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index c2241e6c12..d09a769a3b 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -239,6 +239,8 @@ avatar: "アイコン"
 banner: "バナー"
 nsfw: "閲覧注意"
 disconnectedFromServer: "サーバーから切断されました"
+reload: "リロード"
+doNothing: "なにもしない"
 reloadConfirm: "リロードしますか?"
 watch: "ウォッチ"
 unwatch: "ウォッチ解除"
diff --git a/src/client/app.vue b/src/client/app.vue
index cfb17c05f9..34e2dbf7fb 100644
--- a/src/client/app.vue
+++ b/src/client/app.vue
@@ -159,6 +159,8 @@
 	<transition name="zoom-in-top">
 		<x-notifications v-if="notificationsOpen" class="notifications" ref="notifications"/>
 	</transition>
+
+	<stream-indicator v-if="$store.getters.isSignedIn"/>
 </div>
 </template>
 
@@ -201,7 +203,6 @@ export default Vue.extend({
 			widgetsEditMode: false,
 			isDesktop: window.innerWidth >= DESKTOP_THRESHOLD,
 			canBack: false,
-			disconnectedDialog: null as Promise<void> | null,
 			wallpaper: localStorage.getItem('wallpaper') != null,
 			faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer
 		};
@@ -265,30 +266,6 @@ export default Vue.extend({
 				}]);
 			}
 		}
-
-		this.$root.stream.on('_disconnected_', () => {
-			if (this.disconnectedDialog) return;
-			if (this.$store.state.device.autoReload) {
-				location.reload();
-				return;
-			}
-
-			setTimeout(() => {
-				if (this.$root.stream.state !== 'reconnecting') return;
-
-				this.disconnectedDialog = this.$root.dialog({
-					type: 'warning',
-					showCancelButton: true,
-					title: this.$t('disconnectedFromServer'),
-					text: this.$t('reloadConfirm'),
-				}).then(({ canceled }) => {
-					if (!canceled) {
-						location.reload();
-					}
-					this.disconnectedDialog = null;
-				});
-			}, 150)
-		});
 	},
 
 	mounted() {
diff --git a/src/client/components/index.ts b/src/client/components/index.ts
index 9385c2af73..9e95fba873 100644
--- a/src/client/components/index.ts
+++ b/src/client/components/index.ts
@@ -11,6 +11,7 @@ import url from './url.vue';
 import loading from './loading.vue';
 import SequentialEntrance from './sequential-entrance.vue';
 import error from './error.vue';
+import streamIndicator from './stream-indicator.vue';
 
 Vue.component('mfm', mfm);
 Vue.component('mk-acct', acct);
@@ -23,3 +24,4 @@ Vue.component('mk-url', url);
 Vue.component('mk-loading', loading);
 Vue.component('mk-error', error);
 Vue.component('sequential-entrance', SequentialEntrance);
+Vue.component('stream-indicator', streamIndicator);
diff --git a/src/client/components/stream-indicator.vue b/src/client/components/stream-indicator.vue
new file mode 100644
index 0000000000..dd7a5d07c1
--- /dev/null
+++ b/src/client/components/stream-indicator.vue
@@ -0,0 +1,80 @@
+<template>
+<div class="nsbbhtug" v-if="hasDisconnected" @click="resetDisconnected">
+	<div>{{ $t('disconnectedFromServer') }}</div>
+	<div class="command">
+		<button class="_textButton" @click="reload">{{ $t('reload') }}</button>
+		<button class="_textButton">{{ $t('doNothing') }}</button>
+	</div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import i18n from '../i18n';
+
+export default Vue.extend({
+	i18n,
+	data() {
+		return {
+			hasDisconnected: false,
+		}
+	},
+	computed: {
+		stream() {
+			return this.$root.stream;
+		},
+	},
+	created() {
+		this.$root.stream.on('_connected_', this.onConnected);
+		this.$root.stream.on('_disconnected_', this.onDisconnected);
+	},
+	beforeDestroy() {
+		this.$root.stream.off('_connected_', this.onConnected);
+		this.$root.stream.off('_disconnected_', this.onDisconnected);
+	},
+	methods: {
+		onConnected() {
+			if (this.hasDisconnected) {
+				if (this.$store.state.device.autoReload) {
+					this.reload();
+				}
+			}
+		},
+		onDisconnected() {
+			this.hasDisconnected = true;
+		},
+		resetDisconnected() {
+			this.hasDisconnected = false;
+		},
+		reload() {
+			location.reload();
+		},
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.nsbbhtug {
+	position: fixed;
+	z-index: 16385;
+	bottom: 8px;
+	right: 8px;
+	margin: 0;
+	padding: 6px 12px;
+	font-size: 0.9em;
+	color: #fff;
+	background: #000;
+	opacity: 0.8;
+	border-radius: 4px;
+	max-width: 320px;
+
+	> .command {
+		display: flex;
+		justify-content: space-around;
+
+		> button {
+			padding: 0.7em;
+		}
+	}
+}
+</style>