Skip to content

Commit

Permalink
Merge pull request #11 from brazilets/module11-task1
Browse files Browse the repository at this point in the history
Надо подкачаться
  • Loading branch information
Lizunchik authored Mar 27, 2024
2 parents 16e53ca + 0ddb58a commit 7cd79cf
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 91 deletions.
27 changes: 27 additions & 0 deletions js/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const API_URL_BASE = 'https://31.javascript.htmlacademy.pro/kekstagram/data';
const API_URL_SEND = 'https://31.javascript.htmlacademy.pro/kekstagram/';

const getData = () =>
fetch(API_URL_BASE)
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Не удалось загрузить данные');
}
});

const sendData = (data) =>
fetch(API_URL_SEND, {
method: 'POST',
body: data,
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Не удалось отправить данные');
}
});

export { getData, sendData };
6 changes: 4 additions & 2 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { renderUsersPictures } from './thumbnails.js';
import { fetchDataAndRender } from './thumbnails.js';
import './api.js';
import './uploadForm.js';
import './slider.js';

renderUsersPictures();
fetchDataAndRender();
66 changes: 66 additions & 0 deletions js/slider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { imgPreview } from './uploadForm.js';

const effectLevelSlider = document.querySelector('.img-upload__effect-level');
const slider = document.querySelector('.effect-level__slider');
if (slider) {
noUiSlider.create(slider, {
start: [100],
step: 0.1,
range: {
'min': [0],
'max': [100]
},
format: {
to: function (value) {
return Number(value).toFixed(1);
},
from: function (value) {
return Number(value);
}
}
});

slider.noUiSlider.on('update', (values, handle) => {
const value = Number(values[handle]);
const effectLevelValue = document.querySelector('.effect-level__value');
effectLevelValue.value = value.toFixed(1);

const currentEffect = document.querySelector('input[name="effect"]:checked').value;

switch (currentEffect) {
case 'chrome':
imgPreview.style.filter = `grayscale(${(value / 100).toFixed(1)})`;
break;
case 'sepia':
imgPreview.style.filter = `sepia(${(value / 100).toFixed(1)})`;
break;
case 'marvin':
imgPreview.style.filter = `invert(${value.toFixed(1)}%)`;
break;
case 'phobos':
imgPreview.style.filter = `blur(${(value * 0.03).toFixed(1)}px)`;
break;
case 'heat':
imgPreview.style.filter = `brightness(${(1 + (value * 0.02)).toFixed(1)})`;
break;
default:
imgPreview.style.filter = 'none';
}
});

document.querySelector('.effects__list').addEventListener('change', (evt) => {
if (evt.target.value === 'none') {
effectLevelSlider.classList.add('hidden');
} else {
effectLevelSlider.classList.remove('hidden');
slider.noUiSlider.set(100);
}
});

window.addEventListener('load', () => {
const currentEffect = document.querySelector('input[name="effect"]:checked').value;
if (currentEffect === 'none') {
effectLevelSlider.classList.add('hidden');
}
});
}
22 changes: 17 additions & 5 deletions js/thumbnails.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { createPosts } from './data.js';
import { getData } from './api.js';
import { openBigPicture } from './fullSize.js';

const templateUserPicture = document.querySelector('#picture')
.content
.querySelector('.picture');

const usersPictures = createPosts();
let usersPictures = [];

const containerUsersPictures = document.querySelector('.pictures');

const renderUsersPictures = () => {
const renderUsersPictures = (pictures) => {
const usersPicturesFragment = document.createDocumentFragment();

usersPictures.forEach(({ url, description, likes, comments, id }) => {
pictures.forEach(({ url, description, likes, comments, id }) => {
const userPicture = templateUserPicture.cloneNode(true);
userPicture.querySelector('.picture__img').src = url;
userPicture.querySelector('.picture__img').alt = description;
Expand All @@ -32,4 +32,16 @@ const clearUsersPictures = () => {
containerUsersPictures.innerHTML = '';
};

export { renderUsersPictures, clearUsersPictures };
function fetchDataAndRender() {
getData().then((data) => {
usersPictures = data;
renderUsersPictures(usersPictures);
}).catch(() => {
const errorTemplate = document.querySelector('#data-error').content.cloneNode(true);
document.body.appendChild(errorTemplate);
setTimeout(() => {
document.body.removeChild(document.querySelector('. data-error'));
}, 5000);
});
}
export { renderUsersPictures, clearUsersPictures, fetchDataAndRender };
175 changes: 91 additions & 84 deletions js/uploadForm.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { sendData } from './api.js';

const imgUploadForm = document.querySelector('.img-upload__form');
const inputFile = document.querySelector('.img-upload__input');
const formOverlay = document.querySelector('.img-upload__overlay');
const cancelButton = document.querySelector('.img-upload__cancel');
const submitButton = imgUploadForm.querySelector('.img-upload__submit');
const hashtagInput = imgUploadForm.querySelector('.text__hashtags');
const commentInput = imgUploadForm.querySelector('.text__description');
const imgPreview = document.querySelector('.img-upload__preview img');

const pristine = new Pristine(imgUploadForm, {
classTo: 'img-upload__field-wrapper',
Expand All @@ -17,28 +20,30 @@ inputFile.addEventListener('change', () => {
document.body.classList.add('modal-open');
});

cancelButton.addEventListener('click', () => {
function closeButton() {
formOverlay.classList.add('hidden');
document.body.classList.remove('modal-open');
});
document.addEventListener('keydown', onEscKeyDown);

document.addEventListener('keydown', onEscKeyDown);
inputFile.value = '';
imgUploadForm.reset();
document.querySelector('.scale__control--value').value = `${100}%`;
document.querySelector('.img-upload__preview').style.transform = '';
imgPreview.style.transform = 'scale(1)';
document.querySelector('.effect-level__slider').noUiSlider.set(100);
document.querySelector('.img-upload__preview').style.filter = 'none';
document.querySelector('.img-upload__effect-level').classList.add('hidden');
}

cancelButton.addEventListener('click', () => {
formOverlay.classList.add('hidden');
document.body.classList.remove('modal-open');

inputFile.value = '';
const otherInputs = imgUploadForm.querySelectorAll('otherInput');
otherInputs.forEach((input) => {
input.value = '';
});
closeButton();
});

const scaleControlSmaller = document.querySelector('.scale__control--smaller');
const scaleControlBigger = document.querySelector('.scale__control--bigger');
const scaleControlValue = document.querySelector('.scale__control--value');
const imgPreview = document.querySelector('.img-upload__preview img');

scaleControlSmaller.addEventListener('click', () => {
let scaleValue = parseInt(scaleControlValue.value, 10);
Expand All @@ -58,7 +63,7 @@ scaleControlBigger.addEventListener('click', () => {
}
});

let message = 'Неверный формат хэштега.';
let hashtagErrorMessage = 'Неверный формат хэштега.';
pristine.addValidator(hashtagInput, (value) => {
if (!value) {
return true;
Expand All @@ -67,15 +72,15 @@ pristine.addValidator(hashtagInput, (value) => {
const hashtags = value.split(' ');

if (hashtags.length > 5) {
message = 'Слишком много хэштегов. Максимум 5.';
hashtagErrorMessage = 'Слишком много хэштегов. Максимум 5.';
return false;
}

const lowerCaseHashtags = hashtags.map((hashtag) => hashtag.toLowerCase());
const hashDuplicates = new Set(lowerCaseHashtags).size !== lowerCaseHashtags.length;

if (hashDuplicates) {
message = 'Хэштеги не должны повторяться.';
hashtagErrorMessage = 'Хэштеги не должны повторяться.';
return false;
}

Expand All @@ -85,21 +90,21 @@ pristine.addValidator(hashtagInput, (value) => {
return false;
}
if (!hashtag.startsWith('#')) {
message = 'Хэштег должен начинаться с символа #.';
hashtagErrorMessage = 'Хэштег должен начинаться с символа #.';
return false;
}
if (hashtag.length > 20) {
message = 'Хэштег не может быть длиннее 20 символов.';
hashtagErrorMessage = 'Хэштег не может быть длиннее 20 символов.';
return false;
}

if (/[^a-zа-яё0-9#]/i.test(hashtag)) {
message = 'Хэштег может содержать только буквы и цифры.';
hashtagErrorMessage = 'Хэштег может содержать только буквы и цифры.';
return false;
}
}
return true;
}, () => message, 2);
}, () => hashtagErrorMessage, 2);

hashtagInput.addEventListener('focus', () => {
document.removeEventListener('keydown', onEscKeyDown);
Expand Down Expand Up @@ -131,77 +136,79 @@ commentInput.addEventListener('keydown', (evt) => {
}
});

imgUploadForm.addEventListener('submit', (evt) => {
evt.preventDefault();
const successTemplate = document.querySelector('#success').content;
const successMessage = successTemplate.querySelector('.success').cloneNode(true);
const errorTemplate = document.querySelector('#error').content;
const errorMessage = errorTemplate.querySelector('.error').cloneNode(true);

submitButton.disabled = true;
function isEscapeKey(evt) {
return evt.key === 'Escape';
}

const isValid = pristine.validate();
function closeMessage(message, escKeydownHandler, clickHandler) {
message.remove();
document.removeEventListener('keydown', escKeydownHandler);
message.removeEventListener('click', clickHandler);
}

function onMessageEscKeydown(evt, closeHandler) {
if (isEscapeKey(evt)) {
closeHandler();
}
}

if (isValid) {
imgUploadForm.submit();
imgUploadForm.reset();
scaleControlValue.value = '100%';
imgPreview.style.transform = 'scale(1)';
imgPreview.style.filter = 'none';
function onMessageClick(evt, message, closeHandler) {
if (!evt.target.closest('.success__inner') || evt.target.closest('.success__button')) {
closeHandler();
}
}

imgUploadForm.addEventListener('submit', (evt) => {
const isValid = pristine.validate();
evt.preventDefault();
if (!isValid) {
return;
}
submitButton.disabled = false;
submitButton.disabled = true;
const formData = new FormData(imgUploadForm);
sendData(formData)
.then(() => {
formOverlay.classList.add('hidden');
document.body.classList.remove('modal-open');
document.body.appendChild(successMessage);
document.addEventListener('keydown', (evtKeydown) => onMessageEscKeydown(evtKeydown, () => closeMessage(successMessage, onMessageEscKeydown, onMessageClick)));
successMessage.addEventListener('click', (evtClick) => onMessageClick(evtClick, successMessage, () => closeMessage(successMessage, onMessageEscKeydown, onMessageClick)));
imgUploadForm.reset();
scaleControlValue.value = '100%';
imgPreview.style.transform = 'scale(1)';
imgPreview.style.filter = 'none';
document.querySelector('.effect-level__slider').noUiSlider.set(100);
})


.catch(() => {
document.body.appendChild(errorMessage);
document.addEventListener('keydown', (evtKeydown) => onMessageEscKeydown(evtKeydown, () => closeMessage(errorMessage, onMessageEscKeydown, onMessageClick)));

const errorButton = errorMessage.querySelector('.error__button');
errorButton.addEventListener('click', () => {
closeMessage(errorMessage, onMessageEscKeydown, onMessageClick);
});
errorMessage.addEventListener('click', (evtClick) => {
if (evtClick.target === errorMessage) {
closeMessage(errorMessage, onMessageEscKeydown, onMessageClick);
}
});

const errorText = errorMessage.querySelector('.error__inner');
errorText.addEventListener('click', (evtClick) => {
evtClick.stopPropagation();
});
})
.finally(() => {
submitButton.disabled = false;
});
});

const slider = document.querySelector('.effect-level__slider');
if (slider) {
noUiSlider.create(slider, {
start: [100],
step: 1,
range: {
'min': [0],
'max': [100]
}
});

slider.noUiSlider.on('update', (values, handle) => {
const value = values[handle];
const effectLevelValue = document.querySelector('.effect-level__value');
effectLevelValue.value = value;

const currentEffect = document.querySelector('input[name="effect"]:checked').value;

switch (currentEffect) {
case 'chrome':
imgPreview.style.filter = `grayscale(${value / 100})`;
break;
case 'sepia':
imgPreview.style.filter = `sepia(${value / 100})`;
break;
case 'marvin':
imgPreview.style.filter = `invert(${value}%)`;
break;
case 'phobos':
imgPreview.style.filter = `blur(${value * 0.03}px)`;
break;
case 'heat':
imgPreview.style.filter = `brightness(${1 + (value * 0.02)})`;
break;
default:
imgPreview.style.filter = 'none';
}
});

document.querySelector('.effects__list').addEventListener('change', (evt) => {
const effectLevelSlider = document.querySelector('.img-upload__effect-level');
if (evt.target.value === 'none') {
effectLevelSlider.classList.add('hidden');
} else {
effectLevelSlider.classList.remove('hidden');
slider.noUiSlider.set(100);
}
});

window.addEventListener('load', () => {
const effectLevelSlider = document.querySelector('.img-upload__effect-level');
const currentEffect = document.querySelector('input[name="effect"]:checked').value;
if (currentEffect === 'none') {
effectLevelSlider.classList.add('hidden');
}
});
}
export { imgPreview };

0 comments on commit 7cd79cf

Please sign in to comment.