/** * postDetailModal.js * Модуль для открытия деталей поста в модальном окне * Полностью переработанная версия */ (function() { 'use strict'; // Константы const INITIAL_COMMENTS_COUNT = 10; const DEBUG = false; // Отключаем - всё работает // Состояние let modal = null; let modalElement = null; let currentPost = null; /** * Инициализация */ function initPostDetailModal() { modalElement = document.getElementById('postDetailModal'); if (!modalElement) { console.warn('postDetailModal: элемент #postDetailModal не найден'); return; } modal = new bootstrap.Modal(modalElement); modalElement.addEventListener('hidden.bs.modal', function() { const contentDiv = document.getElementById('postDetailContent'); if (contentDiv) { contentDiv.innerHTML = `
Загрузка...
`; } currentPost = null; }); attachPostLinkHandlers(); } /** * Утилиты для работы с cookies */ function getCsrfToken() { const cookies = document.cookie.split(';'); for (let cookie of cookies) { const [name, value] = cookie.trim().split('='); if (name === 'csrftoken') { return decodeURIComponent(value); } } return null; } function getAccessToken() { const cookies = document.cookie.split(';'); for (let cookie of cookies) { const [name, value] = cookie.trim().split('='); if (name === 'access_token') { return decodeURIComponent(value); } } return null; } /** * Утилиты */ function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function getCurrentUserId() { // Получаем ID текущего пользователя из meta-тега const meta = document.querySelector('meta[name="user-id"]'); if (meta) { const userId = meta.getAttribute('content'); return userId ? parseInt(userId) : null; } return null; } function getAuthorId(authorObj) { if (!authorObj) return null; // API возвращает author.id return authorObj.id || null; } function formatDate(dateString) { const date = new Date(dateString); const now = new Date(); const diff = now - date; const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) { return 'Сегодня, ' + date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); } else if (days === 1) { return 'Вчера, ' + date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); } else if (days < 7) { return days + ' дн. назад'; } else { return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' }); } } function formatBody(text) { return text.replace(/\n/g, '
'); } function pluralizeComments(count) { const cases = [2, 0, 1, 1, 1, 2]; const titles = ['комментарий', 'комментария', 'комментариев']; return titles[(count % 100 > 4 && count % 100 < 20) ? 2 : cases[(count % 10 < 5) ? count % 10 : 5]]; } /** * Загрузка поста */ async function loadPostDetail(postId) { const accessToken = getAccessToken(); const headers = { 'Accept': 'application/json' }; if (accessToken) { headers['Authorization'] = `Bearer ${accessToken}`; } try { const response = await fetch(`/api/v1/posts/${postId}/`, { method: 'GET', headers: headers }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const post = await response.json(); if (DEBUG) { console.log('=== POST DEBUG ==='); console.log('🙋 Current User ID:', getCurrentUserId()); console.log('📝 Post:', post); console.log('👤 Post author:', post.author); console.log('🆔 Post author ID:', getAuthorId(post.author), typeof getAuthorId(post.author)); if (post.comments && post.comments.length > 0) { console.log('\n=== ALL COMMENTS DEBUG ==='); console.table(post.comments.map(c => ({ id: c.id, author_name: c.author?.full_name, author_id: c.author?.id, is_me: c.author?.id === getCurrentUserId() ? '✅ МОЙ' : '❌ чужой', text: c.text.substring(0, 30) }))); } console.log('==================\n'); } currentPost = post; renderPostDetail(post); } catch (error) { console.error('Ошибка загрузки поста:', error); showError('Не удалось загрузить пост'); } } /** * Рендеринг */ function renderPostDetail(post) { const contentDiv = document.getElementById('postDetailContent'); const postAuthorId = getAuthorId(post.author); if (DEBUG) { console.log('Rendering with postAuthorId:', postAuthorId); } let html = ''; html += '
'; html += renderPostHeader(post); if (post.image) { html += `
${escapeHtml(post.title || 'Публикация')}
`; } html += '
'; html += `

${escapeHtml(post.title || 'Без названия')}

`; if (post.body) { html += `
${formatBody(post.body)}
`; } html += '
'; html += renderPostFooter(post); html += renderCommentsSection(post, postAuthorId); html += '
'; contentDiv.innerHTML = html; if (post.comments && post.comments.length > 0) { contentDiv.dataset.allComments = JSON.stringify(post.comments); contentDiv.dataset.postAuthorId = postAuthorId || ''; } scrollToBottom(); attachLikeHandlers(); attachLoadMoreCommentsHandler(); attachCommentFormHandler(); } function renderPostHeader(post) { let html = '
'; html += '
'; if (post.author && post.author.avatar) { html += ``; } else { html += ''; } html += '
'; html += '
'; html += `
${escapeHtml(post.author?.full_name || 'Аноним')}
`; html += ``; html += '
'; if (post.pinned) { html += ''; } html += '
'; return html; } function renderPostFooter(post) { let html = ''; return html; } function renderCommentsSection(post, postAuthorId) { let html = '
'; if (post.comments && post.comments.length > 0) { html += '
'; html += '
'; html += '
'; html += ''; html += '
Комментарии
'; html += `(${post.comments.length})`; html += '
'; if (post.comments.length > INITIAL_COMMENTS_COUNT) { const remainingCount = post.comments.length - INITIAL_COMMENTS_COUNT; html += `'; } html += '
'; const visibleComments = post.comments.slice(-INITIAL_COMMENTS_COUNT); visibleComments.forEach(comment => { html += renderComment(comment, postAuthorId); }); html += '
'; html += '
'; } html += renderCommentForm(post.id); html += '
'; return html; } function renderComment(comment, postAuthorId) { // ВАЖНО: Отображаем справа комментарии ТЕКУЩЕГО пользователя (как в мессенджере) // НЕ автора поста, а автора комментария === текущий пользователь const currentUserId = getCurrentUserId(); const commentAuthorId = getAuthorId(comment.author); // Мой комментарий = справа, чужой = слева const isMyComment = (currentUserId !== null && commentAuthorId !== null && currentUserId === commentAuthorId); if (DEBUG) { console.log(`🔍 Comment #${comment.id} by ${comment.author?.full_name}:`, { 'currentUserId (ME)': currentUserId, 'commentAuthorId': commentAuthorId, 'isMyComment': isMyComment, 'CSS class': isMyComment ? 'comment-item--author (RIGHT ➡️)' : 'comment-item (LEFT ⬅️)' }); } const commentClass = isMyComment ? 'comment-item comment-item--author' : 'comment-item'; let html = `
`; html += '
'; const authorName = comment.author?.full_name || 'Аноним'; const authorId = getAuthorId(comment.author); if (authorId) { html += `${escapeHtml(authorName)}`; } else { html += `${escapeHtml(authorName)}`; } html += '·'; html += ``; html += '
'; html += `
${formatBody(comment.text)}
`; html += '
'; return html; } function renderCommentForm(postId) { let html = '
'; html += '
'; html += `
`; html += '
'; html += '