Skip to content

Commit

Permalink
✔️ Сборка #11
Browse files Browse the repository at this point in the history
  • Loading branch information
Keks committed Dec 18, 2024
1 parent 61f96f9 commit bea80c7
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 176 deletions.
13 changes: 13 additions & 0 deletions 11/js/comment-creator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const commentTemplateElement = document.querySelector('.social__comment');

const createCommentTemplateElement = ({ avatar, message, name }) => {
const newCommentTemplateElement = commentTemplateElement.cloneNode(true);
const socialPictureElement = newCommentTemplateElement.querySelector('.social__picture');
const socialTextElement = newCommentTemplateElement.querySelector('.social__text');
socialPictureElement.src = avatar;
socialPictureElement.alt = name;
socialTextElement.textContent = message;
return newCommentTemplateElement;
};

export { createCommentTemplateElement };
39 changes: 39 additions & 0 deletions 11/js/comments-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createCommentTemplateElement } from './comment-creator.js';
const COMMENTS_LOAD_STEP = 5; // Количество комментариев, которые показываются за один раз

const bigPictureSocialElement = document.querySelector('.big-picture__social');

const socialCommentCountElement = bigPictureSocialElement.querySelector('.social__comment-shown-count');
const socialCommentTotalCountElement = bigPictureSocialElement.querySelector('.social__comment-total-count');
const commentsContainerElement = bigPictureSocialElement.querySelector('.social__comments');
const commentsLoaderElement = bigPictureSocialElement.querySelector('.comments-loader');


// Переменные для хранения текущих комментариев
let currentComments = [];
let displayedCommentsCount = 0;

// Функция рендера комментариев порциями
const renderComments = () => {
const remainingComments = currentComments.slice(displayedCommentsCount, displayedCommentsCount + COMMENTS_LOAD_STEP); // Выделяем из массива комментариев группу из COMMENTS_LOAD_STEP комментов для подгрузки
const commentsFragment = document.createDocumentFragment(); // Создаем фрагмент для подгрузки
remainingComments.forEach((comment) => { // Добавляем новую порцию комментариев
commentsFragment.append(createCommentTemplateElement(comment)); // Прогоняем каждый элемент через функцию создания комментария и добавляем во фрагмент
});
commentsContainerElement.append(commentsFragment); // Добавляем фрагмент в конец контейнера
displayedCommentsCount += remainingComments.length; // Обновляем счетчик показанных комментариев
commentsLoaderElement.classList.toggle('hidden', displayedCommentsCount >= currentComments.length);
socialCommentCountElement.textContent = displayedCommentsCount;
socialCommentTotalCountElement.textContent = currentComments.length;
};

// Функция инициализации загрузки комментариев
const initComments = (comments) => {
currentComments = comments; // Сохраняем все комментарии
displayedCommentsCount = 0; // Сбрасываем счетчик показанных комментариев
commentsContainerElement.innerHTML = ''; // Очищаем контейнер комментариев
renderComments(); // Первичная загрузка комментариев
commentsLoaderElement.addEventListener('click', renderComments);
};

export { initComments };
87 changes: 39 additions & 48 deletions 11/js/data.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
getRandomInt,
getRandomUniqueInt,
getRandomArrElement
} from './util.js';
import { getRandomInt, getRandomUniqueInt, getRandomArrElement } from './util.js';

const OBJECT_QTY = 25;

Expand Down Expand Up @@ -42,47 +38,47 @@ const AvatarRange = {
};

const DESCRIPTION = [
"Закат на берегу моря",
"Старинная улочка европейского города",
"Котенок спит на кровати",
"Заснеженные склоны Хибин",
"Букет цветов на столе",
"Велосипед пристегнутый на велопарковке",
"Чашка горячего кофе",
"Осенний парк с опавшей листвой",
"Маяк на скалистом берегу",
"Шмель на цветке",
"Деревенский домик в глухом лесу",
"Отражение звезд на поверхности Ладоги",
"Птенцы в гнезде",
"Радуга над зеленым полем после дождя",
"Следы на песчаном пляже",
'Закат на берегу моря',
'Старинная улочка европейского города',
'Котенок спит на кровати',
'Заснеженные склоны Хибин',
'Букет цветов на столе',
'Велосипед пристегнутый на велопарковке',
'Чашка горячего кофе',
'Осенний парк с опавшей листвой',
'Маяк на скалистом берегу',
'Шмель на цветке',
'Деревенский домик в глухом лесу',
'Отражение звезд на поверхности Ладоги',
'Птенцы в гнезде',
'Радуга над зеленым полем после дождя',
'Следы на песчаном пляже',
];

const MESSAGE = [
"Всё отлично!",
"В целом всё неплохо. Но не всё.",
"Когда вы делаете фотографию, хорошо бы убирать палец из кадра. В конце концов это просто непрофессионально.",
"Моя бабушка случайно чихнула с фотоаппаратом в руках и у неё получилась фотография лучше.",
"Я поскользнулся на банановой кожуре и уронил фотоаппарат на кота и у меня получилась фотография лучше.",
"Лица у людей на фотке перекошены, как будто их избивают. Как можно было поймать такой неудачный момент?!",
'Всё отлично!',
'В целом всё неплохо. Но не всё.',
'Когда вы делаете фотографию, хорошо бы убирать палец из кадра. В конце концов это просто непрофессионально.',
'Моя бабушка случайно чихнула с фотоаппаратом в руках и у неё получилась фотография лучше.',
'Я поскользнулся на банановой кожуре и уронил фотоаппарат на кота и у меня получилась фотография лучше.',
'Лица у людей на фотке перекошены, как будто их избивают. Как можно было поймать такой неудачный момент?!',
];

const AUTHOR_NAME = [
"Довакин",
"Алдуин",
"Шеппард",
"Геральт",
"Супер Марио",
"Соник",
"Кратос",
"Солид Снейк",
"Клод Страйф",
"Лара Крофт",
"Наруто",
"Элли",
"Джоель",
"Сэм Фишер",
'Довакин',
'Алдуин',
'Шеппард',
'Геральт',
'Супер Марио',
'Соник',
'Кратос',
'Солид Снейк',
'Клод Страйф',
'Лара Крофт',
'Наруто',
'Элли',
'Джоель',
'Сэм Фишер',
];

const getPhotoId = getRandomUniqueInt(IdPhotoRange.MIN, IdPhotoRange.MAX);
Expand All @@ -101,16 +97,13 @@ const createComment = () => {
return {
id: getMessageId(),
avatar: `img/avatar-${getRandomInt(AvatarRange.MIN, AvatarRange.MAX)}.svg`,
message: messagesQty.join(" "),
message: messagesQty.join(' '),
name: getRandomArrElement(AUTHOR_NAME),
};
};

