From 253c0c42e2871d3fe4ac959508bed5d93cd01b38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?=
 <46447427+samunohito@users.noreply.github.com>
Date: Fri, 10 Nov 2023 17:49:09 +0900
Subject: [PATCH] =?UTF-8?q?=E3=83=87=E3=83=83=E3=82=AD=E3=81=AE=E3=82=AB?=
 =?UTF-8?q?=E3=83=A9=E3=83=A0=E3=81=8B=E3=82=89=E3=83=AA=E3=83=AD=E3=83=BC?=
 =?UTF-8?q?=E3=83=89=E3=81=A7=E3=81=8D=E3=82=8B=E6=A9=9F=E8=83=BD=E3=82=92?=
 =?UTF-8?q?=E8=BF=BD=E5=8A=A0=20(#12274)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* デッキのカラムからリロードできる機能を追加

* tweak

---------

Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
---
 .../frontend/src/components/MkNotifications.vue  |  4 ++++
 packages/frontend/src/ui/deck/antenna-column.vue |  2 +-
 packages/frontend/src/ui/deck/channel-column.vue |  2 +-
 packages/frontend/src/ui/deck/column.vue         | 13 +++++++++++++
 packages/frontend/src/ui/deck/direct-column.vue  | 16 ++++++++++++++--
 packages/frontend/src/ui/deck/list-column.vue    |  2 +-
 .../frontend/src/ui/deck/mentions-column.vue     | 16 ++++++++++++++--
 .../src/ui/deck/notifications-column.vue         |  6 ++++--
 .../src/ui/deck/role-timeline-column.vue         |  2 +-
 packages/frontend/src/ui/deck/tl-column.vue      |  3 ++-
 10 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue
index 77e66f0165..0c817bd64c 100644
--- a/packages/frontend/src/components/MkNotifications.vue
+++ b/packages/frontend/src/components/MkNotifications.vue
@@ -96,6 +96,10 @@ onUnmounted(() => {
 onDeactivated(() => {
 	if (connection) connection.dispose();
 });
+
+defineExpose({
+	reload,
+});
 </script>
 
 <style lang="scss" module>
diff --git a/packages/frontend/src/ui/deck/antenna-column.vue b/packages/frontend/src/ui/deck/antenna-column.vue
index a93a14648c..1f4600d949 100644
--- a/packages/frontend/src/ui/deck/antenna-column.vue
+++ b/packages/frontend/src/ui/deck/antenna-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :menu="menu" :column="column" :isStacked="isStacked">
+<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="() => timeline.reloadTimeline()">
 	<template #header>
 		<i class="ti ti-antenna"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
diff --git a/packages/frontend/src/ui/deck/channel-column.vue b/packages/frontend/src/ui/deck/channel-column.vue
index 4b982073ad..d2d279e5d7 100644
--- a/packages/frontend/src/ui/deck/channel-column.vue
+++ b/packages/frontend/src/ui/deck/channel-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :menu="menu" :column="column" :isStacked="isStacked">
+<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="() => timeline.reloadTimeline()">
 	<template #header>
 		<i class="ti ti-device-tv"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
diff --git a/packages/frontend/src/ui/deck/column.vue b/packages/frontend/src/ui/deck/column.vue
index 269b9d57d5..1a6b833b45 100644
--- a/packages/frontend/src/ui/deck/column.vue
+++ b/packages/frontend/src/ui/deck/column.vue
@@ -57,6 +57,7 @@ const props = withDefaults(defineProps<{
 	isStacked?: boolean;
 	naked?: boolean;
 	menu?: MenuItem[];
+	refresher?: () => Promise<void>;
 }>(), {
 	isStacked: false,
 	naked: false,
@@ -183,6 +184,18 @@ function getMenu() {
 		items = props.menu.concat(items);
 	}
 
+	if (props.refresher) {
+		items = [{
+			icon: 'ti ti-refresh',
+			text: i18n.ts.reload,
+			action: () => {
+				if (props.refresher) {
+					props.refresher();
+				}
+			},
+		}, ...items];
+	}
+
 	return items;
 }
 
diff --git a/packages/frontend/src/ui/deck/direct-column.vue b/packages/frontend/src/ui/deck/direct-column.vue
index 940d2d7609..d8389949dd 100644
--- a/packages/frontend/src/ui/deck/direct-column.vue
+++ b/packages/frontend/src/ui/deck/direct-column.vue
@@ -4,10 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :column="column" :isStacked="isStacked">
+<XColumn :column="column" :isStacked="isStacked" :refresher="() => reloadTimeline()">
 	<template #header><i class="ti ti-mail" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
-	<MkNotes :pagination="pagination"/>
+	<MkNotes ref="tlComponent" :pagination="pagination"/>
 </XColumn>
 </template>
 
@@ -16,6 +16,7 @@ import { } from 'vue';
 import XColumn from './column.vue';
 import { Column } from './deck-store.js';
 import MkNotes from '@/components/MkNotes.vue';
+import { reloadStream } from '@/stream.js';
 
 defineProps<{
 	column: Column;
@@ -29,4 +30,15 @@ const pagination = {
 		visibility: 'specified',
 	},
 };
+
+const tlComponent: InstanceType<typeof MkNotes> = $ref();
+
+function reloadTimeline() {
+	return new Promise<void>((res) => {
+		tlComponent.pagingComponent?.reload().then(() => {
+			reloadStream();
+			res();
+		});
+	});
+}
 </script>
diff --git a/packages/frontend/src/ui/deck/list-column.vue b/packages/frontend/src/ui/deck/list-column.vue
index 14bc6917a3..40e4dcee7e 100644
--- a/packages/frontend/src/ui/deck/list-column.vue
+++ b/packages/frontend/src/ui/deck/list-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :menu="menu" :column="column" :isStacked="isStacked">
+<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="() => timeline.reloadTimeline()">
 	<template #header>
 		<i class="ti ti-list"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
diff --git a/packages/frontend/src/ui/deck/mentions-column.vue b/packages/frontend/src/ui/deck/mentions-column.vue
index 381a9d02f2..7965444538 100644
--- a/packages/frontend/src/ui/deck/mentions-column.vue
+++ b/packages/frontend/src/ui/deck/mentions-column.vue
@@ -4,10 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :column="column" :isStacked="isStacked">
+<XColumn :column="column" :isStacked="isStacked" :refresher="() => reloadTimeline()">
 	<template #header><i class="ti ti-at" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
-	<MkNotes :pagination="pagination"/>
+	<MkNotes ref="tlComponent" :pagination="pagination"/>
 </XColumn>
 </template>
 
@@ -16,12 +16,24 @@ import { } from 'vue';
 import XColumn from './column.vue';
 import { Column } from './deck-store.js';
 import MkNotes from '@/components/MkNotes.vue';
+import { reloadStream } from '@/stream.js';
 
 defineProps<{
 	column: Column;
 	isStacked: boolean;
 }>();
 
+const tlComponent: InstanceType<typeof MkNotes> = $ref();
+
+function reloadTimeline() {
+	return new Promise<void>((res) => {
+		tlComponent.pagingComponent?.reload().then(() => {
+			reloadStream();
+			res();
+		});
+	});
+}
+
 const pagination = {
 	endpoint: 'notes/mentions' as const,
 	limit: 10,
diff --git a/packages/frontend/src/ui/deck/notifications-column.vue b/packages/frontend/src/ui/deck/notifications-column.vue
index b6bbf1fb55..770e8ea820 100644
--- a/packages/frontend/src/ui/deck/notifications-column.vue
+++ b/packages/frontend/src/ui/deck/notifications-column.vue
@@ -4,10 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :column="column" :isStacked="isStacked" :menu="menu">
+<XColumn :column="column" :isStacked="isStacked" :menu="menu" :refresher="() => notificationsComponent.reload()">
 	<template #header><i class="ti ti-bell" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
-	<XNotifications :excludeTypes="props.column.excludeTypes"/>
+	<XNotifications ref="notificationsComponent" :excludeTypes="props.column.excludeTypes"/>
 </XColumn>
 </template>
 
@@ -24,6 +24,8 @@ const props = defineProps<{
 	isStacked: boolean;
 }>();
 
+let notificationsComponent = $shallowRef<InstanceType<typeof XNotifications>>();
+
 function func() {
 	os.popup(defineAsyncComponent(() => import('@/components/MkNotificationSelectWindow.vue')), {
 		excludeTypes: props.column.excludeTypes,
diff --git a/packages/frontend/src/ui/deck/role-timeline-column.vue b/packages/frontend/src/ui/deck/role-timeline-column.vue
index e986b1f7d3..86d8878820 100644
--- a/packages/frontend/src/ui/deck/role-timeline-column.vue
+++ b/packages/frontend/src/ui/deck/role-timeline-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :menu="menu" :column="column" :isStacked="isStacked">
+<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="() => timeline.reloadTimeline()">
 	<template #header>
 		<i class="ti ti-badge"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
diff --git a/packages/frontend/src/ui/deck/tl-column.vue b/packages/frontend/src/ui/deck/tl-column.vue
index c5629f69a4..9f24ea31ed 100644
--- a/packages/frontend/src/ui/deck/tl-column.vue
+++ b/packages/frontend/src/ui/deck/tl-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<XColumn :menu="menu" :column="column" :isStacked="isStacked">
+<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="() => timeline.reloadTimeline()">
 	<template #header>
 		<i v-if="column.tl === 'home'" class="ti ti-home"></i>
 		<i v-else-if="column.tl === 'local'" class="ti ti-planet"></i>
@@ -48,6 +48,7 @@ const props = defineProps<{
 }>();
 
 let disabled = $ref(false);
+let timeline = $shallowRef<InstanceType<typeof MkTimeline>>();
 
 const isLocalTimelineAvailable = (($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable));
 const isGlobalTimelineAvailable = (($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable));