Resolve #6043
This commit is contained in:
		| @@ -2,6 +2,9 @@ ChangeLog | |||||||
| ========= | ========= | ||||||
|  |  | ||||||
| ------------------- | ------------------- | ||||||
|  | ### ✨Improvements | ||||||
|  | * アンテナで除外キーワードを設定できるように | ||||||
|  |  | ||||||
| ### 🐛Fixes | ### 🐛Fixes | ||||||
| * ハッシュタグをもっと見るできないのを修正 | * ハッシュタグをもっと見るできないのを修正 | ||||||
| * 無効になっているタイムラインでも使用できるかのように表示される問題を修正 | * 無効になっているタイムラインでも使用できるかのように表示される問題を修正 | ||||||
|   | |||||||
| @@ -286,6 +286,7 @@ manageAntennas: "アンテナの管理" | |||||||
| name: "名前" | name: "名前" | ||||||
| antennaSource: "受信ソース" | antennaSource: "受信ソース" | ||||||
| antennaKeywords: "受信キーワード" | antennaKeywords: "受信キーワード" | ||||||
|  | antennaExcludeKeywords: "除外キーワード" | ||||||
| antennaKeywordsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります" | antennaKeywordsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります" | ||||||
| notifyAntenna: "新しいノートを通知する" | notifyAntenna: "新しいノートを通知する" | ||||||
| withFileAntenna: "ファイルが添付されたノートのみ" | withFileAntenna: "ファイルが添付されたノートのみ" | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								migration/1582210532752-antenna-exclude.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								migration/1582210532752-antenna-exclude.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | import {MigrationInterface, QueryRunner} from "typeorm"; | ||||||
|  |  | ||||||
|  | export class antennaExclude1582210532752 implements MigrationInterface { | ||||||
|  |     name = 'antennaExclude1582210532752' | ||||||
|  |  | ||||||
|  |     public async up(queryRunner: QueryRunner): Promise<any> { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "antenna" ADD "excludeKeywords" jsonb NOT NULL DEFAULT '[]'`, undefined); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async down(queryRunner: QueryRunner): Promise<any> { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "excludeKeywords"`, undefined); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -30,6 +30,10 @@ | |||||||
| 			<span>{{ $t('antennaKeywords') }}</span> | 			<span>{{ $t('antennaKeywords') }}</span> | ||||||
| 			<template #desc>{{ $t('antennaKeywordsDescription') }}</template> | 			<template #desc>{{ $t('antennaKeywordsDescription') }}</template> | ||||||
| 		</mk-textarea> | 		</mk-textarea> | ||||||
|  | 		<mk-textarea v-model="excludeKeywords"> | ||||||
|  | 			<span>{{ $t('antennaExcludeKeywords') }}</span> | ||||||
|  | 			<template #desc>{{ $t('antennaKeywordsDescription') }}</template> | ||||||
|  | 		</mk-textarea> | ||||||
| 		<mk-switch v-model="caseSensitive">{{ $t('caseSensitive') }}</mk-switch> | 		<mk-switch v-model="caseSensitive">{{ $t('caseSensitive') }}</mk-switch> | ||||||
| 		<mk-switch v-model="withFile">{{ $t('withFileAntenna') }}</mk-switch> | 		<mk-switch v-model="withFile">{{ $t('withFileAntenna') }}</mk-switch> | ||||||
| 		<mk-switch v-model="notify">{{ $t('notifyAntenna') }}</mk-switch> | 		<mk-switch v-model="notify">{{ $t('notifyAntenna') }}</mk-switch> | ||||||
| @@ -75,6 +79,7 @@ export default Vue.extend({ | |||||||
| 			userGroupId: null, | 			userGroupId: null, | ||||||
| 			users: '', | 			users: '', | ||||||
| 			keywords: '', | 			keywords: '', | ||||||
|  | 			excludeKeywords: '', | ||||||
| 			caseSensitive: false, | 			caseSensitive: false, | ||||||
| 			withReplies: false, | 			withReplies: false, | ||||||
| 			withFile: false, | 			withFile: false, | ||||||
| @@ -107,6 +112,7 @@ export default Vue.extend({ | |||||||
| 		this.userGroupId = this.antenna.userGroupId; | 		this.userGroupId = this.antenna.userGroupId; | ||||||
| 		this.users = this.antenna.users.join('\n'); | 		this.users = this.antenna.users.join('\n'); | ||||||
| 		this.keywords = this.antenna.keywords.map(x => x.join(' ')).join('\n'); | 		this.keywords = this.antenna.keywords.map(x => x.join(' ')).join('\n'); | ||||||
|  | 		this.excludeKeywords = this.antenna.excludeKeywords.map(x => x.join(' ')).join('\n'); | ||||||
| 		this.caseSensitive = this.antenna.caseSensitive; | 		this.caseSensitive = this.antenna.caseSensitive; | ||||||
| 		this.withReplies = this.antenna.withReplies; | 		this.withReplies = this.antenna.withReplies; | ||||||
| 		this.withFile = this.antenna.withFile; | 		this.withFile = this.antenna.withFile; | ||||||
| @@ -126,7 +132,8 @@ export default Vue.extend({ | |||||||
| 					notify: this.notify, | 					notify: this.notify, | ||||||
| 					caseSensitive: this.caseSensitive, | 					caseSensitive: this.caseSensitive, | ||||||
| 					users: this.users.trim().split('\n').map(x => x.trim()), | 					users: this.users.trim().split('\n').map(x => x.trim()), | ||||||
| 					keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')) | 					keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')), | ||||||
|  | 					excludeKeywords: this.excludeKeywords.trim().split('\n').map(x => x.trim().split(' ')), | ||||||
| 				}); | 				}); | ||||||
| 				this.$emit('created'); | 				this.$emit('created'); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -141,7 +148,8 @@ export default Vue.extend({ | |||||||
| 					notify: this.notify, | 					notify: this.notify, | ||||||
| 					caseSensitive: this.caseSensitive, | 					caseSensitive: this.caseSensitive, | ||||||
| 					users: this.users.trim().split('\n').map(x => x.trim()), | 					users: this.users.trim().split('\n').map(x => x.trim()), | ||||||
| 					keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')) | 					keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')), | ||||||
|  | 					excludeKeywords: this.excludeKeywords.trim().split('\n').map(x => x.trim().split(' ')), | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ export default Vue.extend({ | |||||||
| 				userGroupId: null, | 				userGroupId: null, | ||||||
| 				users: [], | 				users: [], | ||||||
| 				keywords: [], | 				keywords: [], | ||||||
|  | 				excludeKeywords: [], | ||||||
| 				withReplies: false, | 				withReplies: false, | ||||||
| 				caseSensitive: false, | 				caseSensitive: false, | ||||||
| 				withFile: false, | 				withFile: false, | ||||||
|   | |||||||
| @@ -52,6 +52,19 @@ export async function checkHitAntenna(antenna: Antenna, note: Note, noteUser: Us | |||||||
| 		if (!matched) return false; | 		if (!matched) return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (antenna.excludeKeywords.length > 0) { | ||||||
|  | 		if (note.text == null) return false; | ||||||
|  |  | ||||||
|  | 		const matched = antenna.excludeKeywords.some(keywords => | ||||||
|  | 			keywords.every(keyword => | ||||||
|  | 				antenna.caseSensitive | ||||||
|  | 					? note.text!.includes(keyword) | ||||||
|  | 					: note.text!.toLowerCase().includes(keyword.toLowerCase()) | ||||||
|  | 			)); | ||||||
|  | 		 | ||||||
|  | 		if (matched) return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (antenna.withFile) { | 	if (antenna.withFile) { | ||||||
| 		if (note.fileIds.length === 0) return false; | 		if (note.fileIds.length === 0) return false; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -71,6 +71,11 @@ export class Antenna { | |||||||
| 	}) | 	}) | ||||||
| 	public keywords: string[][]; | 	public keywords: string[][]; | ||||||
|  |  | ||||||
|  | 	@Column('jsonb', { | ||||||
|  | 		default: [] | ||||||
|  | 	}) | ||||||
|  | 	public excludeKeywords: string[][]; | ||||||
|  |  | ||||||
| 	@Column('boolean', { | 	@Column('boolean', { | ||||||
| 		default: false | 		default: false | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ export class AntennaRepository extends Repository<Antenna> { | |||||||
| 			createdAt: antenna.createdAt.toISOString(), | 			createdAt: antenna.createdAt.toISOString(), | ||||||
| 			name: antenna.name, | 			name: antenna.name, | ||||||
| 			keywords: antenna.keywords, | 			keywords: antenna.keywords, | ||||||
|  | 			excludeKeywords: antenna.excludeKeywords, | ||||||
| 			src: antenna.src, | 			src: antenna.src, | ||||||
| 			userListId: antenna.userListId, | 			userListId: antenna.userListId, | ||||||
| 			userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null, | 			userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null, | ||||||
|   | |||||||
| @@ -33,6 +33,10 @@ export const meta = { | |||||||
| 			validator: $.arr($.arr($.str)) | 			validator: $.arr($.arr($.str)) | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | 		excludeKeywords: { | ||||||
|  | 			validator: $.arr($.arr($.str)) | ||||||
|  | 		}, | ||||||
|  |  | ||||||
| 		users: { | 		users: { | ||||||
| 			validator: $.arr($.str) | 			validator: $.arr($.str) | ||||||
| 		}, | 		}, | ||||||
| @@ -102,6 +106,7 @@ export default define(meta, async (ps, user) => { | |||||||
| 		userListId: userList ? userList.id : null, | 		userListId: userList ? userList.id : null, | ||||||
| 		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, | 		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, | ||||||
| 		keywords: ps.keywords, | 		keywords: ps.keywords, | ||||||
|  | 		excludeKeywords: ps.excludeKeywords, | ||||||
| 		users: ps.users, | 		users: ps.users, | ||||||
| 		caseSensitive: ps.caseSensitive, | 		caseSensitive: ps.caseSensitive, | ||||||
| 		withReplies: ps.withReplies, | 		withReplies: ps.withReplies, | ||||||
|   | |||||||
| @@ -36,6 +36,10 @@ export const meta = { | |||||||
| 			validator: $.arr($.arr($.str)) | 			validator: $.arr($.arr($.str)) | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | 		excludeKeywords: { | ||||||
|  | 			validator: $.arr($.arr($.str)) | ||||||
|  | 		}, | ||||||
|  |  | ||||||
| 		users: { | 		users: { | ||||||
| 			validator: $.arr($.str) | 			validator: $.arr($.str) | ||||||
| 		}, | 		}, | ||||||
| @@ -118,6 +122,7 @@ export default define(meta, async (ps, user) => { | |||||||
| 		userListId: userList ? userList.id : null, | 		userListId: userList ? userList.id : null, | ||||||
| 		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, | 		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, | ||||||
| 		keywords: ps.keywords, | 		keywords: ps.keywords, | ||||||
|  | 		excludeKeywords: ps.excludeKeywords, | ||||||
| 		users: ps.users, | 		users: ps.users, | ||||||
| 		caseSensitive: ps.caseSensitive, | 		caseSensitive: ps.caseSensitive, | ||||||
| 		withReplies: ps.withReplies, | 		withReplies: ps.withReplies, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo