Skip to content

Commit

Permalink
feat: enable shortpolling for updating chat list
Browse files Browse the repository at this point in the history
  • Loading branch information
rasulov1337 committed Dec 17, 2024
1 parent d486a66 commit aaf21a3
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 65 deletions.
15 changes: 15 additions & 0 deletions src/components/ChatRecipientCard/ChatRecipientCard.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div
class='recipient-card'
data-id='{{author.id}}'
data-name='{{author.name}}'
id='{{id}}'
>
<img class='recipient-card__avatar' src='{{author.avatar}}' />
<div class='recipient-card__info'>
<p class='recipient-card__name'>{{author.name}}</p>
<p
class='recipient-card__text'
id='recipient-{{author.id}}-last-message'
>{{lastMessage}}</p>
</div>
</div>
70 changes: 70 additions & 0 deletions src/components/ChatRecipientCard/ChatRecipientCard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import ChatRepository from '../../repositories/ChatRepository';
import BaseComponent from '../BaseComponent/BaseComponent';
import ChatWindow from '../ChatWindow/ChatWindow';

export default class ChatRecipientCard extends BaseComponent {
private authorInfo: {
name: string;
id: string;
avatar: string;
};
private lastMessage: string;

constructor(
parent: HTMLElement,
id: string,
authorInfo: {
name: string;
id: string;
avatar: string;
},
lastMessage: string
) {
super({
parent: parent,
id: id,
templateName: 'ChatRecipientCard',
templateData: {
author: authorInfo,
lastMessage: lastMessage,
},
});

this.authorInfo = authorInfo;
this.lastMessage = lastMessage;
}

protected addEventListeners(): void {
this.thisElement.onclick = async () => {
// Remove active class from already selected chat list item
document
.querySelector('.recipient-card--active')
?.classList.remove('recipient-card--active');

this.thisElement.classList.add('recipient-card--active');

// Remove old Chat Window if present
document.getElementById('ChatWindow-0')?.remove();

// Create new Chat Window
const data = await ChatRepository.get(this.authorInfo.id);
const chatWindow = new ChatWindow(
document.getElementById('ChatPage-')!,
this.authorInfo.id,
this.authorInfo.name,
data
);

chatWindow.on('new-message', (message) => {
if (typeof message !== 'string') return;
(
document.getElementById(
`recipient-${this.authorInfo.id}-last-message`
) as HTMLElement
).textContent = message;
});

chatWindow.render();
};
}
}
6 changes: 1 addition & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ function renderMapPage(adId?: string) {
mapPage.render(pageContainer);
}

const renderArticlesPage = () => {};

const renderMessagesPage = () => {};

const renderFavoritesPage = () => {
const favouritePage = new FavouritePage();
favouritePage.render(pageContainer);
Expand Down Expand Up @@ -199,7 +195,7 @@ router.addRoute('/chats', async (params: URLSearchParams) => {
const recipientId = params.get('recipientId') as string;

const data = await ChatRepository.getAll();
const chatPage = new ChatPage(pageContainer, data, recipientId);
const chatPage = new ChatPage(pageContainer, data.chats, recipientId);
chatPage.render();
});

Expand Down
23 changes: 2 additions & 21 deletions src/pages/ChatPage/ChatPage.hbs
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
<div class='chat-page' id='{{id}}'>
<div class='recipients-list'>
{{#each chats}}
<div
class='recipient-card'
data-id='{{this.authorUuid}}'
data-name='{{this.authorName}}'
id='recipient-{{this.authorUuid}}'
>
<img
class='recipient-card__avatar'
src='{{this.authorAvatar}}'
/>
<div class='recipient-card__info'>
<p class='recipient-card__name'>{{this.authorName}}</p>
<p
class='recipient-card__text'
id='recipient-{{this.authorUuid}}-last-message'
>{{this.lastMessage}}</p>
</div>
</div>
{{/each}}
<div class='recipients-list' id='recipients-list'>
{{#each chats}}{{/each}}
</div>
</div>
85 changes: 46 additions & 39 deletions src/pages/ChatPage/ChatPage.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import BaseComponent from '../../components/BaseComponent/BaseComponent';
import ChatRecipientCard from '../../components/ChatRecipientCard/ChatRecipientCard';
import ChatWindow from '../../components/ChatWindow/ChatWindow';
import ApiClient from '../../modules/ApiClient';
import ChatRepository, { Chat } from '../../repositories/ChatRepository';

export default class ChatPage extends BaseComponent {
private chats: Chat[];

constructor(
parent: HTMLElement,
data: { chats: Chat[] },
chats: Chat[],
startChatWithRecipientId?: string
) {
super({
parent: parent,
id: '',
templateData: data,
templateData: { chats: chats },
templateName: 'ChatPage',
});

this.chats = chats;

if (!startChatWithRecipientId) return;

requestAnimationFrame(async () => {
Expand Down Expand Up @@ -47,46 +52,48 @@ export default class ChatPage extends BaseComponent {
});
}

protected addEventListeners(): void {
const cards = document.getElementsByClassName(
'recipient-card'
) as HTMLCollectionOf<HTMLElement>;
protected addEventListeners(): void {}

for (const el of cards) {
(el as HTMLElement).onclick = async (e) => {
this.handleCardClick(e, el);
};
}
protected afterRender(): void {
this.renderItems();

const id = setInterval(async () => {
const chats = (await ChatRepository.getAll()).chats;

// That means that we are not on ChatPage
if (!document.getElementById('recipients-list')) {
clearInterval(id);
return;
}

if (chats === this.chats) {
return;
}

this.chats = chats;
this.renderItems();
}, 5_000);
}

private async handleCardClick(e: Event, el: HTMLElement) {
// Remove active class from already selected chat list item
document
.querySelector('.recipient-card--active')
?.classList.remove('recipient-card--active');
el.classList.add('recipient-card--active');

// Remove old Chat Window if present
document.getElementById('ChatWindow-0')?.remove();

// Create new Chat Window
const data = await ChatRepository.get(el.dataset.id!);
const chatWindow = new ChatWindow(
this.thisElement,
el.dataset.id!,
el.dataset.name!,
data
);

chatWindow.on('new-message', (message) => {
if (typeof message !== 'string') return;
(
document.getElementById(
`recipient-${el.dataset.id}-last-message`
) as HTMLElement
).textContent = message;
});
private renderItems() {
const listEl = document.getElementById(
'recipients-list'
) as HTMLElement;

listEl.replaceChildren();

chatWindow.render();
for (const card of this.chats) {
const el = new ChatRecipientCard(
listEl,
card.authorUuid,
{
name: card.authorName,
id: card.authorUuid,
avatar: card.authorAvatar,
},
card.lastMessage
);
el.render();
}
}
}

0 comments on commit aaf21a3

Please sign in to comment.