From 8c2ab25e5f2040fcbc81bc2a02a279fed40e1c11 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Fri, 9 May 2025 17:40:08 +0900
Subject: Feat: No websocket mode (#15851)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* wip
* wip
* wip
* wip
* Update MkTimeline.vue
* wip
* wip
* wip
* Update MkTimeline.vue
* Update use-pagination.ts
* wip
* wip
* Update MkTimeline.vue
* Update MkTimeline.vue
* wip
* wip
* Update MkTimeline.vue
* Update MkTimeline.vue
* Update MkTimeline.vue
* wip
* Update use-pagination.ts
* wip
* Update use-pagination.ts
* Update MkNotifications.vue
* Update MkNotifications.vue
* wip
* wip
* wip
* Update use-note-capture.ts
* Update use-note-capture.ts
* Update use-note-capture.ts
* wip
* wip
* wip
* wip
* Update MkNoteDetailed.vue
* wip
* wip
* Update MkTimeline.vue
* wip
* fix
* Update MkTimeline.vue
* wip
* test
* Revert "test"
This reverts commit 3375619396c54dcda5e564eb1da444c2391208c9.
* Update use-pagination.ts
* test
* Revert "test"
This reverts commit 42c53c830e28485d2fb49061fa7cdeee31bc6a22.
* test
* Revert "test"
This reverts commit c4f8cda4aa1cec9d1eb97557145f3ad3d2d0e469.
* Update style.scss
* Update MkTimeline.vue
* Update MkTimeline.vue
* Update MkTimeline.vue
* ✌️
* Update MkTimeline.vue
* wip
* wip
* test
* Update MkPullToRefresh.vue
* Update MkPullToRefresh.vue
* Update MkPullToRefresh.vue
* Update MkPullToRefresh.vue
* Update MkTimeline.vue
* wip
* tweak navbar
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Update home.vue
* wip
* refactor
* wip
* wip
* Update note.vue
* Update navbar.vue
* Update MkPullToRefresh.vue
* Update MkPullToRefresh.vue
* Update MkPullToRefresh.vue
* wip
* Update MkStreamingNotificationsTimeline.vue
* Update use-pagination.ts
* wip
* improve perf
* wip
* Update MkNotesTimeline.vue
* wip
* megre
* Update use-pagination.ts
* Update use-pagination.ts
* Update MkStreamingNotesTimeline.vue
* Update use-pagination.ts
* Update CHANGELOG.md
* Update CHANGELOG.md
* Update CHANGELOG.md
---
packages/frontend/src/ui/_common_/common.vue | 22 +-
.../frontend/src/ui/_common_/navbar-for-mobile.vue | 273 ---------------------
packages/frontend/src/ui/_common_/navbar.vue | 198 +++++++++++----
.../frontend/src/ui/_common_/stream-indicator.vue | 11 +-
packages/frontend/src/ui/deck/antenna-column.vue | 9 +-
packages/frontend/src/ui/deck/channel-column.vue | 9 +-
packages/frontend/src/ui/deck/direct-column.vue | 10 +-
packages/frontend/src/ui/deck/list-column.vue | 9 +-
packages/frontend/src/ui/deck/mentions-column.vue | 12 +-
.../frontend/src/ui/deck/notifications-column.vue | 4 +-
.../frontend/src/ui/deck/role-timeline-column.vue | 9 +-
packages/frontend/src/ui/deck/tl-column.vue | 10 +-
12 files changed, 191 insertions(+), 385 deletions(-)
delete mode 100644 packages/frontend/src/ui/_common_/navbar-for-mobile.vue
(limited to 'packages/frontend/src/ui')
diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue
index 5fe99e0d14..fcf9fb234d 100644
--- a/packages/frontend/src/ui/_common_/common.vue
+++ b/packages/frontend/src/ui/_common_/common.vue
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:leaveToClass="prefer.s.animation ? $style.transition_menuDrawer_leaveTo : ''"
>
-
+
@@ -112,7 +112,8 @@ import { useStream } from '@/stream.js';
import { i18n } from '@/i18n.js';
import { prefer } from '@/preferences.js';
import { globalEvents } from '@/events.js';
-import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
+import { store } from '@/store.js';
+import XNavbar from '@/ui/_common_/navbar.vue';
const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue'));
const XUpload = defineAsyncComponent(() => import('./upload.vue'));
@@ -129,7 +130,9 @@ function onNotification(notification: Misskey.entities.Notification, isClient =
if (window.document.visibilityState === 'visible') {
if (!isClient && notification.type !== 'test') {
// サーバーサイドのテスト通知の際は自動で既読をつけない(テストできないので)
- useStream().send('readNotification');
+ if (store.s.realtimeMode) {
+ useStream().send('readNotification');
+ }
}
notifications.value.unshift(notification);
@@ -146,11 +149,12 @@ function onNotification(notification: Misskey.entities.Notification, isClient =
}
if ($i) {
- const connection = useStream().useChannel('main', null, 'UI');
- connection.on('notification', onNotification);
+ if (store.s.realtimeMode) {
+ const connection = useStream().useChannel('main');
+ connection.on('notification', onNotification);
+ }
globalEvents.on('clientNotification', notification => onNotification(notification, true));
- //#region Listen message from SW
if ('serviceWorker' in navigator) {
swInject();
}
@@ -226,12 +230,6 @@ if ($i) {
left: 0;
z-index: 1001;
height: 100dvh;
- width: 240px;
- box-sizing: border-box;
- contain: strict;
- overflow: auto;
- overscroll-behavior: contain;
- background: var(--MI_THEME-navBg);
}
.widgetsDrawerBg {
diff --git a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
deleted file mode 100644
index 826e03751a..0000000000
--- a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
+++ /dev/null
@@ -1,273 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{ i18n.ts.timeline }}
-
-
-
-
- {{ navbarItemDef[item].title }}
-
- {{ navbarItemDef[item].indicateValue }}
-
-
-
-
-
-
- {{ i18n.ts.controlPanel }}
-
-
-
- {{ i18n.ts.settings }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/frontend/src/ui/_common_/navbar.vue b/packages/frontend/src/ui/_common_/navbar.vue
index ce8efa3324..7cfedc939f 100644
--- a/packages/frontend/src/ui/_common_/navbar.vue
+++ b/packages/frontend/src/ui/_common_/navbar.vue
@@ -10,6 +10,9 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -50,6 +53,9 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -76,16 +82,18 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
-
+
+
+
+
+
@@ -108,15 +116,16 @@ const router = useRouter();
const props = defineProps<{
showWidgetButton?: boolean;
+ asDrawer?: boolean;
}>();
const emit = defineEmits<{
(ev: 'widgetButtonClick'): void;
}>();
-const forceIconOnly = ref(window.innerWidth <= 1279);
+const forceIconOnly = ref(!props.asDrawer && window.innerWidth <= 1279);
const iconOnly = computed(() => {
- return forceIconOnly.value || (store.r.menuDisplay.value === 'sideIcon');
+ return !props.asDrawer && (forceIconOnly.value || (store.r.menuDisplay.value === 'sideIcon'));
});
const otherMenuItemIndicated = computed(() => {
@@ -147,6 +156,20 @@ function toggleIconOnly() {
}
}
+function toggleRealtimeMode(ev: MouseEvent) {
+ os.popupMenu([{
+ type: 'label',
+ text: i18n.ts.realtimeMode,
+ }, {
+ text: store.s.realtimeMode ? i18n.ts.turnItOff : i18n.ts.turnItOn,
+ icon: store.s.realtimeMode ? 'ti ti-bolt-off' : 'ti ti-bolt',
+ action: () => {
+ store.set('realtimeMode', !store.s.realtimeMode);
+ window.location.reload();
+ },
+ }], ev.currentTarget ?? ev.target);
+}
+
function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({
withExtraOperation: true,
@@ -191,21 +214,108 @@ function menuEdit() {
overscroll-behavior: contain;
background: var(--MI_THEME-navBg);
contain: strict;
+
+ /* 画面が縦に長い、設置している項目数が少ないなどの環境においても確実にbottomを最下部に表示するため */
display: flex;
flex-direction: column;
- direction: rtl; // スクロールバーを左に表示したいため
+
+ direction: rtl; /* スクロールバーを左に表示したいため */
}
.top {
+ flex-shrink: 0;
direction: ltr;
+
+ /* 疑似progressive blur */
+ &::before {
+ position: absolute;
+ z-index: -1;
+ inset: 0;
+ content: "";
+ backdrop-filter: blur(8px);
+ mask-image: linear-gradient(
+ to top,
+ rgb(0 0 0 / 0%) 0%,
+ rgb(0 0 0 / 4.9%) 7.75%,
+ rgb(0 0 0 / 10.4%) 11.25%,
+ rgb(0 0 0 / 45%) 23.55%,
+ rgb(0 0 0 / 55%) 26.45%,
+ rgb(0 0 0 / 89.6%) 38.75%,
+ rgb(0 0 0 / 95.1%) 42.25%,
+ rgb(0 0 0 / 100%) 50%
+ );
+ }
+
+ &::after {
+ position: absolute;
+ z-index: -1;
+ inset: 0;
+ bottom: 25%;
+ content: "";
+ backdrop-filter: blur(16px);
+ mask-image: linear-gradient(
+ to top,
+ rgb(0 0 0 / 0%) 0%,
+ rgb(0 0 0 / 4.9%) 15.5%,
+ rgb(0 0 0 / 10.4%) 22.5%,
+ rgb(0 0 0 / 45%) 47.1%,
+ rgb(0 0 0 / 55%) 52.9%,
+ rgb(0 0 0 / 89.6%) 77.5%,
+ rgb(0 0 0 / 95.1%) 91.9%,
+ rgb(0 0 0 / 100%) 100%
+ );
+ }
}
.middle {
+ flex: 1;
direction: ltr;
}
.bottom {
+ flex-shrink: 0;
direction: ltr;
+
+ /* 疑似progressive blur */
+ &::before {
+ position: absolute;
+ z-index: -1;
+ inset: -30px 0 0 0;
+ content: "";
+ backdrop-filter: blur(8px);
+ mask-image: linear-gradient(
+ to bottom,
+ rgb(0 0 0 / 0%) 0%,
+ rgb(0 0 0 / 4.9%) 7.75%,
+ rgb(0 0 0 / 10.4%) 11.25%,
+ rgb(0 0 0 / 45%) 23.55%,
+ rgb(0 0 0 / 55%) 26.45%,
+ rgb(0 0 0 / 89.6%) 38.75%,
+ rgb(0 0 0 / 95.1%) 42.25%,
+ rgb(0 0 0 / 100%) 50%
+ );
+ pointer-events: none;
+ }
+
+ &::after {
+ position: absolute;
+ z-index: -1;
+ inset: 0;
+ top: 25%;
+ content: "";
+ backdrop-filter: blur(16px);
+ mask-image: linear-gradient(
+ to bottom,
+ rgb(0 0 0 / 0%) 0%,
+ rgb(0 0 0 / 4.9%) 15.5%,
+ rgb(0 0 0 / 10.4%) 22.5%,
+ rgb(0 0 0 / 45%) 47.1%,
+ rgb(0 0 0 / 55%) 52.9%,
+ rgb(0 0 0 / 89.6%) 77.5%,
+ rgb(0 0 0 / 95.1%) 91.9%,
+ rgb(0 0 0 / 100%) 100%
+ );
+ }
}
.subButtons {
@@ -290,29 +400,18 @@ function menuEdit() {
}
.top {
+ --top-height: 80px;
+
position: sticky;
top: 0;
z-index: 1;
- padding: 20px 0;
- background: var(--nav-bg-transparent);
- -webkit-backdrop-filter: var(--MI-blur, blur(8px));
- backdrop-filter: var(--MI-blur, blur(8px));
+ display: flex;
+ height: var(--top-height);
}
.instance {
position: relative;
- display: block;
- text-align: center;
- width: 100%;
-
- &:focus-visible {
- outline: none;
-
- > .instanceIcon {
- outline: 2px solid var(--MI_THEME-focus);
- outline-offset: 2px;
- }
- }
+ width: var(--top-height);
}
.instanceIcon {
@@ -322,13 +421,20 @@ function menuEdit() {
border-radius: 8px;
}
+ .realtimeMode {
+ display: inline-block;
+ width: var(--top-height);
+ margin-left: auto;
+
+ &.on {
+ color: var(--MI_THEME-accent);
+ }
+ }
+
.bottom {
position: sticky;
bottom: 0;
padding-top: 20px;
- background: var(--nav-bg-transparent);
- -webkit-backdrop-filter: var(--MI-blur, blur(8px));
- backdrop-filter: var(--MI-blur, blur(8px));
}
.post {
@@ -416,10 +522,6 @@ function menuEdit() {
padding-right: 8px;
}
- .middle {
- flex: 1;
- }
-
.divider {
margin: 16px 16px;
border-top: solid 0.5px var(--MI_THEME-divider);
@@ -520,9 +622,6 @@ function menuEdit() {
top: 0;
z-index: 1;
padding: 20px 0;
- background: var(--nav-bg-transparent);
- -webkit-backdrop-filter: var(--MI-blur, blur(8px));
- backdrop-filter: var(--MI-blur, blur(8px));
}
.instance {
@@ -551,9 +650,6 @@ function menuEdit() {
position: sticky;
bottom: 0;
padding-top: 20px;
- background: var(--nav-bg-transparent);
- -webkit-backdrop-filter: var(--MI-blur, blur(8px));
- backdrop-filter: var(--MI-blur, blur(8px));
}
.widget {
@@ -564,6 +660,18 @@ function menuEdit() {
text-align: center;
}
+ .realtimeMode {
+ display: block;
+ position: relative;
+ width: 100%;
+ height: 52px;
+ text-align: center;
+
+ &.on {
+ color: var(--MI_THEME-accent);
+ }
+ }
+
.post {
display: block;
position: relative;
@@ -637,10 +745,6 @@ function menuEdit() {
display: none;
}
- .middle {
- flex: 1;
- }
-
.divider {
margin: 8px auto;
width: calc(100% - 32px);
@@ -650,7 +754,7 @@ function menuEdit() {
.item {
display: block;
position: relative;
- padding: 18px 0;
+ padding: 16px 0;
width: 100%;
text-align: center;
diff --git a/packages/frontend/src/ui/_common_/stream-indicator.vue b/packages/frontend/src/ui/_common_/stream-indicator.vue
index 5f7600881f..35508b7ce6 100644
--- a/packages/frontend/src/ui/_common_/stream-indicator.vue
+++ b/packages/frontend/src/ui/_common_/stream-indicator.vue
@@ -20,6 +20,7 @@ import { i18n } from '@/i18n.js';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
import { prefer } from '@/preferences.js';
+import { store } from '@/store.js';
const zIndex = os.claimZIndex('high');
@@ -37,11 +38,13 @@ function reload() {
window.location.reload();
}
-useStream().on('_disconnected_', onDisconnected);
+if (store.s.realtimeMode) {
+ useStream().on('_disconnected_', onDisconnected);
-onUnmounted(() => {
- useStream().off('_disconnected_', onDisconnected);
-});
+ onUnmounted(() => {
+ useStream().off('_disconnected_', onDisconnected);
+ });
+}