feat: 未読の通知のみ表示する機能
This commit is contained in:
		
							parent
							
								
									27c056cbbf
								
							
						
					
					
						commit
						ec05c07321
					
				
					 5 changed files with 39 additions and 6 deletions
				
			
		|  | @ -14,7 +14,9 @@ | ||||||
| - アカウント登録にメールアドレスの設定を必須にするオプション | - アカウント登録にメールアドレスの設定を必須にするオプション | ||||||
| - クライアント: アニメーションを減らす設定をメニューのアニメーションにも適用するように | - クライアント: アニメーションを減らす設定をメニューのアニメーションにも適用するように | ||||||
| - クライアント: MFM関数構文のサジェストを実装 | - クライアント: MFM関数構文のサジェストを実装 | ||||||
|  | - クライアント: 未読の通知のみ表示する機能 | ||||||
| - ActivityPub: HTML -> MFMの変換を強化 | - ActivityPub: HTML -> MFMの変換を強化 | ||||||
|  | - API: i/notifications に unreadOnly オプションを追加 | ||||||
| - API: ap系のエンドポイントをログイン必須化+レートリミット追加 | - API: ap系のエンドポイントをログイン必須化+レートリミット追加 | ||||||
| - Misskeyのコマンドラインオプションを廃止 | - Misskeyのコマンドラインオプションを廃止 | ||||||
| 	- 代わりに環境変数で設定することができます | 	- 代わりに環境変数で設定することができます | ||||||
|  |  | ||||||
|  | @ -792,6 +792,7 @@ unresolved: "未解決" | ||||||
| itsOn: "オンになっています" | itsOn: "オンになっています" | ||||||
| itsOff: "オフになっています" | itsOff: "オフになっています" | ||||||
| emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする" | emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする" | ||||||
|  | unread: "未読" | ||||||
| 
 | 
 | ||||||
| _signup: | _signup: | ||||||
|   almostThere: "ほとんど完了です" |   almostThere: "ほとんど完了です" | ||||||
|  |  | ||||||
|  | @ -48,6 +48,11 @@ export default defineComponent({ | ||||||
| 			required: false, | 			required: false, | ||||||
| 			default: null, | 			default: null, | ||||||
| 		}, | 		}, | ||||||
|  | 		unreadOnly: { | ||||||
|  | 			type: Boolean, | ||||||
|  | 			required: false, | ||||||
|  | 			default: false, | ||||||
|  | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	data() { | 	data() { | ||||||
|  | @ -58,6 +63,7 @@ export default defineComponent({ | ||||||
| 				limit: 10, | 				limit: 10, | ||||||
| 				params: () => ({ | 				params: () => ({ | ||||||
| 					includeTypes: this.allIncludeTypes || undefined, | 					includeTypes: this.allIncludeTypes || undefined, | ||||||
|  | 					unreadOnly: this.unreadOnly, | ||||||
| 				}) | 				}) | ||||||
| 			}, | 			}, | ||||||
| 		}; | 		}; | ||||||
|  | @ -76,6 +82,11 @@ export default defineComponent({ | ||||||
| 			}, | 			}, | ||||||
| 			deep: true | 			deep: true | ||||||
| 		}, | 		}, | ||||||
|  | 		unreadOnly: { | ||||||
|  | 			handler() { | ||||||
|  | 				this.reload(); | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 		// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、 | 		// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、 | ||||||
| 		// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す | 		// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す | ||||||
| 		'$i.mutingNotificationTypes': { | 		'$i.mutingNotificationTypes': { | ||||||
|  |  | ||||||
|  | @ -2,13 +2,13 @@ | ||||||
| <div> | <div> | ||||||
| 	<MkHeader :info="header"/> | 	<MkHeader :info="header"/> | ||||||
| 	<div class="clupoqwt" v-size="{ min: [800] }"> | 	<div class="clupoqwt" v-size="{ min: [800] }"> | ||||||
| 		<XNotifications class="notifications" @before="before" @after="after" page/> | 		<XNotifications class="notifications" @before="before" @after="after" :unread-only="tab === 'unread'"/> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { computed, defineComponent } from 'vue'; | ||||||
| import Progress from '@client/scripts/loading'; | import Progress from '@client/scripts/loading'; | ||||||
| import XNotifications from '@client/components/notifications.vue'; | import XNotifications from '@client/components/notifications.vue'; | ||||||
| import * as os from '@client/os'; | import * as os from '@client/os'; | ||||||
|  | @ -26,7 +26,8 @@ export default defineComponent({ | ||||||
| 				icon: 'fas fa-bell', | 				icon: 'fas fa-bell', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
| 			}, | 			}, | ||||||
| 			header: { | 			tab: 'all', | ||||||
|  | 			header: computed(() => ({ | ||||||
| 				title: this.$ts.notifications, | 				title: this.$ts.notifications, | ||||||
| 				icon: 'fas fa-bell', | 				icon: 'fas fa-bell', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | @ -35,9 +36,18 @@ export default defineComponent({ | ||||||
| 					icon: 'fas fa-check', | 					icon: 'fas fa-check', | ||||||
| 					handler: () => { | 					handler: () => { | ||||||
| 						os.apiWithDialog('notifications/mark-all-as-read'); | 						os.apiWithDialog('notifications/mark-all-as-read'); | ||||||
| 					} | 					}, | ||||||
| 				}] | 				}], | ||||||
| 			}, | 				tabs: [{ | ||||||
|  | 					active: this.tab === 'all', | ||||||
|  | 					title: this.$ts.all, | ||||||
|  | 					onClick: () => { this.tab = 'all'; }, | ||||||
|  | 				}, { | ||||||
|  | 					active: this.tab === 'unread', | ||||||
|  | 					title: this.$ts.unread, | ||||||
|  | 					onClick: () => { this.tab = 'unread'; }, | ||||||
|  | 				},] | ||||||
|  | 			})), | ||||||
| 		}; | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,6 +33,11 @@ export const meta = { | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | 		unreadOnly: { | ||||||
|  | 			validator: $.optional.bool, | ||||||
|  | 			default: false | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		markAsRead: { | 		markAsRead: { | ||||||
| 			validator: $.optional.bool, | 			validator: $.optional.bool, | ||||||
| 			default: true | 			default: true | ||||||
|  | @ -105,6 +110,10 @@ export default define(meta, async (ps, user) => { | ||||||
| 		query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes }); | 		query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes }); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (ps.unreadOnly) { | ||||||
|  | 		query.andWhere(`notification.isRead = false`); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	const notifications = await query.take(ps.limit!).getMany(); | 	const notifications = await query.take(ps.limit!).getMany(); | ||||||
| 
 | 
 | ||||||
| 	// Mark all as read
 | 	// Mark all as read
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue