mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-23 03:25:07 +03:00
Clean up
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { MessagePanel } from "./MessagePanel";
|
||||
import {
|
||||
fetchDMHistory,
|
||||
decryptDm,
|
||||
import {
|
||||
fetchDMHistory,
|
||||
decryptDm,
|
||||
sendDMViaWebSocket,
|
||||
sendDmWithFiles,
|
||||
editDmEnvelope,
|
||||
@@ -43,7 +43,7 @@ export class DMPanel extends MessagePanel {
|
||||
async activate(): Promise<void> {
|
||||
// Don't load messages immediately during activation to prevent animation freeze
|
||||
// Messages will be loaded after the animation completes
|
||||
|
||||
|
||||
// Subscribe to recipient's online status
|
||||
if (this.dmData?.userId) {
|
||||
onlineStatusManager.subscribe(this.dmData.userId);
|
||||
@@ -65,9 +65,9 @@ export class DMPanel extends MessagePanel {
|
||||
private async parseTextPayload(env: DmEnvelope, decryptedMessages: Message[]) {
|
||||
const plaintext = await decryptDm(env, this.dmData!.publicKey);
|
||||
const username = formatDMUsername(
|
||||
env.senderId,
|
||||
env.recipientId,
|
||||
this.currentUser.currentUser?.id!,
|
||||
env.senderId,
|
||||
env.recipientId,
|
||||
this.currentUser.currentUser?.id!,
|
||||
this.dmData!.username
|
||||
);
|
||||
|
||||
@@ -146,10 +146,10 @@ export class DMPanel extends MessagePanel {
|
||||
if (!this.currentUser.authToken || !this.dmData || !content.trim()) return;
|
||||
|
||||
try {
|
||||
const payload: DmEncryptedJSON = {
|
||||
type: "text",
|
||||
data: {
|
||||
content: content.trim(),
|
||||
const payload: DmEncryptedJSON = {
|
||||
type: "text",
|
||||
data: {
|
||||
content: content.trim(),
|
||||
reply_to_id: replyToId ?? undefined
|
||||
}
|
||||
}
|
||||
@@ -193,12 +193,12 @@ export class DMPanel extends MessagePanel {
|
||||
async handleWebSocketMessage(response: DMWebSocketMessage): Promise<void> {
|
||||
if (response.type === "dmNew" && this.dmData) {
|
||||
const envelope = response.data;
|
||||
|
||||
|
||||
// If this is for the active DM conversation
|
||||
if (envelope.senderId === this.dmData.userId || envelope.recipientId === this.dmData.userId) {
|
||||
try {
|
||||
const dmMsg = await this.parseTextPayload(envelope, this.getMessages());
|
||||
|
||||
|
||||
// Check if this is a confirmation of a message we sent
|
||||
const isOurMessage = envelope.senderId !== this.dmData.userId;
|
||||
if (isOurMessage) {
|
||||
@@ -211,7 +211,7 @@ export class DMPanel extends MessagePanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.addMessage(dmMsg);
|
||||
|
||||
// Update last read if it's from the other user
|
||||
@@ -228,17 +228,17 @@ export class DMPanel extends MessagePanel {
|
||||
try {
|
||||
// Decrypt new content in-place
|
||||
const plaintext = await decryptDm(
|
||||
{
|
||||
id,
|
||||
senderId: 0,
|
||||
recipientId: 0,
|
||||
iv,
|
||||
ciphertext,
|
||||
salt,
|
||||
iv2,
|
||||
wrappedMk,
|
||||
timestamp: new Date().toISOString()
|
||||
},
|
||||
{
|
||||
id,
|
||||
senderId: 0,
|
||||
recipientId: 0,
|
||||
iv,
|
||||
ciphertext,
|
||||
salt,
|
||||
iv2,
|
||||
wrappedMk,
|
||||
timestamp: new Date().toISOString()
|
||||
},
|
||||
this.dmData.publicKey
|
||||
);
|
||||
let content = plaintext;
|
||||
@@ -272,7 +272,7 @@ export class DMPanel extends MessagePanel {
|
||||
if (this.dmData?.userId) {
|
||||
onlineStatusManager.unsubscribe(this.dmData.userId);
|
||||
}
|
||||
|
||||
|
||||
this.dmData = null;
|
||||
this.messagesLoaded = false;
|
||||
this.clearMessages();
|
||||
@@ -324,10 +324,10 @@ export class DMPanel extends MessagePanel {
|
||||
|
||||
async handleDeleteMessage(messageId: number): Promise<void> {
|
||||
if (!this.currentUser.authToken || !this.dmData) return;
|
||||
|
||||
|
||||
// Remove message immediately from UI
|
||||
this.deleteMessageImmediately(messageId);
|
||||
|
||||
|
||||
// Fire and forget server deletion; UI already updated
|
||||
await deleteDmEnvelope(messageId, this.dmData.userId, this.currentUser.authToken);
|
||||
}
|
||||
@@ -348,14 +348,14 @@ export class DMPanel extends MessagePanel {
|
||||
console.error("Failed to edit DM:", e);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async getProfile(): Promise<ProfileDialogData | null> {
|
||||
if (!this.dmData || !this.currentUser.authToken) return null;
|
||||
|
||||
|
||||
try {
|
||||
const userProfile = await fetchUserProfile(this.currentUser.authToken, this.dmData.username);
|
||||
if (!userProfile) return null;
|
||||
|
||||
|
||||
return {
|
||||
userId: userProfile.id,
|
||||
username: userProfile.username,
|
||||
@@ -373,10 +373,10 @@ export class DMPanel extends MessagePanel {
|
||||
|
||||
updateMessageReactions(dmEnvelopeId: number, reactions: any[]): void {
|
||||
const messages = this.getMessages();
|
||||
const messageIndex = messages.findIndex(msg =>
|
||||
const messageIndex = messages.findIndex(msg =>
|
||||
msg.runtimeData?.dmEnvelope?.id === dmEnvelopeId
|
||||
);
|
||||
|
||||
|
||||
if (messageIndex !== -1) {
|
||||
const updatedMessage = { ...messages[messageIndex] };
|
||||
updatedMessage.reactions = reactions;
|
||||
|
||||
@@ -89,7 +89,7 @@ export abstract class MessagePanel {
|
||||
|
||||
protected updateMessageReactions(messageId: number, reactions: any[]): void {
|
||||
this.updateState({
|
||||
messages: this.state.messages.map(msg =>
|
||||
messages: this.state.messages.map(msg =>
|
||||
msg.id === messageId ? { ...msg, reactions } : msg
|
||||
)
|
||||
});
|
||||
@@ -125,7 +125,7 @@ export abstract class MessagePanel {
|
||||
}
|
||||
|
||||
// ========== PUBLIC API ==========
|
||||
|
||||
|
||||
// Event handlers
|
||||
handleSendMessage(content: string, replyToId?: number, files: File[] = []): void {
|
||||
this.sendMessageWithImmediateDisplay(content, replyToId, files);
|
||||
@@ -136,10 +136,10 @@ export abstract class MessagePanel {
|
||||
if (!message?.runtimeData?.sendingState?.retryData) return;
|
||||
|
||||
const { content, replyToId, files } = message.runtimeData.sendingState.retryData;
|
||||
|
||||
|
||||
// Create new temp ID for retry
|
||||
const tempId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
||||
|
||||
|
||||
// Update status back to sending and create new temp message
|
||||
const retryMessage: Message = {
|
||||
...message,
|
||||
@@ -184,7 +184,7 @@ export abstract class MessagePanel {
|
||||
// Clear the timeout since we're handling the failure immediately
|
||||
clearTimeout(timeoutId);
|
||||
this.pendingMessages.delete(tempId);
|
||||
|
||||
|
||||
// Update message to failed state directly
|
||||
this.updateState({
|
||||
messages: this.state.messages.map(msg => {
|
||||
@@ -211,7 +211,7 @@ export abstract class MessagePanel {
|
||||
if (pending) {
|
||||
clearTimeout(pending.timeoutId);
|
||||
this.pendingMessages.delete(tempId);
|
||||
|
||||
|
||||
// Replace temporary message with confirmed one
|
||||
this.updateState({
|
||||
messages: this.state.messages.map(msg => {
|
||||
@@ -249,7 +249,7 @@ export abstract class MessagePanel {
|
||||
}
|
||||
|
||||
// ========== PRIVATE METHODS ==========
|
||||
|
||||
|
||||
// Create and display message immediately with sending state
|
||||
private async sendMessageWithImmediateDisplay(content: string, replyToId?: number, files: File[] = []): Promise<void> {
|
||||
if (!content.trim() && files.length === 0) return;
|
||||
@@ -326,7 +326,7 @@ export abstract class MessagePanel {
|
||||
if (pending) {
|
||||
clearTimeout(pending.timeoutId);
|
||||
this.pendingMessages.delete(tempId);
|
||||
|
||||
|
||||
// Update message to failed state
|
||||
this.updateState({
|
||||
messages: this.state.messages.map(msg => {
|
||||
|
||||
@@ -70,7 +70,7 @@ export class PublicChatPanel extends MessagePanel {
|
||||
if (files.length === 0) {
|
||||
const response = await request({
|
||||
data: {
|
||||
content: content.trim(),
|
||||
content: content.trim(),
|
||||
reply_to_id: replyToId ?? null
|
||||
},
|
||||
credentials: {
|
||||
@@ -86,7 +86,7 @@ export class PublicChatPanel extends MessagePanel {
|
||||
const form = new FormData();
|
||||
form.append("payload", JSON.stringify({
|
||||
content: content.trim(),
|
||||
reply_to_id: replyToId ?? null
|
||||
reply_to_id: replyToId ?? null
|
||||
} satisfies SendMessageRequest["data"]));
|
||||
for (const f of files) form.append("files", f, f.name);
|
||||
const res = await fetch(`${API_BASE_URL}/send_message`, {
|
||||
@@ -119,7 +119,7 @@ export class PublicChatPanel extends MessagePanel {
|
||||
case 'newMessage':
|
||||
if (response.data) {
|
||||
const newMsg = response.data;
|
||||
|
||||
|
||||
// Check if this is a confirmation of a message we sent
|
||||
const isOurMessage = newMsg.username === this.currentUser.currentUser?.username;
|
||||
if (isOurMessage) {
|
||||
@@ -132,7 +132,7 @@ export class PublicChatPanel extends MessagePanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.addMessage(newMsg);
|
||||
}
|
||||
break;
|
||||
@@ -185,18 +185,18 @@ export class PublicChatPanel extends MessagePanel {
|
||||
async handleDeleteMessage(id: number): Promise<void> {
|
||||
// Remove message immediately from UI
|
||||
this.deleteMessageImmediately(id);
|
||||
|
||||
|
||||
// Fire and forget server deletion; UI already updated
|
||||
await request({
|
||||
type: "deleteMessage",
|
||||
data: { message_id: id },
|
||||
credentials: {
|
||||
scheme: "Bearer",
|
||||
credentials: this.currentUser.authToken!
|
||||
credentials: {
|
||||
scheme: "Bearer",
|
||||
credentials: this.currentUser.authToken!
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async getProfile(): Promise<ProfileDialogData | null> {
|
||||
return {
|
||||
username: "Общий чат",
|
||||
|
||||
Reference in New Issue
Block a user