diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2023-02-22 14:47:51 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-22 14:47:51 +0900 |
| commit | b9ee14fe5b185f3533326a15f05056cc8bd685ce (patch) | |
| tree | 986d374413d3915e49ab951af249a29f8c6e955d | |
| parent | Update CHANGELOG.md (diff) | |
| download | misskey-b9ee14fe5b185f3533326a15f05056cc8bd685ce.tar.gz misskey-b9ee14fe5b185f3533326a15f05056cc8bd685ce.tar.bz2 misskey-b9ee14fe5b185f3533326a15f05056cc8bd685ce.zip | |
fix: MkUserSelectDialog/search-by-username-and-hostでローカルユーザーを絞って検索できない問題を修正 (#9943)
* fix: MkUserSelectDialog/search-by-username-and-hostでローカルユーザーを絞って検索できない問題を修正
Fix #9627
* update CHANGELOG.md
* clean up
* search-by-username-and-host大改造
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts | 107 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkInput.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkUserSelectDialog.vue | 5 |
4 files changed, 59 insertions, 56 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f1b865260..aa3a9692e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ You should also include the user name that made the change. - enhance(client): MFMのx3, x4が含まれていたらノートをたたむように ### Bugfixes +- ユーザー検索ダイアログでローカルユーザーを絞って検索できない問題を修正 - fix(client): MkHeader及びデッキのカラムでチャンネル一覧を選択したとき、最大5個までしか表示されない - 管理画面の広告を10個以上見えるように diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 8b22f913d2..34827547b0 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -1,6 +1,7 @@ import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; +import type { Config } from '@/config.js'; import type { User } from '@/models/entities/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -53,6 +54,9 @@ export const paramDef = { @Injectable() export default class extends Endpoint<typeof meta, typeof paramDef> { constructor( + @Inject(DI.config) + private config: Config, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -62,79 +66,76 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private userEntityService: UserEntityService, ) { super(meta, paramDef, async (ps, me) => { - const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日 - - if (ps.host) { - const q = this.usersRepository.createQueryBuilder('user') - .where('user.isSuspended = FALSE') - .andWhere('user.host LIKE :host', { host: sqlLikeEscape(ps.host.toLowerCase()) + '%' }); - + const setUsernameAndHostQuery = (query = this.usersRepository.createQueryBuilder('user')) => { if (ps.username) { - q.andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' }); + query.andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' }) } - q.andWhere('user.updatedAt IS NOT NULL'); - q.orderBy('user.updatedAt', 'DESC'); + if (ps.host) { + if (ps.host === this.config.hostname || ps.host === '.') { + query.andWhere('user.host IS NULL'); + } else { + query.andWhere('user.host LIKE :host', { + host: sqlLikeEscape(ps.host.toLowerCase()) + '%' + }); + } + } - const users = await q.take(ps.limit).getMany(); + return query; + }; - return await this.userEntityService.packMany(users, me, { detail: ps.detail }); - } else if (ps.username) { - let users: User[] = []; + const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日 - if (me) { - const followingQuery = this.followingsRepository.createQueryBuilder('following') - .select('following.followeeId') - .where('following.followerId = :followerId', { followerId: me.id }); + let users: User[] = []; - const query = this.usersRepository.createQueryBuilder('user') - .where(`user.id IN (${ followingQuery.getQuery() })`) - .andWhere('user.id != :meId', { meId: me.id }) - .andWhere('user.isSuspended = FALSE') - .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' }) - .andWhere(new Brackets(qb => { qb - .where('user.updatedAt IS NULL') - .orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold }); - })); + if (me) { + const followingQuery = this.followingsRepository.createQueryBuilder('following') + .select('following.followeeId') + .where('following.followerId = :followerId', { followerId: me.id }); - query.setParameters(followingQuery.getParameters()); + const query = setUsernameAndHostQuery() + .andWhere(`user.id IN (${ followingQuery.getQuery() })`) + .andWhere('user.id != :meId', { meId: me.id }) + .andWhere('user.isSuspended = FALSE') + .andWhere(new Brackets(qb => { qb + .where('user.updatedAt IS NULL') + .orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold }); + })); - users = await query - .orderBy('user.usernameLower', 'ASC') - .take(ps.limit) - .getMany(); + query.setParameters(followingQuery.getParameters()); - if (users.length < ps.limit) { - const otherQuery = await this.usersRepository.createQueryBuilder('user') - .where(`user.id NOT IN (${ followingQuery.getQuery() })`) - .andWhere('user.id != :meId', { meId: me.id }) - .andWhere('user.isSuspended = FALSE') - .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' }) - .andWhere('user.updatedAt IS NOT NULL'); + users = await query + .orderBy('user.usernameLower', 'ASC') + .take(ps.limit) + .getMany(); - otherQuery.setParameters(followingQuery.getParameters()); + if (users.length < ps.limit) { + const otherQuery = setUsernameAndHostQuery() + .andWhere(`user.id NOT IN (${ followingQuery.getQuery() })`) + .andWhere('user.isSuspended = FALSE') + .andWhere('user.updatedAt IS NOT NULL'); - const otherUsers = await otherQuery - .orderBy('user.updatedAt', 'DESC') - .take(ps.limit - users.length) - .getMany(); + otherQuery.setParameters(followingQuery.getParameters()); - users = users.concat(otherUsers); - } - } else { - users = await this.usersRepository.createQueryBuilder('user') - .where('user.isSuspended = FALSE') - .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' }) - .andWhere('user.updatedAt IS NOT NULL') + const otherUsers = await otherQuery .orderBy('user.updatedAt', 'DESC') .take(ps.limit - users.length) .getMany(); + + users = users.concat(otherUsers); } + } else { + const query = setUsernameAndHostQuery() + .andWhere('user.isSuspended = FALSE') + .andWhere('user.updatedAt IS NOT NULL'); - return await this.userEntityService.packMany(users, me, { detail: !!ps.detail }); + users = await query + .orderBy('user.updatedAt', 'DESC') + .take(ps.limit - users.length) + .getMany(); } - return []; + return await this.userEntityService.packMany(users, me, { detail: !!ps.detail }); }); } } diff --git a/packages/frontend/src/components/MkInput.vue b/packages/frontend/src/components/MkInput.vue index 0f99bf9aad..3e3d7354c1 100644 --- a/packages/frontend/src/components/MkInput.vue +++ b/packages/frontend/src/components/MkInput.vue @@ -23,7 +23,7 @@ @input="onInput" > <datalist v-if="datalist" :id="id"> - <option v-for="data in datalist" :value="data"/> + <option v-for="data in datalist" :key="data" :value="data"/> </datalist> <div ref="suffixEl" class="suffix"><slot name="suffix"></slot></div> </div> diff --git a/packages/frontend/src/components/MkUserSelectDialog.vue b/packages/frontend/src/components/MkUserSelectDialog.vue index 981ae56e6c..4ce8c08512 100644 --- a/packages/frontend/src/components/MkUserSelectDialog.vue +++ b/packages/frontend/src/components/MkUserSelectDialog.vue @@ -16,7 +16,7 @@ <template #label>{{ i18n.ts.username }}</template> <template #prefix>@</template> </MkInput> - <MkInput v-model="host" @update:model-value="search"> + <MkInput v-model="host" @update:model-value="search" :datalist="[hostname]"> <template #label>{{ i18n.ts.host }}</template> <template #prefix>@</template> </MkInput> @@ -61,6 +61,7 @@ import * as os from '@/os'; import { defaultStore } from '@/store'; import { i18n } from '@/i18n'; import { $i } from '@/account'; +import { hostname } from '@/config'; const emit = defineEmits<{ (ev: 'ok', selected: misskey.entities.UserDetailed): void; @@ -115,7 +116,7 @@ onMounted(() => { os.api('users/show', { userIds: defaultStore.state.recentlyUsedUsers, }).then(users => { - if (props.includeSelf) { + if (props.includeSelf && users.find(x => $i ? x.id === $i.id : true) == null) { recentUsers = [$i, ...users]; } else { recentUsers = users; |