diff --git a/CHANGELOG_engawa.md b/CHANGELOG_engawa.md index e3f4dc2610..51cec6a22f 100644 --- a/CHANGELOG_engawa.md +++ b/CHANGELOG_engawa.md @@ -26,7 +26,7 @@ - 検索ウィジェットにオートフォーカスが当たらなくなりました ### Server -- +- 検索機能に新しいパラメータを追加( [1673beta/cherrypick#94](https://github.com/1673beta/cherrypick/issues/94) ) ### Misc diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 6b7c50ec2f..748dae1867 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -60,6 +60,8 @@ export class SearchService { channelId?: MiNote['channelId'] | null; host?: string | null; fileOption?: string | null; + excludeNsfw?: boolean; + excludeBot?: boolean; }, pagination: { untilId?: MiNote['id']; sinceId?: MiNote['id']; @@ -91,6 +93,23 @@ export class SearchService { } } + if (opts.fileOption) { + if (opts.fileOption === 'fileOnly') { + query.andWhere('note.fileIds != \'{}\' ') + } else if (opts.fileOption === 'noFile') { + query.andWhere('note.fileIds = \'{}\' ') + } + } + + if (opts.excludeNsfw) { + query.andWhere('note.cw IS NULL'); + query.andWhere('0 = (SELECT COUNT(*) FROM drive_file df WHERE df.id = ANY(note."fileIds") AND df."isSensitive" = TRUE )'); + } + + if (opts.excludeBot) { + query.andWhere(' (SELECT "isBot" FROM "user" WHERE id = note."userId") = FALSE '); + } + /** * if (this.config.pgroonga) { * query.andWhere('note.text &@~ :q', { q: `%${sqlLikeEscape(q)}%` }); diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index e724294288..e1d40d9233 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -41,7 +41,6 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - origin: { type: 'string', enum: ['local', 'remote', 'combined'], default: 'combined' }, offset: { type: 'integer', default: 0 }, host: { type: 'string', @@ -49,6 +48,9 @@ export const paramDef = { }, userId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, channelId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, + fileOption: { type: 'string', enum: ['combined', 'fileOnly', 'noFile'], default: 'combined' }, + excludeNsfw: { type: 'boolean', default: false }, + excludeBot: { type: 'boolean', default: false }, }, required: ['query'], } as const; @@ -72,7 +74,9 @@ export default class extends Endpoint { // eslint- userId: ps.userId, channelId: ps.channelId, host: ps.host, - origin: ps.origin, + fileOption: ps.fileOption, + excludeNsfw: ps.excludeNsfw, + excludeBot: ps.excludeBot, }, { untilId: ps.untilId, sinceId: ps.sinceId, diff --git a/packages/cherrypick-js/src/autogen/types.ts b/packages/cherrypick-js/src/autogen/types.ts index 2fa1db46f8..2d9b491def 100644 --- a/packages/cherrypick-js/src/autogen/types.ts +++ b/packages/cherrypick-js/src/autogen/types.ts @@ -23698,11 +23698,6 @@ export type operations = { untilId?: string; /** @default 10 */ limit?: number; - /** - * @default combined - * @enum {string} - */ - origin?: 'local' | 'remote' | 'combined'; /** @default 0 */ offset?: number; /** @description The local host is represented with `.`. */ @@ -23717,6 +23712,15 @@ export type operations = { * @default null */ channelId?: string | null; + /** + * @default combined + * @enum {string} + */ + fileOption?: 'combined' | 'fileOnly' | 'noFile'; + /** @default false */ + excludeNsfw?: boolean; + /** @default false */ + excludeBot?: boolean; }; }; }; diff --git a/packages/frontend/src/pages/search.note.vue b/packages/frontend/src/pages/search.note.vue index e197da18e1..d60bcaa74c 100644 --- a/packages/frontend/src/pages/search.note.vue +++ b/packages/frontend/src/pages/search.note.vue @@ -36,6 +36,19 @@ SPDX-License-Identifier: AGPL-3.0-only + + + +
+ {{ i18n.ts._advancedSearch._searchOption.toggleCW }} + {{ i18n.ts.antennaExcludeBots }} + + + + + +
+
@@ -66,6 +79,7 @@ import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkRadios from '@/components/MkRadios.vue'; import { $i } from '@/account.js'; import { instance } from '@/instance.js'; +import MkSwitch from '@/components/MkSwitch.vue'; const props = withDefaults(defineProps<{ query?: string; @@ -85,6 +99,9 @@ const searchQuery = ref(toRef(props, 'query').value); const notePagination = ref(); const user = ref(null); const hostInput = ref(toRef(props, 'host').value); +const excludeNsfw = ref(false); +const excludeBot = ref(false); +const fileOption = ref('combined'); const noteSearchableScope = instance.noteSearchableScope ?? 'local'; @@ -198,6 +215,9 @@ async function search() { query: searchQuery.value, userId: user.value ? user.value.id : null, ...(searchHost.value ? { host: searchHost.value } : {}), + excludeNsfw: excludeNsfw.value, + excludeBot: excludeBot.value, + fileOption: fileOption.value, }, };