Skip to content

Commit

Permalink
Merge pull request #22 from frontend-park-mail-ru/sending_messages
Browse files Browse the repository at this point in the history
Отправка сообщений
  • Loading branch information
oFem1m authored Apr 9, 2024
2 parents f8370e9 + 0027199 commit 282572d
Show file tree
Hide file tree
Showing 26 changed files with 388 additions and 157 deletions.
3 changes: 2 additions & 1 deletion src/Components/Chat/Chat.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
class='input_text chat-input'
type='text'
placeholder='Сообщение...'
autocomplete='off'
value='{{inputMessageValue}}'
/>
<button class='input_send chat-input' disabled>-></button>
<button class='input_send chat-input'>→</button>
</div>
</div>
</main>
15 changes: 14 additions & 1 deletion src/Components/Chat/Chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,20 @@ export default class Chat extends BaseComponent {

this.getParent()
.querySelector('#input_message')
.addEventListener('input', this.getConfig().inputMessaegHandler);
.addEventListener('input', this.getConfig().inputMessageHandler);

this.getParent()
.querySelector('#input_message')
.addEventListener('keydown', (event) => {
if (event.keyCode === 13) {
event.preventDefault();
this.getConfig().sendMessageHandler();
}
});

this.getParent()
.querySelector('.input_send')
.addEventListener('click', this.getConfig().sendMessageHandler);
}

