enhance(frontend): ローカルユーザーのみグループに招待できるように

This commit is contained in:
NoriDev 2023-09-25 19:58:46 +09:00
parent 615d4bcd13
commit 4d3ab485c5
5 changed files with 35 additions and 10 deletions

View file

@ -71,6 +71,7 @@
- Enhance: 로그인할 때 프로필 아이콘의 모양을 '프로필 아이콘을 사각형으로 표시' 설정을 따르도록 - Enhance: 로그인할 때 프로필 아이콘의 모양을 '프로필 아이콘을 사각형으로 표시' 설정을 따르도록
- Enhance: 일부 설정 배치 변경 - Enhance: 일부 설정 배치 변경
- Enhance: '타임라인 상단에 글 작성란 표시' 옵션이 활성화 되었을 때 autofocus를 사용하지 않도록 - Enhance: '타임라인 상단에 글 작성란 표시' 옵션이 활성화 되었을 때 autofocus를 사용하지 않도록
- Enhance: 로컬 유저만 그룹에 초대할 수 있도록
- Fix: (Friendly) 흐림 효과를 사용할 때 하단 내비게이션 바의 가독성이 매우 떨어지는 문제 - Fix: (Friendly) 흐림 효과를 사용할 때 하단 내비게이션 바의 가독성이 매우 떨어지는 문제
- Fix: (Friendly) 위젯 버튼에서 'UI 애니메이션 줄이기' 옵션이 적용되지 않는 문제 - Fix: (Friendly) 위젯 버튼에서 'UI 애니메이션 줄이기' 옵션이 적용되지 않는 문제
- Fix: (Friendly) 스크롤을 해도 위젯 버튼이 숨겨지지 않는 문제 - Fix: (Friendly) 스크롤을 해도 위젯 버튼이 숨겨지지 않는 문제

View file

@ -17,17 +17,17 @@ SPDX-License-Identifier: AGPL-3.0-only
<div> <div>
<div :class="$style.form"> <div :class="$style.form">
<FormSplit :minWidth="170"> <FormSplit :minWidth="170">
<MkInput v-model="username" :autofocus="true" @update:modelValue="search"> <MkInput v-model="username" :autofocus="true" @update:modelValue="includeHost ? search : searchLocal">
<template #label>{{ i18n.ts.username }}</template> <template #label>{{ i18n.ts.username }}</template>
<template #prefix>@</template> <template #prefix>@</template>
</MkInput> </MkInput>
<MkInput v-model="host" :datalist="[hostname]" @update:modelValue="search"> <MkInput v-if="includeHost" v-model="host" :datalist="[hostname]" @update:modelValue="includeHost ? search : searchLocal">
<template #label>{{ i18n.ts.host }}</template> <template #label>{{ i18n.ts.host }}</template>
<template #prefix>@</template> <template #prefix>@</template>
</MkInput> </MkInput>
</FormSplit> </FormSplit>
</div> </div>
<div v-if="username != '' || host != ''" :class="[$style.result, { [$style.hit]: users.length > 0 }]"> <div v-if="username != '' || (host != '' && includeHost)" :class="[$style.result, { [$style.hit]: users.length > 0 }]">
<div v-if="users.length > 0" :class="$style.users"> <div v-if="users.length > 0" :class="$style.users">
<div v-for="user in users" :key="user.id" class="_button" :class="[$style.user, { [$style.selected]: selected && selected.id === user.id }]" @click="selected = user" @dblclick="ok()"> <div v-for="user in users" :key="user.id" class="_button" :class="[$style.user, { [$style.selected]: selected && selected.id === user.id }]" @click="selected = user" @dblclick="ok()">
<MkAvatar :user="user" :class="$style.avatar" indicator/> <MkAvatar :user="user" :class="$style.avatar" indicator/>
@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span>{{ i18n.ts.noUsers }}</span> <span>{{ i18n.ts.noUsers }}</span>
</div> </div>
</div> </div>
<div v-if="username == '' && host == ''" :class="$style.recent"> <div v-if="(username == '' && !includeHost) || (username == '' && host == '' && includeHost)" :class="$style.recent">
<div :class="$style.users"> <div :class="$style.users">
<div v-for="user in recentUsers" :key="user.id" class="_button" :class="[$style.user, { [$style.selected]: selected && selected.id === user.id }]" @click="selected = user" @dblclick="ok()"> <div v-for="user in recentUsers" :key="user.id" class="_button" :class="[$style.user, { [$style.selected]: selected && selected.id === user.id }]" @click="selected = user" @dblclick="ok()">
<MkAvatar :user="user" :class="$style.avatar" indicator/> <MkAvatar :user="user" :class="$style.avatar" indicator/>
@ -74,9 +74,12 @@ const emit = defineEmits<{
(ev: 'closed'): void; (ev: 'closed'): void;
}>(); }>();
const props = defineProps<{ const props = withDefaults(defineProps<{
includeSelf?: boolean; includeSelf?: boolean;
}>(); includeHost?: boolean;
}>(), {
includeHost: true,
});
let username = $ref(''); let username = $ref('');
let host = $ref(''); let host = $ref('');
@ -100,6 +103,20 @@ const search = () => {
}); });
}; };
const searchLocal = () => {
if (username === '') {
users = [];
return;
}
os.api('users/search', {
username: username,
limit: 10,
detail: false,
}).then(_users => {
users = _users;
});
};
const ok = () => { const ok = () => {
if (selected == null) return; if (selected == null) return;
emit('ok', selected); emit('ok', selected);

View file

@ -435,10 +435,11 @@ export function form(title, form) {
}); });
} }
export async function selectUser(opts: { includeSelf?: boolean } = {}) { export async function selectUser(opts: { includeSelf?: boolean, includeHost?: boolean } = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), { popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), {
includeSelf: opts.includeSelf, includeSelf: opts.includeSelf,
includeHost: opts.includeHost,
}, { }, {
ok: user => { ok: user => {
resolve(user); resolve(user);

View file

@ -69,7 +69,10 @@ function fetchGroup() {
} }
function invite() { function invite() {
os.selectUser().then(user => { os.selectUser({
includeSelf: false,
includeHost: false,
}).then(user => {
os.apiWithDialog('users/groups/invite', { os.apiWithDialog('users/groups/invite', {
groupId: group.id, groupId: group.id,
userId: user.id, userId: user.id,
@ -108,7 +111,10 @@ async function renameGroup() {
} }
function transfer() { function transfer() {
os.selectUser().then(user => { os.selectUser({
includeSelf: false,
includeHost: false,
}).then(user => {
os.apiWithDialog('users/groups/transfer', { os.apiWithDialog('users/groups/transfer', {
groupId: group.id, groupId: group.id,
userId: user.id, userId: user.id,

View file

@ -206,7 +206,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
icon: 'ti ti-messages', icon: 'ti ti-messages',
text: i18n.ts.startMessaging, text: i18n.ts.startMessaging,
to: `/my/messaging/@${user.host === null ? user.username : user.username + '@' + user.host}`, to: `/my/messaging/@${user.host === null ? user.username : user.username + '@' + user.host}`,
} : undefined, meId !== user.id ? { } : undefined, meId !== user.id && user.host === null ? {
icon: 'ti ti-users', icon: 'ti ti-users',
text: i18n.ts.inviteToGroup, text: i18n.ts.inviteToGroup,
action: inviteGroup, action: inviteGroup,