Skip to content

Commit

Permalink
feat: 新しい検索オプション (#131)
Browse files Browse the repository at this point in the history
* feat: excludeNsfwを復活させる

* feat: 検索からBotを除外するオプション

* feat: ファイルの有無をフィルターする機能

* update changelog

---------

Co-authored-by: Esurio <esurio@esurio1673.net>
  • Loading branch information
1673beta and Esurio authored Aug 10, 2024
1 parent 86e6280 commit 340a38d
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG_engawa.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
- 検索ウィジェットにオートフォーカスが当たらなくなりました

### Server
-
- 検索機能に新しいパラメータを追加( [1673beta/cherrypick#94](https://github.com/1673beta/cherrypick/issues/94) )

### Misc

Expand Down
19 changes: 19 additions & 0 deletions packages/backend/src/core/SearchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'];
Expand Down Expand Up @@ -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)}%` });
Expand Down
8 changes: 6 additions & 2 deletions packages/backend/src/server/api/endpoints/notes/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ 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',
description: 'The local host is represented with `.`.',
},
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;
Expand All @@ -72,7 +74,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // 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,
Expand Down
14 changes: 9 additions & 5 deletions packages/cherrypick-js/src/autogen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 `.`. */
Expand All @@ -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;
};
};
};
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/src/pages/search.note.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</MkFolder>

<MkFolder>
<template #label>{{ i18n.ts.options }}</template>
<div class="_gaps">
<MkSwitch v-model="excludeNsfw">{{ i18n.ts._advancedSearch._searchOption.toggleCW }}</MkSwitch>
<MkSwitch v-model="excludeBot">{{ i18n.ts.antennaExcludeBots }}</MkSwitch>
<MkRadios v-model="fileOption">
<option value="combined">{{ i18n.ts._advancedSearch._fileOption.combined }}</option>
<option value="fileOnly">{{ i18n.ts._advancedSearch._fileOption.fileAttachedOnly }}</option>
<option value="noFile">{{ i18n.ts._advancedSearch._fileOption.noFile }}</option>
</MkRadios>
</div>
</MkFolder>
</div>
</MkFoldableSection>
<div>
Expand Down Expand Up @@ -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;
Expand All @@ -85,6 +99,9 @@ const searchQuery = ref(toRef(props, 'query').value);
const notePagination = ref<Paging>();
const user = ref<UserDetailed | null>(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';
Expand Down Expand Up @@ -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,
},
};
Expand Down

0 comments on commit 340a38d

Please sign in to comment.