setInputMessageValue(value) {
Expand Down
4 changes: 2 additions & 2 deletions src/Components/ChatList/ChatList.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export default class ChatList extends BaseComponent {
this.getParent()
.querySelector('#profile_btn')
.addEventListener('click', () => {
goToPage('/profile');
goToPage('/profile', true);
});
this.getParent()
.querySelector('#contacts_btn')
.addEventListener('click', () => {
goToPage('/contacts');
goToPage('/contacts', true);
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/Components/ChatListItem/ChatListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class ChatListItem extends BaseComponent {
.then((data) => {
if (data.status === 200) {
// Обработка успешной авторизации
goToPage('/chat');
goToPage('/chat', true);
} else {
throw new Error('Пришел не 200 статус');
}
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Contacts/Contacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class Contacts extends BaseComponent {
.querySelector('#backButton')
.addEventListener('click', () => {
// TODO: Возврат назад
goToPage('/chat');
goToPage('/chat', true);
});
}

Expand Down
7 changes: 5 additions & 2 deletions src/Components/Message/Message.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:root {
--message-color: var(--white);
--my-message-color: var(--green-light);
--my-message-color: var(--blue-light);
}

.message {
Expand All @@ -14,8 +14,11 @@
}

.my_message {
border-radius: var(--border-radius) var(--border-radius) 1px var(--border-radius);
border-radius: var(--border-radius) var(--border-radius) 1px var(--border-radius);
background-color: var(--my-message-color);
padding: 10px;
max-width: 75%;
margin-left: auto;
margin-right: 0;
margin-bottom: 5px;
}
2 changes: 1 addition & 1 deletion src/Components/Message/Message.hbs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div class="message">
<div class="{{message_owner}}">
{{message_text}}
</div>
6 changes: 3 additions & 3 deletions src/Components/Profile/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ export default class Profile extends BaseComponent {
.querySelector('#backButton')
.addEventListener('click', () => {
// TODO: Возврат назад
goToPage('/chat');
goToPage('/chat', true);
});
this.getParent()
.querySelector('#editButton')
.addEventListener('click', () => {
goToPage('/edit');
goToPage('/edit', true);
});
this.getParent()
.querySelector('#changePasswordButton')
.addEventListener('click', () => {
goToPage('/password');
goToPage('/password', true);
});
}
}
13 changes: 13 additions & 0 deletions src/Pages/BasePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class BasePage {
#parent;

constructor(parent) {
this.#parent = parent;
}

render() {
throw new Error('Метод render не определен');
}

async getData() {}
}
7 changes: 5 additions & 2 deletions src/Pages/ChangePasswordPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import Form from '../Components/Form/Form.js';
import { validatePassword } from '../utils/valid.js';
import { ProfileAPI } from '../utils/API/ProfileAPI.js';
import { goToPage } from '../utils/router.js';
import { BasePage } from './BasePage.js';

/**
* Рендерит страницу изменения пароля
* @class Класс страницы изменения пароля
*/
export default class ChangePasswordPage {
export default class ChangePasswordPage extends BasePage {
#parent;

constructor(parent) {
super(parent);
this.#parent = parent;
this.render();
}

formCallback(event) {
Expand Down Expand Up @@ -57,7 +60,7 @@ export default class ChangePasswordPage {
header: 'Изменение пароля',
onSubmit: this.formCallback,
onAdditionButtonClick: () => {
goToPage('/profile');
goToPage('/profile', true);
},
inputs: [
{
Expand Down
159 changes: 114 additions & 45 deletions src/Pages/ChatPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,58 @@ import Chat from '../Components/Chat/Chat.js';
import ChatList from '../Components/ChatList/ChatList.js';
import Message from '../Components/Message/Message.js';
import { ProfileAPI } from '../utils/API/ProfileAPI.js';
import { websocketManager } from '../utils/WebSocket.js';
import { sanitizer } from '../utils/valid.js';
import { BasePage } from './BasePage.js';

/**
/*
* Рендерит страницу чатов
* @class Класс страницы чатов
*/
export default class ChatPage {
export default class ChatPage extends BasePage {
#parent;
#chat;
#chatList;
#messageDrafts = {};
#currentChatId;
#profile;
#chats;

constructor(parent, urlParams) {
super(parent);
this.#parent = parent;
this.#currentChatId = parseInt(urlParams.get('id'));
websocketManager.connect();
websocketManager.setMessageHandler(this.handleWebSocketMessage);
this.getData().then(() => this.render());
}

getData = async () => {
try {
const chatAPI = new ChatAPI();
const profileAPI = new ProfileAPI();

const [chatsResponse, profileResponse] = await Promise.all([
chatAPI.getChats(),
profileAPI.getProfile(),
]);

this.#chats = chatsResponse.body.chats;
if (profileResponse.status !== 200) {
throw new Error('Пришел не 200 статус');
}
this.#profile = profileResponse.body.user;

return {
chats: this.#chats,
profile: this.#profile,
};
} catch (error) {
console.error('Ошибка при получении данных:', error);
throw error;
}
};

render() {
const wrapper = document.createElement('div');
wrapper.classList = 'full-screen';
Expand All @@ -30,61 +65,88 @@ export default class ChatPage {
logoutHandler: this.handleLogout,
});
this.#chatList.render();
this.#chatList.setUserName(`${this.#profile.username}`);

this.#chat = new Chat(wrapper, {
inputMessaegHandler: this.messageDraftHandler,
inputMessageHandler: this.messageDraftHandler,
sendMessageHandler: this.messageSendHandler,
});
this.#chat.render();

this.#parent.appendChild(wrapper);
this.displayChats(this.#chats);
}

const chatAPI = new ChatAPI();
if (this.#currentChatId) {
chatAPI.chatById(this.#currentChatId).then((response) => {
if (response.status === 200) {
this.displayActiveChat(response.body.chat);
} else {
goToPage('/chat');
this.#currentChatId = null;
}
});
messageDraftHandler = (event) => {
this.#messageDrafts[this.#currentChatId] = event.target.value;
};

messageSendHandler = () => {
// Контейнер активного чата
const inputMessage = this.#parent
.querySelector('#input_message')
.value.trim();
const urlParams = new URLSearchParams(window.location.search);
const chatId = parseInt(urlParams.get('id'));
if (inputMessage && chatId) {
// Проверяем, что есть сообщение и ID чата
const sanitizedInputMessage = sanitizer(inputMessage);
websocketManager.sendMessage(chatId, sanitizedInputMessage);
document.querySelector('#input_message').value = '';
} else {
console.error('Нет текста сообщения или ID чата.');
}
chatAPI
.getChats()
.then((response) => {
response.body.chats.forEach((chatConfig) => {
this.#chatList.addChat(chatConfig, () => {
this.#chat.setInputMessageValue(
this.#messageDrafts[chatConfig.id] || '',
);
this.displayActiveChat(chatConfig);
goToPage('/chat?id=' + chatConfig.id);
});
});
})
.catch((error) => {
console.error('Ошибка при получении чатов:', error);
};

handleWebSocketMessage = (message) => {
const chatIndex = this.#chats.findIndex(
(chat) => chat.id === message.chat_id,
);
if (chatIndex !== -1) {
const chat = this.#chats.splice(chatIndex, 1)[0];
this.#chats.unshift(chat);
const activeChatContainer = document.getElementById(
'active-chat-container',
);
const owner =
message.user_id === this.#profile.id ? 'my_message' : 'message';
const messageElement = new Message(activeChatContainer, {
message_owner: owner,
message_text: message.message_text,
});
messageElement.render();
this.#chats[0].messages.push(message); // Добавляем сообщение в начало массива сообщений
this.displayChats(this.#chats); // Обновляем отображение чатов
}
};

const profileAPI = new ProfileAPI();
profileAPI
.getProfile()
.then((response) => {
if (response.status !== 200) {
throw new Error('Пришел не 200 статус');
}
const profile = response.body.user;
this.#chatList.setUserName(`${profile.username}`);
})
.catch((error) => {
console.error('Ошибка при получении профиля:', error);
displayChats(chats) {
const chatListContainer = document.getElementById(
'chat-list-container',
);
chatListContainer.innerHTML = '';
let checkChatId = false;
chats.forEach((chatConfig) => {
if (chatConfig.id === this.#currentChatId) {
checkChatId = true;
this.displayActiveChat(chatConfig);
}
this.#chatList.addChat(chatConfig, () => {
this.#chat.setInputMessageValue(
this.#messageDrafts[chatConfig.id] || '',
);
this.displayActiveChat(chatConfig);
this.#currentChatId = chatConfig.id;
goToPage('/chat?id=' + chatConfig.id, false);
});
});
this.#messageDrafts[this.#currentChatId] = '';
if (!checkChatId && !isNaN(this.#currentChatId)) {
goToPage('/chat', false);
this.#currentChatId = null;
}
}

messageDraftHandler = (event) => {
this.#messageDrafts[this.#currentChatId] = event.target.value;
};

displayActiveChat(chat) {
// Очищаем контейнер активного чата
const activeChatContainer = document.getElementById(
Expand Down Expand Up @@ -114,7 +176,13 @@ export default class ChatPage {

// Отображаем сообщения в чате
chat.messages.forEach((message) => {
// Если сообщение от акитивного юзера, то
let owner = 'message';
if (this.#profile.id === message.user_id) {
owner = 'my_message';
}
const messageElement = new Message(activeChatContainer, {
message_owner: owner,
message_text: message.message_text,
});
messageElement.render();
Expand All @@ -130,7 +198,8 @@ export default class ChatPage {
if (data.status === 200) {
// Обработка успешной авторизации
console.log('Successfully logged out');
goToPage('/login');
websocketManager.close();
goToPage('/login', true);
} else {
console.log('Error logged out');
}
Expand Down
Loading

0 comments on commit 282572d

Please sign in to comment.