const generateObj = () => {
const comments = Array.from(
{ length: getRandomInt(CommentsRange.MIN, CommentsRange.MAX) },
createComment
);
const comments = Array.from({ length: getRandomInt(CommentsRange.MIN, CommentsRange.MAX) }, createComment);
return {
id: getPhotoId(),
url: `photos/${getRandomUrl()}.jpg`,
Expand All @@ -122,6 +115,4 @@ const generateObj = () => {

const generateArrObj = () => Array.from({ length: OBJECT_QTY }, generateObj);

export {
generateArrObj
};
export { generateArrObj };
22 changes: 11 additions & 11 deletions 11/js/functions.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const isWithinWorkingHours = (workdayStart, workdayEnd, meetingStart, meetingLength) => {
const convertToMinutes = (timeString) => {
const [hours, minutes] = timeString.split(':');
return (Number(hours) * 60) + Number(minutes)
};
const workdayStartMinutes = convertToMinutes(workdayStart);
const workdayEndMinutes = convertToMinutes(workdayEnd);
const meetingStartMinutes = convertToMinutes(meetingStart);
const meetingEndMinutes = meetingStartMinutes + meetingLength;
return meetingStartMinutes >= workdayStartMinutes && meetingEndMinutes <= workdayEndMinutes
};
// const isWithinWorkingHours = (workdayStart, workdayEnd, meetingStart, meetingLength) => {
// const convertToMinutes = (timeString) => {
// const [hours, minutes] = timeString.split(':');
// return (Number(hours) * 60) + Number(minutes)
// };
// const workdayStartMinutes = convertToMinutes(workdayStart);
// const workdayEndMinutes = convertToMinutes(workdayEnd);
// const meetingStartMinutes = convertToMinutes(meetingStart);
// const meetingEndMinutes = meetingStartMinutes + meetingLength;
// return meetingStartMinutes >= workdayStartMinutes && meetingEndMinutes <= workdayEndMinutes
// };

// console.log(isWithinWorkingHours('08:00', '17:30', '14:00', 90));
// console.log(isWithinWorkingHours('8:0', '10:0', '8:0', 120));
Expand Down
4 changes: 1 addition & 3 deletions 11/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ import { setupPictureEventListeners } from './photo-modal.js';

const photoCollection = generateArrObj();
renderGallery(photoCollection);
setupPictureEventListeners (photoCollection);


setupPictureEventListeners(photoCollection);
139 changes: 44 additions & 95 deletions 11/js/photo-modal.js
Original file line number Diff line number Diff line change
@@ -1,122 +1,71 @@
import { isEscapeKey } from './util.js';
import { initComments } from './comments-loader.js';

const picturesContainerElement = document.querySelector('.pictures');
const socialCommentCountElement = document.querySelector('.social__comment-shown-count');
const socialCommentTotalCountElement = document.querySelector('.social__comment-total-count');
const commentsLoaderElement = document.querySelector('.comments-loader');
// Общий контейнер
const bodyContainerElement = document.body;
const bigPictureContainerElement = document.querySelector('.big-picture');
const bigPictureCloseButtonElement = bigPictureContainerElement.querySelector('.big-picture__cancel');
const bigPictureImageElement = bigPictureContainerElement.querySelector('img');
const bigPictureLikesElement = bigPictureContainerElement.querySelector('.likes-count');
const bigPictureDescriptionElement = bigPictureContainerElement.querySelector('.social__caption');
const commentsQuantityElement = bigPictureContainerElement.querySelector('.social__comment-total-count');
const commentsContainerElement = bigPictureContainerElement.querySelector('.social__comments');
const commentTemplateElement = document.querySelector('.social__comment');

const COMMENTS_STEP = 5; // Количество комментариев, которые показываются за один раз
// Контейнер с картинками
const picturesContainerElement = document.querySelector('.pictures');

// Функция добавления обработчика событий на контейнер с картинками и вычисление ID картинки, по которой был клик
const setupPictureEventListeners = (photoCollection) => {
picturesContainerElement.addEventListener('click', (evt) => {
const currentEventPictureId = evt.target.closest('.picture').dataset.pictureId;
if (currentEventPictureId) {
const foundedPhoto = photoCollection.find((picture) => picture.id === Number(currentEventPictureId));
renderBigPicture(foundedPhoto);
}
});
};
// Элементы большой картинки
const bigPictureContainerElement = document.querySelector('.big-picture');
const bigPictureOverlayElement = document.querySelector('.overlay');
const bigPictureCloseButtonElement = bigPictureContainerElement.querySelector('.big-picture__cancel');
const bigPictureImageElement = bigPictureContainerElement.querySelector('.big-picture__img img');
const bigPictureSocialElement = bigPictureContainerElement.querySelector('.big-picture__social');
const bigPictureLikesElement = bigPictureSocialElement.querySelector('.likes-count');
const bigPictureDescriptionElement = bigPictureSocialElement.querySelector('.social__caption');

// Рендер большой картинки
const renderBigPicture = ({ url, likes, comments, description }) => {
bigPictureImageElement.src = url;
bigPictureLikesElement.textContent = likes;
commentsQuantityElement.textContent = comments.length;
bigPictureDescriptionElement.textContent = description;
attachBigPictureListeners(); // Вешаем обработчик событий
initComments(comments); // Инициализируем комментарии
toggleVisibility(true); // Переключатель видимости
};

// добавление обработчиков события на кнопку закрытия и эскейп
const attachBigPictureListeners = () => {
bigPictureCloseButtonElement.addEventListener('click', onClickCloseButton);
bigPictureOverlayElement.addEventListener('click', onOverlayClick);
document.addEventListener('keydown', onKeydownDocument);
initComments(comments); // Инициализируем комментарии
bigPictureContainerElement.classList.remove('hidden'); // включаем видимость контейнера большой картинки
bodyContainerElement.classList.add('modal-open'); // блокируем прокрутку body
};

// Переменные для хранения текущих комментариев
let currentComments = [];
let displayedCommentsCount = 0;

// Функция инициализации загрузки комментариев
const initComments = (comments) => {
currentComments = comments; // Сохраняем все комментарии
displayedCommentsCount = 0; // Сбрасываем счетчик показанных комментариев
commentsContainerElement.innerHTML = ''; // Очищаем контейнер комментариев
commentsLoaderElement.addEventListener('click', renderComments); // Добавляем обработчик кнопки "Загрузить еще"
renderComments(); // Первичная загрузка комментариев
};

// Функция рендера комментариев порциями
const renderComments = () => {
const remainingComments = currentComments.slice(displayedCommentsCount, displayedCommentsCount + COMMENTS_STEP); // Выделяем из массива комментариев группу из COMMENTS_STEP комментов для подгрузки
const commentsFragment = document.createDocumentFragment(); // Создаем фрагмент для подгрузки
remainingComments.forEach(comment => { // Добавляем новую порцию комментариев
commentsFragment.append(createCommentTemplateElement(comment)); // Прогоняем каждый элемент через функцию создания комментария и добавляем во фрагмент
});
commentsContainerElement.append(commentsFragment); // Добавляем фрагмент в конец контейнера
displayedCommentsCount += remainingComments.length; // Обновляем счетчик показанных комментариев
updateCommentsLoaderElementVisibility(); // Обновляем видимость кнопки "Загрузить еще"
updateCommentCounter(); // Обновляем счетчик комментариев
};

// Функция создания элемента комментария
const createCommentTemplateElement = ({ avatar, message, name }) => {
const newCommentTemplateElement = commentTemplateElement.cloneNode(true);
const socialPictureElement = newCommentTemplateElement.querySelector('.social__picture');
const socialTextElement = newCommentTemplateElement.querySelector('.social__text');
socialPictureElement.src = avatar;
socialPictureElement.alt = name;
socialTextElement.textContent = message;
return newCommentTemplateElement;
};

// Функция обновления счетчика комментариев
const updateCommentCounter = () => {
socialCommentCountElement.textContent = displayedCommentsCount;
socialCommentTotalCountElement.textContent = currentComments.length;
};

// Функция обновления видимости кнопки "Загрузить еще"
const updateCommentsLoaderElementVisibility = () => {
commentsLoaderElement.classList.toggle('hidden', displayedCommentsCount >= currentComments.length);
};
// Вызов закрытия картинки нажатием на закрывающий элемент
function onClickCloseButton () {
closeBigPicture();
}

// Функция переключения видимости контейнера с картинкой и прокрутки
const toggleVisibility = (isOpen) => {
bigPictureContainerElement.classList.toggle('hidden', !isOpen);
bodyContainerElement.classList.toggle('modal-open', isOpen);
};
// Вызов закрытия картинки нажатием мимо модального окна
function onOverlayClick(evt) {
if (evt.target === bigPictureOverlayElement) {
closeBigPicture();
}
}

// Вызов закрытия картинки нажатием на эскейп
const onKeydownDocument = (evt) => {
// Вызов закрытия картинки нажатием на escape
function onKeydownDocument (evt) {
if (isEscapeKey(evt)) {
evt.preventDefault();
closeBigPicture();
}
};
}

// Вызов закрытия картинки нажатием на закрывающий элемент
const onClickCloseButton = () => {
closeBigPicture();
};

// Функция закрытия большой картинки, переключение видимостей, снятие обработчиков событий
const closeBigPicture = () => {
commentsLoaderElement.removeEventListener('click', renderComments);
function closeBigPicture () {
bigPictureCloseButtonElement.removeEventListener('click', onClickCloseButton);
bigPictureContainerElement.removeEventListener('click', onOverlayClick);
document.removeEventListener('keydown', onKeydownDocument);
toggleVisibility(false);
bigPictureContainerElement.classList.add('hidden');
bodyContainerElement.classList.remove('modal-open');
}

// Функция добавления обработчика событий на контейнер с картинками и вычисление ID картинки, по которой был клик
const setupPictureEventListeners = (photoCollection) => {
picturesContainerElement.addEventListener('click', (evt) => {
const id = evt.target.closest('.picture').dataset.pictureId; // поиск по установленному атрибуту data-set-id
if (id) {
const foundedPhoto = photoCollection.find((picture) => picture.id === Number(id));
renderBigPicture(foundedPhoto);
}
});
};

export { setupPictureEventListeners };
Loading

0 comments on commit bea80c7

Please sign in to comment.