fix: restore build and stabilize E2E cross-signal behavior
Revert the automated member-ordering pass that broke Angular field init (TS2729) and disable that rule until a safe reorder strategy exists. Fix modal/confirm dialog i18n defaults via template fallbacks, search all active endpoints (including offline), register foreign rooms with actor owner IDs, sync profile display names from avatar summaries, and guard dm-chat when a private call converts to a group conversation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
import {
|
||||
Component,
|
||||
computed,
|
||||
@@ -25,6 +26,7 @@ import { DirectCallService } from '../../../direct-call';
|
||||
import { Attachment, AttachmentFacade } from '../../../attachment';
|
||||
import { ThemeNodeDirective } from '../../../theme';
|
||||
import { DirectMessageService } from '../../application/services/direct-message.service';
|
||||
import { isConversationBound } from './dm-chat.rules';
|
||||
import { selectAllUsers, selectCurrentUser } from '../../../../store/users/users.selectors';
|
||||
import { NgIcon, provideIcons } from '@ng-icons/core';
|
||||
import { lucidePhone, lucidePhoneCall } from '@ng-icons/lucide';
|
||||
@@ -83,68 +85,55 @@ interface DmStatusLabel {
|
||||
export class DmChatComponent {
|
||||
@ViewChild(ChatMessageComposerComponent) composer?: ChatMessageComposerComponent;
|
||||
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
private readonly store = inject(Store);
|
||||
private readonly electronBridge = inject(ElectronBridgeService);
|
||||
private readonly attachments = inject(AttachmentFacade);
|
||||
private readonly klipy = inject(KlipyService);
|
||||
private readonly linkMetadata = inject(LinkMetadataService);
|
||||
private readonly profileCard = inject(ProfileCardService);
|
||||
private readonly viewport = inject(ViewportService);
|
||||
private readonly metadataRequestKeys = new Set<string>();
|
||||
private openedConversationId: string | null = null;
|
||||
private readonly i18n = inject(AppI18nService);
|
||||
readonly isMobile = this.viewport.isMobile;
|
||||
|
||||
readonly directCalls = inject(DirectCallService);
|
||||
|
||||
readonly directMessages = inject(DirectMessageService);
|
||||
|
||||
readonly currentUser = this.store.selectSignal(selectCurrentUser);
|
||||
|
||||
readonly allUsers = this.store.selectSignal(selectAllUsers);
|
||||
|
||||
readonly showGifPicker = signal(false);
|
||||
|
||||
readonly conversationId = input<string | null>(null);
|
||||
|
||||
readonly showCallButton = input(true);
|
||||
|
||||
readonly composerBottomPadding = signal(140);
|
||||
|
||||
readonly gifPickerAnchorRight = signal(16);
|
||||
|
||||
readonly linkMetadataByMessageId = signal<Record<string, LinkMetadata[]>>({});
|
||||
|
||||
readonly replyTo = signal<Message | null>(null);
|
||||
|
||||
readonly lightboxState = signal<ChatLightboxState | null>(null);
|
||||
|
||||
readonly galleryAttachments = signal<Attachment[] | null>(null);
|
||||
|
||||
readonly imageContextMenu = signal<ChatMessageImageContextMenuEvent | null>(null);
|
||||
|
||||
readonly routeConversationId = toSignal(this.route.paramMap.pipe(map((params) => params.get('conversationId'))), {
|
||||
initialValue: this.route.snapshot.paramMap.get('conversationId')
|
||||
});
|
||||
|
||||
readonly effectiveConversationId = computed(() => this.conversationId() ?? this.routeConversationId());
|
||||
|
||||
readonly currentUserId = computed(() => this.currentUser()?.oderId || this.currentUser()?.id || '');
|
||||
|
||||
readonly conversation = this.directMessages.selectedConversation;
|
||||
|
||||
readonly klipyEnabled = computed(() => this.klipy.isEnabled(null));
|
||||
|
||||
readonly conversationKey = computed(() => this.conversation()?.id ?? 'dm:none');
|
||||
|
||||
readonly typingUsers = computed(() => {
|
||||
void this.directMessages.typingEntries();
|
||||
|
||||
return this.directMessages.typingUsers(this.conversation()?.id);
|
||||
});
|
||||
|
||||
readonly peerUser = computed(() => {
|
||||
const conversation = this.conversation();
|
||||
|
||||
return conversation ? this.peerUserFor(conversation) : null;
|
||||
});
|
||||
|
||||
readonly isGroupConversation = computed(() => {
|
||||
const conversation = this.conversation();
|
||||
|
||||
return !!conversation && (conversation.kind === 'group' || conversation.participants.length > 2);
|
||||
});
|
||||
|
||||
readonly participantUsers = computed<User[]>(() => {
|
||||
const conversation = this.conversation();
|
||||
const knownUsers = this.allUsers();
|
||||
@@ -176,7 +165,6 @@ export class DmChatComponent {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
readonly messageStatuses = computed<DmStatusLabel[]>(() => {
|
||||
const conversation = this.conversation();
|
||||
const currentUserId = this.currentUserId();
|
||||
@@ -192,12 +180,12 @@ export class DmChatComponent {
|
||||
status: message.status
|
||||
}));
|
||||
});
|
||||
|
||||
readonly chatMessages = computed<Message[]>(() => {
|
||||
const conversation = this.conversation();
|
||||
const metadataByMessageId = this.linkMetadataByMessageId();
|
||||
const boundConversationId = this.effectiveConversationId();
|
||||
|
||||
if (!conversation) {
|
||||
if (!conversation || !isConversationBound(conversation.id, boundConversationId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -227,7 +215,6 @@ export class DmChatComponent {
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
readonly peerName = computed(() => {
|
||||
const conversation = this.conversation();
|
||||
const currentUserId = this.currentUserId();
|
||||
@@ -240,7 +227,6 @@ export class DmChatComponent {
|
||||
|
||||
return peerId ? conversation?.participantProfiles[peerId]?.displayName || peerId : this.i18n.instant('dm.chat.defaultTitle');
|
||||
});
|
||||
|
||||
readonly peerCallIcon = computed(() => {
|
||||
const conversation = this.conversation();
|
||||
|
||||
@@ -252,7 +238,6 @@ export class DmChatComponent {
|
||||
|
||||
return peer && this.directCalls.isCallingUser(peer) ? 'lucidePhoneCall' : 'lucidePhone';
|
||||
});
|
||||
|
||||
readonly canCallConversation = computed(() => {
|
||||
const conversation = this.conversation();
|
||||
|
||||
@@ -267,28 +252,6 @@ export class DmChatComponent {
|
||||
return !!this.peerUser();
|
||||
});
|
||||
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
|
||||
private readonly store = inject(Store);
|
||||
|
||||
private readonly electronBridge = inject(ElectronBridgeService);
|
||||
|
||||
private readonly attachments = inject(AttachmentFacade);
|
||||
|
||||
private readonly klipy = inject(KlipyService);
|
||||
|
||||
private readonly linkMetadata = inject(LinkMetadataService);
|
||||
|
||||
private readonly profileCard = inject(ProfileCardService);
|
||||
|
||||
private readonly viewport = inject(ViewportService);
|
||||
|
||||
private readonly metadataRequestKeys = new Set<string>();
|
||||
|
||||
private openedConversationId: string | null = null;
|
||||
|
||||
private readonly i18n = inject(AppI18nService);
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const conversationId = this.effectiveConversationId();
|
||||
@@ -702,5 +665,4 @@ export class DmChatComponent {
|
||||
|
||||
return `${names.slice(0, 3).join(', ')} +${names.length - 3}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user