diff --git a/locales/en-US.yml b/locales/en-US.yml
index d44868618733..b1725a2fb832 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -1098,6 +1098,10 @@ expired: "Expired"
doYouAgree: "Agree?"
beSureToReadThisAsItIsImportant: "Please read this important information."
iHaveReadXCarefullyAndAgree: "I have read the text \"{x}\" and agree."
+releaseToRefresh: "Release to reload"
+refreshing: "Reloading"
+pullDownToRefresh: "Pull down to reload"
+disableStreamingTimeline: "Disable realtime update on timeline"
_initialAccountSetting:
accountCreated: "Your account was successfully created!"
letsStartAccountSetup: "For starters, let's set up your profile."
diff --git a/locales/index.d.ts b/locales/index.d.ts
index b0b8a256f2fa..114247b4375a 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1109,6 +1109,10 @@ export interface Locale {
"pastAnnouncements": string;
"youHaveUnreadAnnouncements": string;
"externalServices": string;
+ "releaseToRefresh": string;
+ "refreshing": string;
+ "pullDownToRefresh": string;
+ "disableStreamingTimeline": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 979022e33a33..907cbf0f5f16 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1106,6 +1106,10 @@ currentAnnouncements: "現在のお知らせ"
pastAnnouncements: "過去のお知らせ"
youHaveUnreadAnnouncements: "未読のお知らせがあります。"
externalServices: "外部サービス"
+releaseToRefresh: "離してリロード"
+refreshing: "リロード中"
+pullDownToRefresh: "引っ張ってリロード"
+disableStreamingTimeline: "タイムラインのリアルタイム更新を無効にする"
_announcement:
forExistingUsers: "既存ユーザーのみ"
diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts
index 2038ef3455f1..6f5ddcac14b9 100644
--- a/packages/frontend/src/boot/main-boot.ts
+++ b/packages/frontend/src/boot/main-boot.ts
@@ -8,7 +8,7 @@ import { common } from './common';
import { version, ui, lang, updateLocale } from '@/config';
import { i18n, updateI18n } from '@/i18n';
import { confirm, alert, post, popup, toast } from '@/os';
-import { useStream } from '@/stream';
+import { useStream, isReloading } from '@/stream';
import * as sound from '@/scripts/sound';
import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
import { defaultStore, ColdDeviceStorage } from '@/store';
@@ -39,6 +39,7 @@ export async function mainBoot() {
let reloadDialogShowing = false;
stream.on('_disconnected_', async () => {
+ if (isReloading) return;
if (defaultStore.state.serverDisconnectedBehavior === 'reload') {
location.reload();
} else if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index c090b4b691f8..64d6c4d2ccd6 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -166,6 +166,8 @@ defineExpose({
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index 714bc17e7bb4..e7498695ba11 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -4,13 +4,16 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
-
+ reloadTimeline(true)">
+
+