From 4277e5343349c6000e626c490578d4e9bef71404 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 28 Jul 2019 04:44:09 +0900
Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E3=81=AE=E3=83=95=E3=82=A3?=
 =?UTF-8?q?=E3=83=AB=E3=82=BF=20(#5224)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* :v:

* Deck
---
 locales/ja-JP.yml                             | 11 ++++++
 .../app/common/views/components/dialog.vue    |  2 +-
 .../views/deck/deck.notifications-column.vue  | 39 ++++++++++++++++++-
 .../common/views/deck/deck.notifications.vue  | 16 ++++++++
 .../views/components/notifications.vue        | 16 ++++++++
 .../desktop/views/widgets/notifications.vue   | 25 +++++++++---
 6 files changed, 101 insertions(+), 8 deletions(-)

diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index b6bbb7e963..437a0b115a 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -37,6 +37,17 @@ common:
   reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?"
   fetching-as-ap-object: "連合に照会中"
   unfollow-confirm: "{name}さんをフォロー解除しますか?"
+  notification-type: "通知の種類"
+  notification-types:
+    all: "すべて"
+    pollVote: "投票"
+    follow: "フォロー"
+    receiveFollowRequest: "フォローリクエスト"
+    reply: "返信"
+    quote: "引用"
+    renote: "Renote"
+    mention: "言及"
+    reaction: "リアクション"
 
   got-it: "わかった"
   customization-tips:
diff --git a/src/client/app/common/views/components/dialog.vue b/src/client/app/common/views/components/dialog.vue
index ed94fe5f35..d5906eb4c4 100644
--- a/src/client/app/common/views/components/dialog.vue
+++ b/src/client/app/common/views/components/dialog.vue
@@ -98,7 +98,7 @@ export default Vue.extend({
 		return {
 			inputValue: this.input && this.input.default ? this.input.default : null,
 			userInputValue: null,
-			selectedValue: this.select ? this.select.items ? this.select.items[0].value : this.select.groupedItems[0].items[0].value : null,
+			selectedValue: this.select ? this.select.default ? this.select.default : this.select.items ? this.select.items[0].value : this.select.groupedItems[0].items[0].value : null,
 			canOk: true,
 			faTimesCircle, faQuestionCircle
 		};
diff --git a/src/client/app/common/views/deck/deck.notifications-column.vue b/src/client/app/common/views/deck/deck.notifications-column.vue
index c81c8b7733..b4361b054a 100644
--- a/src/client/app/common/views/deck/deck.notifications-column.vue
+++ b/src/client/app/common/views/deck/deck.notifications-column.vue
@@ -1,8 +1,8 @@
 <template>
-<x-column :name="name" :column="column" :is-stacked="isStacked">
+<x-column :name="name" :column="column" :is-stacked="isStacked" :menu="menu">
 	<template #header><fa :icon="['far', 'bell']"/>{{ name }}</template>
 
-	<x-notifications/>
+	<x-notifications :type="column.notificationType === 'all' ? null : column.notificationType"/>
 </x-column>
 </template>
 
@@ -30,11 +30,46 @@ export default Vue.extend({
 		}
 	},
 
+	data() {
+		return {
+			menu: null,
+		}
+	},
+
 	computed: {
 		name(): string {
 			if (this.column.name) return this.column.name;
 			return this.$t('@deck.notifications');
 		}
 	},
+
+	created() {
+		if (this.column.notificationType == null) {
+			this.column.notificationType = 'all';
+			this.$store.commit('updateDeckColumn', this.column);
+		}
+
+		this.menu = [{
+			icon: 'cog',
+			text: this.$t('@.notification-type'),
+			action: () => {
+				this.$root.dialog({
+					title: this.$t('@.notification-type'),
+					type: null,
+					select: {
+						items: ['all', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest'].map(x => ({
+							value: x, text: this.$t('@.notification-types.' + x)
+						}))
+						default: this.column.notificationType,
+					},
+					showCancelButton: true
+				}).then(({ canceled, result: type }) => {
+					if (canceled) return;
+					this.column.notificationType = type;
+					this.$store.commit('updateDeckColumn', this.column);
+				});
+			}
+		}];
+	},
 });
 </script>
