Merge branch 'develop' into no-websocket

This commit is contained in:
syuilo 2025-03-28 11:18:15 +09:00
commit 678b718c24
8 changed files with 39 additions and 7 deletions

8
locales/index.d.ts vendored
View File

@ -5472,6 +5472,14 @@ export interface Locale extends ILocale {
* *
*/ */
"deleteRoom": string; "deleteRoom": string;
/**
*
*/
"chatNotAvailableForThisAccountOrServer": string;
/**
* 使
*/
"chatNotAvailableInOtherAccount": string;
/** /**
* *
*/ */

View File

@ -1365,6 +1365,8 @@ _chat:
newline: "改行" newline: "改行"
muteThisRoom: "このルームをミュート" muteThisRoom: "このルームをミュート"
deleteRoom: "ルームを削除" deleteRoom: "ルームを削除"
chatNotAvailableForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは有効化されていません。"
chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えない状態になっています。"
cannotChatWithTheUser: "このユーザーとのチャットを開始できません" cannotChatWithTheUser: "このユーザーとのチャットを開始できません"
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。" cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。"
chatWithThisUser: "チャットする" chatWithThisUser: "チャットする"

View File

@ -557,6 +557,7 @@ export class UserEntityService implements OnModuleInit {
followersVisibility: profile!.followersVisibility, followersVisibility: profile!.followersVisibility,
followingVisibility: profile!.followingVisibility, followingVisibility: profile!.followingVisibility,
chatScope: user.chatScope, chatScope: user.chatScope,
canChat: this.roleService.getUserPolicies(user.id).then(r => r.canChat),
roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({ roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({
id: role.id, id: role.id,
name: role.name, name: role.name,

View File

@ -363,6 +363,10 @@ export const packedUserDetailedNotMeOnlySchema = {
nullable: false, optional: false, nullable: false, optional: false,
enum: ['everyone', 'following', 'followers', 'mutual', 'none'], enum: ['everyone', 'following', 'followers', 'mutual', 'none'],
}, },
canChat: {
type: 'boolean',
nullable: false, optional: false,
},
roles: { roles: {
type: 'array', type: 'array',
nullable: false, optional: false, nullable: false, optional: false,

View File

@ -5,7 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<div class="_gaps"> <div class="_gaps">
<MkButton primary gradate rounded :class="$style.start" @click="start"><i class="ti ti-plus"></i> {{ i18n.ts.startChat }}</MkButton> <MkButton v-if="$i.policies.canChat" primary gradate rounded :class="$style.start" @click="start"><i class="ti ti-plus"></i> {{ i18n.ts.startChat }}</MkButton>
<MkInfo v-else>{{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo>
<MkAd :prefer="['horizontal', 'horizontal-big']"/> <MkAd :prefer="['horizontal', 'horizontal-big']"/>
@ -78,6 +80,7 @@ import * as os from '@/os.js';
import { updateCurrentAccountPartial } from '@/accounts.js'; import { updateCurrentAccountPartial } from '@/accounts.js';
import MkInput from '@/components/MkInput.vue'; import MkInput from '@/components/MkInput.vue';
import MkFoldableSection from '@/components/MkFoldableSection.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue';
import MkInfo from '@/components/MkInfo.vue';
const $i = ensureSignin(); const $i = ensureSignin();

View File

@ -41,6 +41,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<XMessage v-for="message in messages.toReversed()" :key="message.id" :message="message"/> <XMessage v-for="message in messages.toReversed()" :key="message.id" :message="message"/>
</TransitionGroup> </TransitionGroup>
</div> </div>
<div v-if="user && (!user.canChat || user.host !== null)">
<MkInfo warn>{{ i18n.ts._chat.chatNotAvailableInOtherAccount }}</MkInfo>
</div>
<MkInfo v-if="!$i.policies.canChat" warn>{{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo>
</MkSpacer> </MkSpacer>
<MkSpacer v-else-if="tab === 'search'" :contentMax="700"> <MkSpacer v-else-if="tab === 'search'" :contentMax="700">
@ -93,6 +99,7 @@ import { prefer } from '@/preferences.js';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import { useRouter } from '@/router.js'; import { useRouter } from '@/router.js';
import { useMutationObserver } from '@/use/use-mutation-observer.js'; import { useMutationObserver } from '@/use/use-mutation-observer.js';
import MkInfo from '@/components/MkInfo.vue';
const $i = ensureSignin(); const $i = ensureSignin();
const router = useRouter(); const router = useRouter();

View File

@ -362,12 +362,18 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`; const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`;
os.post({ specified: user, initialText: `${canonical} ` }); os.post({ specified: user, initialText: `${canonical} ` });
}, },
}, { });
if ($i.policies.canChat && user.canChat && user.host == null) {
menuItems.push({
type: 'link', type: 'link',
icon: 'ti ti-messages', icon: 'ti ti-messages',
text: i18n.ts._chat.chatWithThisUser, text: i18n.ts._chat.chatWithThisUser,
to: `/chat/user/${user.id}`, to: `/chat/user/${user.id}`,
}, { type: 'divider' }, { });
}
menuItems.push({ type: 'divider' }, {
icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off', icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute, text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
action: toggleMute, action: toggleMute,

View File

@ -4057,6 +4057,7 @@ export type components = {
followersVisibility: 'public' | 'followers' | 'private'; followersVisibility: 'public' | 'followers' | 'private';
/** @enum {string} */ /** @enum {string} */
chatScope: 'everyone' | 'following' | 'followers' | 'mutual' | 'none'; chatScope: 'everyone' | 'following' | 'followers' | 'mutual' | 'none';
canChat: boolean;
roles: components['schemas']['RoleLite'][]; roles: components['schemas']['RoleLite'][];
followedMessage?: string | null; followedMessage?: string | null;
memo: string | null; memo: string | null;