summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/src/core/entities/ChatEntityService.ts17
-rw-r--r--packages/backend/src/models/json-schema/chat-room.ts4
-rw-r--r--packages/frontend/src/pages/chat/room.vue54
-rw-r--r--packages/misskey-js/src/autogen/types.ts1
4 files changed, 66 insertions, 10 deletions
diff --git a/packages/backend/src/core/entities/ChatEntityService.ts b/packages/backend/src/core/entities/ChatEntityService.ts
index da112d5444..6bce2413fd 100644
--- a/packages/backend/src/core/entities/ChatEntityService.ts
+++ b/packages/backend/src/core/entities/ChatEntityService.ts
@@ -238,13 +238,15 @@ export class ChatEntityService {
options?: {
_hint_?: {
packedOwners: Map<MiChatRoom['id'], Packed<'UserLite'>>;
- memberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
+ myMemberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
+ myInvitations?: Map<MiChatRoom['id'], MiChatRoomInvitation | null | undefined>;
};
},
): Promise<Packed<'ChatRoom'>> {
const room = typeof src === 'object' ? src : await this.chatRoomsRepository.findOneByOrFail({ id: src });
- 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 membership = me && me.id !== room.ownerId ? (options?._hint_?.myMemberships?.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 {
id: room.id,
@@ -254,6 +256,7 @@ export class ChatEntityService {
ownerId: room.ownerId,
owner: options?._hint_?.packedOwners.get(room.ownerId) ?? await this.userEntityService.pack(room.owner ?? room.ownerId, me),
isMuted: membership != null ? membership.isMuted : false,
+ invitationExists: invitation != null,
};
}
@@ -278,7 +281,7 @@ export class ChatEntityService {
const owners = _rooms.map(x => x.owner ?? x.ownerId);
- const [packedOwners, memberships] = await Promise.all([
+ const [packedOwners, myMemberships, myInvitations] = await Promise.all([
this.userEntityService.packMany(owners, me)
.then(users => new Map(users.map(u => [u.id, u]))),
this.chatRoomMembershipsRepository.find({
@@ -287,9 +290,15 @@ export class ChatEntityService {
userId: me.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, memberships } })));
+ return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, myMemberships, myInvitations } })));
}
@bindThis
diff --git a/packages/backend/src/models/json-schema/chat-room.ts b/packages/backend/src/models/json-schema/chat-room.ts
index e97556e378..e628a9baa3 100644
--- a/packages/backend/src/models/json-schema/chat-room.ts
+++ b/packages/backend/src/models/json-schema/chat-room.ts
@@ -36,5 +36,9 @@ export const packedChatRoomSchema = {
type: 'boolean',
optional: true, nullable: false,
},
+ invitationExists: {
+ type: 'boolean',
+ optional: true, nullable: false,
+ },
},
} as const;
diff --git a/packages/frontend/src/pages/chat/room.vue b/packages/frontend/src/pages/chat/room.vue
index 64d3420166..ac13c5fac6 100644
--- a/packages/frontend/src/pages/chat/room.vue
+++ b/packages/frontend/src/pages/chat/room.vue
@@ -80,7 +80,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</button>
</div>
</Transition>
- <XForm v-if="!initializing" :user="user" :room="room" :class="$style.form"/>
+ <XForm v-if="initialized" :user="user" :room="room" :class="$style.form"/>
</div>
</div>
</template>
@@ -127,7 +127,8 @@ export type NormalizedChatMessage = Omit<Misskey.entities.ChatMessageLite, 'from
})[];
};
-const initializing = ref(true);
+const initializing = ref(false);
+const initialized = ref(false);
const moreFetching = ref(false);
const messages = ref<NormalizedChatMessage[]>([]);
const canFetchMore = ref(false);
@@ -171,7 +172,10 @@ function normalizeMessage(message: Misskey.entities.ChatMessageLite | Misskey.en
async function initialize() {
const LIMIT = 20;
+ if (initializing.value) return;
+
initializing.value = true;
+ initialized.value = false;
if (props.userId) {
const [u, m] = await Promise.all([
@@ -194,13 +198,44 @@ async function initialize() {
connection.value.on('react', onReact);
connection.value.on('unreact', onUnreact);
} else {
- const [r, m] = await Promise.all([
+ const [rResult, mResult] = await Promise.allSettled([
misskeyApi('chat/rooms/show', { roomId: props.roomId }),
misskeyApi('chat/messages/room-timeline', { roomId: props.roomId, limit: LIMIT }),
]);
- room.value = r as Misskey.entities.ChatRoomsShowResponse;
- messages.value = (m as Misskey.entities.ChatMessagesRoomTimelineResponse).map(x => normalizeMessage(x));
+ if (rResult.status === 'rejected') {
+ os.alert({
+ 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) {
canFetchMore.value = true;
@@ -217,6 +252,7 @@ async function initialize() {
window.document.addEventListener('visibilitychange', onVisibilitychange);
+ initialized.value = true;
initializing.value = false;
}
@@ -319,6 +355,12 @@ onMounted(() => {
initialize();
});
+onActivated(() => {
+ if (!initialized.value) {
+ initialize();
+ }
+});
+
onBeforeUnmount(() => {
connection.value?.dispose();
window.document.removeEventListener('visibilitychange', onVisibilitychange);
@@ -410,7 +452,7 @@ const headerActions = computed<PageHeaderItem[]>(() => [{
}]);
definePage(computed(() => {
- if (!initializing.value) {
+ if (initialized.value) {
if (user.value) {
return {
userName: user.value,
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index 91359cffda..1e38446882 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5534,6 +5534,7 @@ export type components = {
name: string;
description: string;
isMuted?: boolean;
+ invitationExists?: boolean;
};
ChatRoomInvitation: {
id: string;