import { ApiEndpoint, createMovieObject } from "./apiendpoint"; import { Modal } from "bootstrap"; import { modalControls } from "./modalui"; const moviesApiEndpoint = new ApiEndpoint("movies"); const categoriesApiEndpoint = new ApiEndpoint("categories"); document.addEventListener("DOMContentLoaded", loadMoviesTableData()); document .getElementById("movie-button-add") .addEventListener("click", buttonMovieAddClicked); const modal = document.getElementById("modal-movie"); const myModal = modal ? new Modal(modal, {}) : null; // myModal.show(); function createItemsOption(name, value = "", isSelected = false) { const option = document.createElement("option"); option.value = value || ""; option.selected = isSelected; option.text = name; return option; } async function readFile(file) { const reader = new FileReader(); // создание Promise-объекта для использования функции // с помощью await (асинхронно) без коллбэков (callback) // https://learn.javascript.ru/promise return new Promise((resolve, reject) => { // 2. "Возвращаем" содержимое когда файл прочитан // через вызов resolve // Если не использовать Promise, то всю работу по взаимодействию // с REST API пришлось бы делать в обработчике (callback) функции // onloadend reader.onloadend = () => { const fileContent = reader.result; // Здесь могла бы быть работа с REST API // Чтение заканчивает выполняться здесь resolve(fileContent); }; // 3. Возвращаем ошибку reader.onerror = () => { // Или здесь в случае ошибки reject(new Error("oops, something went wrong with the file reader.")); }; // Шаг 1. Сначала читаем файл // Чтение начинает выполняться здесь reader.readAsDataURL(file); }); } // TODO // функция для обновления блока с превью выбранного изображения async function updateImagePreview() { // получение выбранного файла // возможен выбор нескольких файлов, поэтому необходимо получить только первый const file = modalControls.inputImage.files[0]; // чтение содержимого файла в виде base64 строки const fileContent = await readFile(file); console.info("base64 ", fileContent); // обновление атрибута src для тега img с id image-preview modalControls.imagePreview.src = fileContent; } const imagePlaceholder = "./static/images/cover-placeholder160x230.png"; modalControls.form.addEventListener("submit", async (event) => { // отключение стандартного поведения формы при отправке // при отправке страница обновляется и JS перестает работать event.preventDefault(); event.stopPropagation(); // если форма не прошла валидацию, то ничего делать не нужно // if (!cntrls.form.checkValidity()) { // return; // } let imageBase64 = ""; // Получение выбранного пользователем изображения в виде base64 строки // Если пользователь ничего не выбрал, то не нужно сохранять в БД // дефолтное изображение // modalControls.imagePreview.src !== imagePlaceholder // TODO // прописать логиук отображения превью if (modalControls.imagePreview.src !== imagePlaceholder) { // Загрузка содержимого атрибута src тэга img с id image-preview // Здесь выполняется HTTP запрос с типом GET const result = await fetch(modalControls.imagePreview.src); // Получение из HTTP-ответа бинарного содержимого const blob = await result.blob(); // Получение base64 строки для файла // Здесь выполняется Promise из функции readFile // Promise позволяет писать линейный код для работы с асинхронными методами // без использования обработчиков (callback) с помощью await imageBase64 = await readFile(blob); } // получение id строки для редактирования // это значение содержится в скрытом input const currentId = modalControls.movieId.value; // если значение id не задано, // то необходимо выполнить добавление записи // иначе обновление записи if (!currentId) { const movie = createMovieObject( modalControls.inputName.value, parseInt(modalControls.selectCategory.value), modalControls.inputDuration.value, modalControls.inputDescription.value, imageBase64 ); await moviesApiEndpoint.createObject(movie); } else { // TODO // await editLine( // currentId, // cntrls.itemsType.value, // cntrls.price.value, // cntrls.count.value, // imageBase64, // ); } // после выполнения добавления/обновления модальное окно скрывается myModal.hide(); await loadMoviesTableData(); }); async function buttonMovieAddClicked(e) { modalControls.title.innerText = "Добавить фильм"; modalControls.selectCategory.innerHTML = ""; const categories = await categoriesApiEndpoint.getObjects(); modalControls.selectCategory.appendChild( createItemsOption("Выберите жанр", "", true) ); for (let i = 0; i < categories.length; i++) { const category = categories[i]; modalControls.selectCategory.appendChild( createItemsOption(category.name, category.id) ); } myModal.show(); } async function movieDeleteButtonClicked(e) { console.log(e.target); const movieId = parseInt(e.target.id.split("-")[3]); await moviesApiEndpoint.deleteObject(movieId); await loadMoviesTableData(); } async function movieEditButtonClicked(e) { // TODO // получить объект по id // заполнение модального окна по данным объекта // показ модального окна } async function loadMoviesTableData() { const movies = await moviesApiEndpoint.getObjects(); const category = await categoriesApiEndpoint.getObjects(); const tableWrapper = document.getElementById("movie-table-body"); // Вызов функции обновления превью изображения при возникновении // события oncahnge в тэге input с id image modalControls.inputImage.addEventListener("change", () => updateImagePreview() ); tableWrapper.innerHTML = ""; for (let i = 0; i < movies.length; i++) { const movie = movies[i]; const movieCategory = await categoriesApiEndpoint.getObject( movie.categoryId ); tableWrapper.innerHTML += `