using System; using System.Data; using System.Drawing; using System.Windows.Forms; namespace Neshina1703 { public partial class MessengerForm : Form { private int currentEmployeeId; private int? currentConversationId; private System.Windows.Forms.Timer refreshTimer; public MessengerForm(int employeeId) { InitializeComponent(); this.currentEmployeeId = employeeId; SetupTimer(); } private void SetupTimer() { refreshTimer = new System.Windows.Forms.Timer(); refreshTimer.Interval = 5000; refreshTimer.Tick += RefreshTimer_Tick; refreshTimer.Start(); } private void RefreshTimer_Tick(object sender, EventArgs e) { LoadConversations(); if (currentConversationId.HasValue) LoadMessages(); } private void MessengerForm_Load(object sender, EventArgs e) { LoadConversations(); LoadEmployees(); } private void LoadConversations() { var conversations = MessageHelper.GetConversationsForEmployee(currentEmployeeId); dgvConversations.DataSource = conversations; if (dgvConversations.Columns.Count > 0) { if (dgvConversations.Columns["id"] != null) dgvConversations.Columns["id"].Visible = false; if (dgvConversations.Columns["other_employee_id"] != null) dgvConversations.Columns["other_employee_id"].Visible = false; if (dgvConversations.Columns["updated_at"] != null) dgvConversations.Columns["updated_at"].Visible = false; if (dgvConversations.Columns["other_employee_name"] != null) { dgvConversations.Columns["other_employee_name"].HeaderText = "Собеседник"; dgvConversations.Columns["other_employee_name"].Width = 120; } if (dgvConversations.Columns["last_message"] != null) { dgvConversations.Columns["last_message"].HeaderText = "Последнее сообщение"; dgvConversations.Columns["last_message"].Width = 100; } if (dgvConversations.Columns["unread_count"] != null) { dgvConversations.Columns["unread_count"].HeaderText = "🔔"; dgvConversations.Columns["unread_count"].Width = 50; } } dgvConversations.ClearSelection(); if (currentConversationId.HasValue) { foreach (DataGridViewRow row in dgvConversations.Rows) { if (row.Cells["id"] != null && row.Cells["id"].Value != null) { if (Convert.ToInt32(row.Cells["id"].Value) == currentConversationId.Value) { row.Selected = true; break; } } } } } private void LoadEmployees() { var employees = MessageHelper.GetAllEmployeesExcept(currentEmployeeId); cbEmployees.DataSource = employees; cbEmployees.DisplayMember = "full_name"; cbEmployees.ValueMember = "id"; cbEmployees.SelectedIndex = -1; } private void LoadMessages() { if (!currentConversationId.HasValue) return; var messages = MessageHelper.GetMessages(currentConversationId.Value); flowMessages.Controls.Clear(); foreach (DataRow row in messages.Rows) { int senderId = Convert.ToInt32(row["sender_id"]); string messageText = row["message_text"].ToString(); DateTime sentAt = Convert.ToDateTime(row["sent_at"]); bool isMyMessage = senderId == currentEmployeeId; var bubble = CreateMessageBubble(messageText, sentAt, isMyMessage); flowMessages.Controls.Add(bubble); } flowMessages.ScrollControlIntoView(flowMessages.Controls[flowMessages.Controls.Count - 1]); MessageHelper.MarkMessagesAsRead(currentConversationId.Value, currentEmployeeId); } private Panel CreateMessageBubble(string text, DateTime sentAt, bool isMyMessage) { var bubble = new Panel { AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Margin = new Padding(5), MaximumSize = new Size(400, 0), BackColor = isMyMessage ? Color.FromArgb(91, 209, 45) : Color.FromArgb(176, 253, 161), Padding = new Padding(10), Cursor = Cursors.Default }; var labelText = new Label { Text = text, AutoSize = false, MaximumSize = new Size(380, 0), ForeColor = Color.Black, BackColor = Color.Transparent, Dock = DockStyle.Top, Padding = new Padding(5) }; labelText.Size = new Size(380, labelText.PreferredHeight); var labelTime = new Label { Text = sentAt.ToString("HH:mm"), AutoSize = true, ForeColor = Color.Black, BackColor = Color.Transparent, Dock = DockStyle.Bottom, Font = new Font("Microsoft Sans Serif", 7F), Padding = new Padding(5, 0, 5, 0) }; bubble.Controls.Add(labelText); bubble.Controls.Add(labelTime); if (isMyMessage) { bubble.Dock = DockStyle.Right; } else { bubble.Dock = DockStyle.Left; } return bubble; } private void dgvConversations_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0) { var row = dgvConversations.Rows[e.RowIndex]; if (row.Cells["id"] != null && row.Cells["id"].Value != null) { currentConversationId = Convert.ToInt32(row.Cells["id"].Value); lblCurrentChat.Text = "Чат с: " + row.Cells["other_employee_name"].Value.ToString(); LoadMessages(); } } } private void btnSend_Click(object sender, EventArgs e) { SendMessage(); } private void txtMessage_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter && !e.Shift) { e.SuppressKeyPress = true; SendMessage(); } } private void SendMessage() { if (!currentConversationId.HasValue) { MessageBox.Show("Выберите чат для отправки сообщения!", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string text = txtMessage.Text.Trim(); if (string.IsNullOrEmpty(text)) return; MessageHelper.SendMessage(currentConversationId.Value, currentEmployeeId, text); txtMessage.Clear(); LoadMessages(); } private void btnStartChat_Click(object sender, EventArgs e) { if (cbEmployees.SelectedValue == null) { MessageBox.Show("Выберите сотрудника для чата!", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } int selectedEmployeeId = Convert.ToInt32(cbEmployees.SelectedValue); int? conversationId = MessageHelper.GetExistingConversation(currentEmployeeId, selectedEmployeeId); if (!conversationId.HasValue) { conversationId = MessageHelper.CreateConversation(currentEmployeeId, selectedEmployeeId); } currentConversationId = conversationId; LoadConversations(); foreach (DataGridViewRow row in dgvConversations.Rows) { if (row.Cells["id"] != null && row.Cells["id"].Value != null && Convert.ToInt32(row.Cells["id"].Value) == conversationId.Value) { dgvConversations.ClearSelection(); row.Selected = true; dgvConversations_CellClick(dgvConversations, new DataGridViewCellEventArgs(0, row.Index)); break; } } } private void MessengerForm_FormClosing(object sender, FormClosingEventArgs e) { refreshTimer?.Stop(); refreshTimer?.Dispose(); } } }