diff --git a/src/client/app/common/views/deck/deck.notifications.vue b/src/client/app/common/views/deck/deck.notifications.vue
index e01d0023f6..aed2af64e9 100644
--- a/src/client/app/common/views/deck/deck.notifications.vue
+++ b/src/client/app/common/views/deck/deck.notifications.vue
@@ -47,12 +47,22 @@ export default Vue.extend({
 		}),
 	],
 
+	props: {
+		type: {
+			type: String,
+			required: false
+		}
+	},
+
 	data() {
 		return {
 			connection: null,
 			pagination: {
 				endpoint: 'i/notifications',
 				limit: 20,
+				params: () => ({
+					includeTypes: this.type ? [this.type] : undefined
+				})
 			}
 		};
 	},
@@ -69,6 +79,12 @@ export default Vue.extend({
 		}
 	},
 
+	watch: {
+		type() {
+			this.reload();
+		}
+	},
+
 	mounted() {
 		this.connection = this.$root.stream.useSharedConnection('main');
 		this.connection.on('notification', this.onNotification);
diff --git a/src/client/app/desktop/views/components/notifications.vue b/src/client/app/desktop/views/components/notifications.vue
index b25f122e0e..0238587034 100644
--- a/src/client/app/desktop/views/components/notifications.vue
+++ b/src/client/app/desktop/views/components/notifications.vue
@@ -153,6 +153,13 @@ export default Vue.extend({
 		paging({}),
 	],
 
+	props: {
+		type: {
+			type: String,
+			required: false
+		}
+	},
+
 	data() {
 		return {
 			connection: null,
@@ -160,6 +167,9 @@ export default Vue.extend({
 			pagination: {
 				endpoint: 'i/notifications',
 				limit: 10,
+				params: () => ({
+					includeTypes: this.type ? [this.type] : undefined
+				})
 			}
 		};
 	},
@@ -176,6 +186,12 @@ export default Vue.extend({
 		}
 	},
 
+	watch: {
+		type() {
+			this.reload();
+		}
+	},
+
 	mounted() {
 		this.connection = this.$root.stream.useSharedConnection('main');
 		this.connection.on('notification', this.onNotification);
diff --git a/src/client/app/desktop/views/widgets/notifications.vue b/src/client/app/desktop/views/widgets/notifications.vue
index 2eaa6a2fef..5a84f7b371 100644
--- a/src/client/app/desktop/views/widgets/notifications.vue
+++ b/src/client/app/desktop/views/widgets/notifications.vue
@@ -1,10 +1,10 @@
 <template>
 <div class="mkw-notifications">
 	<ui-container :show-header="!props.compact">
-		<template #header><fa :icon="['far', 'bell']"/>{{ $t('title') }}</template>
-		<!-- <button #func :title="$t('title')" @click="settings"><fa icon="cog"/></button> -->
+		<template #header><fa :icon="['far', 'bell']"/>{{ props.type === 'all' ? $t('title') : $t('@.notification-types.' + props.type) }}</template>
+		<template #func><button :title="$t('@.notification-type')" @click="settings"><fa icon="cog"/></button></template>
 
-		<mk-notifications :class="$style.notifications"/>
+		<mk-notifications :class="$style.notifications" :type="props.type === 'all' ? null : props.type"/>
 	</ui-container>
 </div>
 </template>
@@ -16,13 +16,28 @@ import i18n from '../../../i18n';
 export default define({
 	name: 'notifications',
 	props: () => ({
-		compact: false
+		compact: false,
+		type: 'all'
 	})
 }).extend({
 	i18n: i18n('desktop/views/widgets/notifications.vue'),
 	methods: {
 		settings() {
-			alert('not implemented yet');
+			this.$root.dialog({
+				title: this.$t('@.notification-type'),
+				type: null,
+				select: {
+					items: ['all', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest'].map(x => ({
+						value: x, text: this.$t('@.notification-types.' + x)
+					}))
+					default: this.props.type,
+				},
+				showCancelButton: true
+			}).then(({ canceled, result: type }) => {
+				if (canceled) return;
+				this.props.type = type;
+				this.save();
+			});
 		},
 		func() {
 			this.props.compact = !this.props.compact;