Compare commits
No commits in common. "039aacb31f7aabeec8c4174efec2c3f97984bea4" and "e1cd7c94fb13f8e49667b17554d22ce8de627a2a" have entirely different histories.
039aacb31f
...
e1cd7c94fb
|
@ -15,7 +15,6 @@
|
||||||
- 従来のWebsocket接続を行うモードはリアルタイムモードとして再定義されました
|
- 従来のWebsocket接続を行うモードはリアルタイムモードとして再定義されました
|
||||||
- チャットなど、一部の機能は引き続き設定に関わらずWebsocket接続が行われます
|
- チャットなど、一部の機能は引き続き設定に関わらずWebsocket接続が行われます
|
||||||
- Enhance: メモリ使用量を軽減しました
|
- Enhance: メモリ使用量を軽減しました
|
||||||
- Enhance: 招待されているが参加していないルームを開いたときに、招待を承認するかどうか尋ねるように
|
|
||||||
- Enhance: リプライ元にアンケートがあることが表示されるように
|
- Enhance: リプライ元にアンケートがあることが表示されるように
|
||||||
- Enhance: ノートのサーバー情報のデザインを改善・パフォーマンス向上
|
- Enhance: ノートのサーバー情報のデザインを改善・パフォーマンス向上
|
||||||
(Based on https://github.com/taiyme/misskey/pull/198, https://github.com/taiyme/misskey/pull/211, https://github.com/taiyme/misskey/pull/283)
|
(Based on https://github.com/taiyme/misskey/pull/198, https://github.com/taiyme/misskey/pull/211, https://github.com/taiyme/misskey/pull/283)
|
||||||
|
@ -23,7 +22,6 @@
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加
|
- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加
|
||||||
- Enhance: チャットルームのレスポンスに招待されているかどうかを示すフラグ`invitationExists`を追加
|
|
||||||
- Fix: チャットルームが削除された場合・チャットルームから抜けた場合に、未読状態が残り続けることがあるのを修正
|
- Fix: チャットルームが削除された場合・チャットルームから抜けた場合に、未読状態が残り続けることがあるのを修正
|
||||||
- Fix: ユーザ除外アンテナをインポートできない問題を修正
|
- Fix: ユーザ除外アンテナをインポートできない問題を修正
|
||||||
- Fix: アンテナのセンシティブなチャンネルのノートを含むかどうかの情報がエクスポートされない問題を修正
|
- Fix: アンテナのセンシティブなチャンネルのノートを含むかどうかの情報がエクスポートされない問題を修正
|
||||||
|
|
|
@ -5555,14 +5555,6 @@ export interface Locale extends ILocale {
|
||||||
* チャットが使えない状態になっているか、相手がチャットを開放していません。
|
* チャットが使えない状態になっているか、相手がチャットを開放していません。
|
||||||
*/
|
*/
|
||||||
"cannotChatWithTheUser_description": string;
|
"cannotChatWithTheUser_description": string;
|
||||||
/**
|
|
||||||
* あなたはこのルームの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。
|
|
||||||
*/
|
|
||||||
"youAreNotAMemberOfThisRoomButInvited": string;
|
|
||||||
/**
|
|
||||||
* 招待を承認しますか?
|
|
||||||
*/
|
|
||||||
"doYouAcceptInvitation": string;
|
|
||||||
/**
|
/**
|
||||||
* チャットする
|
* チャットする
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1385,8 +1385,6 @@ _chat:
|
||||||
chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えない状態になっています。"
|
chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えない状態になっています。"
|
||||||
cannotChatWithTheUser: "このユーザーとのチャットを開始できません"
|
cannotChatWithTheUser: "このユーザーとのチャットを開始できません"
|
||||||
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。"
|
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。"
|
||||||
youAreNotAMemberOfThisRoomButInvited: "あなたはこのルームの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。"
|
|
||||||
doYouAcceptInvitation: "招待を承認しますか?"
|
|
||||||
chatWithThisUser: "チャットする"
|
chatWithThisUser: "チャットする"
|
||||||
thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみチャットを受け付けています。"
|
thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみチャットを受け付けています。"
|
||||||
thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。"
|
thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2025.5.1-alpha.1",
|
"version": "2025.5.1-alpha.0",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -238,15 +238,13 @@ export class ChatEntityService {
|
||||||
options?: {
|
options?: {
|
||||||
_hint_?: {
|
_hint_?: {
|
||||||
packedOwners: Map<MiChatRoom['id'], Packed<'UserLite'>>;
|
packedOwners: Map<MiChatRoom['id'], Packed<'UserLite'>>;
|
||||||
myMemberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
|
memberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
|
||||||
myInvitations?: Map<MiChatRoom['id'], MiChatRoomInvitation | null | undefined>;
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
): Promise<Packed<'ChatRoom'>> {
|
): Promise<Packed<'ChatRoom'>> {
|
||||||
const room = typeof src === 'object' ? src : await this.chatRoomsRepository.findOneByOrFail({ id: src });
|
const room = typeof src === 'object' ? src : await this.chatRoomsRepository.findOneByOrFail({ id: src });
|
||||||
|
|
||||||
const membership = me && me.id !== room.ownerId ? (options?._hint_?.myMemberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
const membership = me && me.id !== room.ownerId ? (options?._hint_?.memberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
||||||
const invitation = me && me.id !== room.ownerId ? (options?._hint_?.myInvitations?.get(room.id) ?? await this.chatRoomInvitationsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: room.id,
|
id: room.id,
|
||||||
|
@ -256,7 +254,6 @@ export class ChatEntityService {
|
||||||
ownerId: room.ownerId,
|
ownerId: room.ownerId,
|
||||||
owner: options?._hint_?.packedOwners.get(room.ownerId) ?? await this.userEntityService.pack(room.owner ?? room.ownerId, me),
|
owner: options?._hint_?.packedOwners.get(room.ownerId) ?? await this.userEntityService.pack(room.owner ?? room.ownerId, me),
|
||||||
isMuted: membership != null ? membership.isMuted : false,
|
isMuted: membership != null ? membership.isMuted : false,
|
||||||
invitationExists: invitation != null,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +278,7 @@ export class ChatEntityService {
|
||||||
|
|
||||||
const owners = _rooms.map(x => x.owner ?? x.ownerId);
|
const owners = _rooms.map(x => x.owner ?? x.ownerId);
|
||||||
|
|
||||||
const [packedOwners, myMemberships, myInvitations] = await Promise.all([
|
const [packedOwners, memberships] = await Promise.all([
|
||||||
this.userEntityService.packMany(owners, me)
|
this.userEntityService.packMany(owners, me)
|
||||||
.then(users => new Map(users.map(u => [u.id, u]))),
|
.then(users => new Map(users.map(u => [u.id, u]))),
|
||||||
this.chatRoomMembershipsRepository.find({
|
this.chatRoomMembershipsRepository.find({
|
||||||
|
@ -290,15 +287,9 @@ export class ChatEntityService {
|
||||||
userId: me.id,
|
userId: me.id,
|
||||||
},
|
},
|
||||||
}).then(memberships => new Map(_rooms.map(r => [r.id, memberships.find(m => m.roomId === r.id)]))),
|
}).then(memberships => new Map(_rooms.map(r => [r.id, memberships.find(m => m.roomId === r.id)]))),
|
||||||
this.chatRoomInvitationsRepository.find({
|
|
||||||
where: {
|
|
||||||
roomId: In(_rooms.map(x => x.id)),
|
|
||||||
userId: me.id,
|
|
||||||
},
|
|
||||||
}).then(invitations => new Map(_rooms.map(r => [r.id, invitations.find(i => i.roomId === r.id)]))),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, myMemberships, myInvitations } })));
|
return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, memberships } })));
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
@ -36,9 +36,5 @@ export const packedChatRoomSchema = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: true, nullable: false,
|
||||||
},
|
},
|
||||||
invitationExists: {
|
|
||||||
type: 'boolean',
|
|
||||||
optional: true, nullable: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -37,8 +37,8 @@ export type PagingCtx<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoint
|
||||||
direction?: 'newer' | 'older';
|
direction?: 'newer' | 'older';
|
||||||
};
|
};
|
||||||
|
|
||||||
export function usePagination<Endpoint extends keyof Misskey.Endpoints, T = Misskey.Endpoints[Endpoint]['res'] extends (infer I)[] ? I : never>(props: {
|
export function usePagination<T extends MisskeyEntity>(props: {
|
||||||
ctx: PagingCtx<Endpoint>;
|
ctx: PagingCtx;
|
||||||
useShallowRef?: boolean;
|
useShallowRef?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const items = props.useShallowRef ? shallowRef<T[]>([]) : ref<T[]>([]);
|
const items = props.useShallowRef ? shallowRef<T[]>([]) : ref<T[]>([]);
|
||||||
|
|
|
@ -80,7 +80,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
<XForm v-if="initialized" :user="user" :room="room" :class="$style.form"/>
|
<XForm v-if="!initializing" :user="user" :room="room" :class="$style.form"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -127,8 +127,7 @@ export type NormalizedChatMessage = Omit<Misskey.entities.ChatMessageLite, 'from
|
||||||
})[];
|
})[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const initializing = ref(false);
|
const initializing = ref(true);
|
||||||
const initialized = ref(false);
|
|
||||||
const moreFetching = ref(false);
|
const moreFetching = ref(false);
|
||||||
const messages = ref<NormalizedChatMessage[]>([]);
|
const messages = ref<NormalizedChatMessage[]>([]);
|
||||||
const canFetchMore = ref(false);
|
const canFetchMore = ref(false);
|
||||||
|
@ -172,10 +171,7 @@ function normalizeMessage(message: Misskey.entities.ChatMessageLite | Misskey.en
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
const LIMIT = 20;
|
const LIMIT = 20;
|
||||||
|
|
||||||
if (initializing.value) return;
|
|
||||||
|
|
||||||
initializing.value = true;
|
initializing.value = true;
|
||||||
initialized.value = false;
|
|
||||||
|
|
||||||
if (props.userId) {
|
if (props.userId) {
|
||||||
const [u, m] = await Promise.all([
|
const [u, m] = await Promise.all([
|
||||||
|
@ -198,44 +194,13 @@ async function initialize() {
|
||||||
connection.value.on('react', onReact);
|
connection.value.on('react', onReact);
|
||||||
connection.value.on('unreact', onUnreact);
|
connection.value.on('unreact', onUnreact);
|
||||||
} else {
|
} else {
|
||||||
const [rResult, mResult] = await Promise.allSettled([
|
const [r, m] = await Promise.all([
|
||||||
misskeyApi('chat/rooms/show', { roomId: props.roomId }),
|
misskeyApi('chat/rooms/show', { roomId: props.roomId }),
|
||||||
misskeyApi('chat/messages/room-timeline', { roomId: props.roomId, limit: LIMIT }),
|
misskeyApi('chat/messages/room-timeline', { roomId: props.roomId, limit: LIMIT }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (rResult.status === 'rejected') {
|
room.value = r as Misskey.entities.ChatRoomsShowResponse;
|
||||||
os.alert({
|
messages.value = (m as Misskey.entities.ChatMessagesRoomTimelineResponse).map(x => normalizeMessage(x));
|
||||||
type: 'error',
|
|
||||||
text: i18n.ts.somethingHappened,
|
|
||||||
});
|
|
||||||
initializing.value = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const r = rResult.value as Misskey.entities.ChatRoomsShowResponse;
|
|
||||||
|
|
||||||
if (r.invitationExists) {
|
|
||||||
const confirm = await os.confirm({
|
|
||||||
type: 'question',
|
|
||||||
title: r.name,
|
|
||||||
text: i18n.ts._chat.youAreNotAMemberOfThisRoomButInvited + '\n' + i18n.ts._chat.doYouAcceptInvitation,
|
|
||||||
});
|
|
||||||
if (confirm.canceled) {
|
|
||||||
initializing.value = false;
|
|
||||||
router.push('/chat');
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
await os.apiWithDialog('chat/rooms/join', { roomId: r.id });
|
|
||||||
initializing.value = false;
|
|
||||||
initialize();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const m = mResult.status === 'fulfilled' ? mResult.value as Misskey.entities.ChatMessagesRoomTimelineResponse : [];
|
|
||||||
|
|
||||||
room.value = r;
|
|
||||||
messages.value = m.map(x => normalizeMessage(x));
|
|
||||||
|
|
||||||
if (messages.value.length === LIMIT) {
|
if (messages.value.length === LIMIT) {
|
||||||
canFetchMore.value = true;
|
canFetchMore.value = true;
|
||||||
|
@ -252,7 +217,6 @@ async function initialize() {
|
||||||
|
|
||||||
window.document.addEventListener('visibilitychange', onVisibilitychange);
|
window.document.addEventListener('visibilitychange', onVisibilitychange);
|
||||||
|
|
||||||
initialized.value = true;
|
|
||||||
initializing.value = false;
|
initializing.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,12 +319,6 @@ onMounted(() => {
|
||||||
initialize();
|
initialize();
|
||||||
});
|
});
|
||||||
|
|
||||||
onActivated(() => {
|
|
||||||
if (!initialized.value) {
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
connection.value?.dispose();
|
connection.value?.dispose();
|
||||||
window.document.removeEventListener('visibilitychange', onVisibilitychange);
|
window.document.removeEventListener('visibilitychange', onVisibilitychange);
|
||||||
|
@ -452,7 +410,7 @@ const headerActions = computed<PageHeaderItem[]>(() => [{
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
definePage(computed(() => {
|
definePage(computed(() => {
|
||||||
if (initialized.value) {
|
if (!initializing.value) {
|
||||||
if (user.value) {
|
if (user.value) {
|
||||||
return {
|
return {
|
||||||
userName: user.value,
|
userName: user.value,
|
||||||
|
|
|
@ -133,7 +133,7 @@ export function playMisskeySfx(operationType: OperationType) {
|
||||||
playMisskeySfxFile(sound).then((succeed) => {
|
playMisskeySfxFile(sound).then((succeed) => {
|
||||||
if (!succeed && sound.type === '_driveFile_') {
|
if (!succeed && sound.type === '_driveFile_') {
|
||||||
// ドライブファイルが存在しない場合はデフォルトのサウンドを再生する
|
// ドライブファイルが存在しない場合はデフォルトのサウンドを再生する
|
||||||
const soundName = PREF_DEF[`sound.on.${operationType}`].default.type as Exclude<SoundType, '_driveFile_'>;
|
const soundName = PREF_DEF[`sound_${operationType}`].default.type as Exclude<SoundType, '_driveFile_'>;
|
||||||
if (_DEV_) console.log(`Failed to play sound: ${sound.fileUrl}, so play default sound: ${soundName}`);
|
if (_DEV_) console.log(`Failed to play sound: ${sound.fileUrl}, so play default sound: ${soundName}`);
|
||||||
playMisskeySfxFileInternal({
|
playMisskeySfxFileInternal({
|
||||||
type: soundName,
|
type: soundName,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"name": "misskey-js",
|
"name": "misskey-js",
|
||||||
"version": "2025.5.1-alpha.1",
|
"version": "2025.5.1-alpha.0",
|
||||||
"description": "Misskey SDK for JavaScript",
|
"description": "Misskey SDK for JavaScript",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
|
|
|
@ -5534,7 +5534,6 @@ export type components = {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
isMuted?: boolean;
|
isMuted?: boolean;
|
||||||
invitationExists?: boolean;
|
|
||||||
};
|
};
|
||||||
ChatRoomInvitation: {
|
ChatRoomInvitation: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
Loading…
Reference in New Issue