let myChart; document.addEventListener("DOMContentLoaded", async () => { const urlParams = new URLSearchParams(window.location.search); const projectId = urlParams.get("id"); const data = await getAllProject(); const DataMetrics = await getDataMetrics(projectId); const project = data.find(project => project.id == projectId); if (project) { document.getElementById("name_project").innerHTML = project.name; } else { console.error("Project not found"); } const videoSelector = document.getElementById("video_selector"); const numberPicker = document.getElementById('number-picker'); const choiceSelect = document.getElementById('choice'); const oneByOneContainer = document.getElementById('one-by-one-container'); const firstLastContainer = document.getElementById('first-last-container'); const addNumberButton = document.getElementById('add-number-button'); const formContainerProject = document.getElementById('form-container-project'); const formContainerCamera = document.getElementById('form-container-camera'); const durationInput = document.getElementById('duration'); const tableImage = document.getElementById("content1"); const numberBoard = document.getElementById('number-board'); // Add event listeners for the "Début" and "Fin" input fields const firstInput = document.getElementById('first'); const lastInput = document.getElementById('last'); const start_timelapse_button = document.getElementById('start-timelapse') let selectedNumbers = []; populateTimelapseLogic(start_timelapse_button, projectId).then( () => { document.getElementById('show-form-button-camera').addEventListener('click', showFormCamera) document.getElementById('close-form-button-camera').addEventListener('click', hideFormCamera) if(document.getElementById('commencer') != null){ document.getElementById('commencer').addEventListener('click', async () => { const days = document.getElementById('days').value; const hours = document.getElementById('hours').value; const minutes = document.getElementById('minutes').value; const frequency = days * 1440 + hours * 60 + minutes; start_timelapse(projectId, frequency).then(()=>{ location.reload(); }) }) } if(document.getElementById('stop-camera') != null){ document.getElementById('stop-camera').addEventListener('click', async () => { stopCamera(projectId) location.reload(); }) } } ) choiceSelect.addEventListener('change', toggleContainers); if (addNumberButton) { addNumberButton.addEventListener('click', addSelectedNumber); } videoSelector.addEventListener("change", () => generateViewMetric(projectId)); document.getElementById('show-form-button-camera').addEventListener('click', showFormProject); document.getElementById('close-form-button-project').addEventListener('click', hideFormProject); document.getElementById('increment-button').addEventListener('click', incrementDuration); document.getElementById('decrement-button').addEventListener('click', decrementDuration); document.getElementById('submit').addEventListener('click', handleFormSubmit); document.getElementById("projets").addEventListener("click", navigateToProjects); document.getElementById("toggle-view").addEventListener("click", toggleView); firstInput.addEventListener('input', updateRange); lastInput.addEventListener('input', updateRange); generateViewMetric(projectId); PopulateSelect(videoSelector, projectId); function toggleContainers() { if (choiceSelect.value === 'oneByOne') { oneByOneContainer.style.display = 'block'; firstLastContainer.style.display = 'none'; populateNumberBoard(DataMetrics.length); setRequiredAttributes(); } else { oneByOneContainer.style.display = 'none'; firstLastContainer.style.display = 'block'; const last = document.getElementById('last'); last.value = DataMetrics.length; last.max = DataMetrics.length; document.getElementById('first').max = last.value; setRequiredAttributes(); } } toggleContainers(); function setRequiredAttributes() { const firstInput = document.getElementById('first'); const lastInput = document.getElementById('last'); const denominatorInput = document.getElementById('denominator'); if (firstLastContainer.style.display === 'block') { firstInput.required = true; lastInput.required = true; denominatorInput.required = true; } else { firstInput.required = false; lastInput.required = false; denominatorInput.required = false; } } function addSelectedNumber() { const selectedNumber = parseInt(numberPicker.value, 10); if (!selectedNumbers.includes(selectedNumber)) { selectedNumbers.push(selectedNumber); numberPicker.remove(numberPicker.selectedIndex); } } function showFormCamera() { formContainerCamera.style.display = 'flex'; } function hideFormCamera() { formContainerCamera.style.display = 'none'; } function showFormProject() { formContainerProject.style.display = 'flex'; } function hideFormProject() { formContainerProject.style.display = 'none'; } function incrementDuration() { durationInput.value = parseInt(durationInput.value) + 1; } function decrementDuration() { if (parseInt(durationInput.value) > 0) { durationInput.value = parseInt(durationInput.value) - 1; } } async function handleFormSubmit(event) { event.preventDefault(); const data = await getDataProjectVideosFromApi(projectId); const nameVideo = document.getElementById('name').value; const videoDuration = durationInput.value; const videoResolution = document.getElementById('resolution').value; if (videoDuration <= 0) { alert('La durée de la vidéo doit être supérieur à 0'); return 0; } if (!checkVideoPath(data, nameVideo) || !nameVideo.length>0) { alert('Le nom : " ' + nameVideo + ' " est déjà pris ou vide ! \n' + 'veuillez en trouver un autre'); return 0; } const choice = choiceSelect.value const measurementIds = getMeasurementsIdsFromForm(choice,firstInput,lastInput); postNewVideo(projectId, measurementIds, nameVideo, videoResolution, videoDuration) .then(()=>{ alert('Nouvelle vidéo enregistrée :\nNom : ' + nameVideo + '\nRésolution : ' + videoResolution + '\nDurée : ' + videoDuration + ' secondes'); }).then(()=>{ getDataProjectVideosFromApi(projectId).then((data)=>{ idVideo = data[data.length-1].id console.log(idVideo) renderVideo(idVideo) }) }) } function navigateToProjects() { window.location.href = "../index.html"; } function toggleView() { if (tableImage.classList.contains("hiddenTable")) { tableImage.classList.remove("hiddenTable"); tableImage.classList.add("full-view"); document.getElementById("toggle-view").innerHTML = "See first images"; } else { tableImage.classList.remove("full-view"); tableImage.classList.add("hiddenTable"); document.getElementById("toggle-view").innerHTML = "See all images"; } } function populateNumberBoard(length) { numberBoard.innerHTML = ''; numberBoard.style.gridTemplateColumns = `repeat(auto-fill, minmax(50px, 1fr))`; for (let i = 1; i <= length; i++) { const numberButton = document.createElement('button'); numberButton.classList.add('number-button'); numberButton.textContent = i; numberButton.addEventListener('click', () => highlightNumber(numberButton)); numberBoard.appendChild(numberButton); } } function highlightNumber(button) { button.classList.toggle('highlight'); } function updateRange() { const firstValue = parseInt(firstInput.value); const lastValue = parseInt(lastInput.value); if (firstValue > lastValue) { lastInput.value = firstValue; } if (lastValue < firstValue) { firstInput.value = lastValue; } firstInput.max = lastValue; lastInput.min = firstValue; } }); function populateImageTable(DataMetrics) { const tableBody = document.getElementById("imageSource"); while (tableBody.rows.length > 0) { tableBody.deleteRow(0); } let row = document.createElement("tr"); let i = 0; DataMetrics.forEach((measure) => { let imageTD = document.createElement("td"); imageTD.innerHTML = ``; row.appendChild(imageTD); if ((i + 1) % 3 === 0 && i !== 0) { tableBody.appendChild(row); row = document.createElement("tr"); } if (row.childNodes.length > 0) { tableBody.appendChild(row); } i++; }); } async function generateViewMetric(projectId) { const ctx = document.getElementById("metric_viewer").getContext("2d"); const videoPlaceHolder = document.getElementById('video-container') const deletePlaceHolder = document.getElementById('delete-placeholder') let Hygrometrie = []; let Temperature = []; let datesMeasurement = []; let measurements; let currentVideoDatas; await new Promise((resolve) => { const checkExist = setInterval(() => { if (document.getElementById("video_selector").options.length > 0) { clearInterval(checkExist); resolve(); } }, 100); // check every 100ms }); const videoId = document.getElementById("video_selector").value; measurements = await getDataMetrics(projectId); let samples; if(videoId!=-1){ currentVideoDatas = await getDataVideoFromApi(videoId); samples = JSON.parse(currentVideoDatas[0]["measurement_ids"]); videoPlaceHolder.innerHTML=` ` deletePlaceHolder.innerHTML=` ` document.getElementById("delete-video").addEventListener("click", ()=>{ showConfirmationAlert(videoId) }) tempoMeasure=filterAndSortMeasurementsByNumber(measurements, samples) } else { samples=measurements.map(measurements => measurements.id); tempoMeasure = filterAndSortMeasurementsByIds(measurements, samples); } tempoMeasure.forEach((measure) => { datesMeasurement.push(measure.timestamp); Temperature.push(measure.temperature); Hygrometrie.push(measure.humidity); }); populateImageTable(tempoMeasure) if (myChart) { myChart.destroy(); } myChart = new Chart(ctx, { type: "line", data: { labels: datesMeasurement, datasets: [ { label: "Température (F°)", data: Temperature, fill: false, borderColor: "rgba(75, 192, 192, 1)", tension: 0.1, yAxisID: "y", // Use the default y-axis }, { label: "Hygrometrie (%)", data: Hygrometrie, fill: false, borderColor: "rgba(153, 102, 255, 1)", tension: 0.1, yAxisID: "y1", // Use the second y-axis }, ], }, options: { scales: { y: { beginAtZero: true, position: "left", }, y1: { beginAtZero: true, position: "right", grid: { drawOnChartArea: false, // Only want the grid lines for one axis to show up }, }, }, }, }) } function showConfirmationAlert(videoId) { const customAlert = document.getElementById('customAlert'); const alertMessage = document.getElementById('alertMessage'); const okBtn = document.getElementById('okBtn'); const cancelBtn = document.getElementById('cancelBtn'); alertMessage.textContent = 'Are you sure you want to delete this video?'; customAlert.style.display = 'block'; okBtn.onclick = function() { deleteVideo(videoId); customAlert.style.display = 'none'; }; cancelBtn.onclick = function() { customAlert.style.display = 'none'; }; } function convertStringToArray(string) { const numberStrings = string.replace(/[{}]/g, '').split(','); // Trim whitespace and convert the string numbers to integers const numberArray = numberStrings.map(num => parseInt(num.trim(), 10)); return numberArray; } function filterAndSortMeasurementsByIds(measurements, ids) { return measurements .filter((measurement) => ids.includes(measurement.id)) .sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp)); } function filterAndSortMeasurementsByNumber(measurements, Numbers) { // Filter measurements based on their position in the Numbers array const filteredMeasurements = Numbers.map(index => measurements[index - 1]).filter(measurement => measurement !== undefined); // Sort the filtered measurements by their timestamp return filteredMeasurements.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp)); } function checkVideoPath(videos, name) { let res = true; videos.forEach(video => { const videoName = video.name; if(videoName==name) res=false; }); return res; } function getMeasurementsIdsFromForm(choice, firstInput, lastInput) { if (choice === 'oneByOne') { const highlightedButtons = document.querySelectorAll('.number-button.highlight'); return Array.from(highlightedButtons).map(button => parseInt(button.textContent)); } else { const first = parseInt(firstInput.value); const last = parseInt(lastInput.value); const denominator = parseInt(document.getElementById('denominator').value); const measurementIds = new Set(); measurementIds.add(first); // Always include the first image // Iterate through the range, adding the step size for (let i = first + denominator; i <= last; i += denominator) { measurementIds.add(i); } measurementIds.add(last); // Always include the last image // Convert the Set back to an array and sort it return Array.from(measurementIds).sort((a, b) => a - b); } } async function populateTimelapseLogic(placeholder,id) { const data = await getSingleProject(id); if(data.status == 0){ placeholder.innerHTML = `` } else if (data.status == 1) { placeholder.innerHTML = ``} else { placeholder.innerHTML = `` } } function increment(id) { const input = document.getElementById(id); input.value = parseInt(input.value) + 1; updateFrequencyText() } function decrement(id) { const input = document.getElementById(id); if (parseInt(input.value) > 0) { input.value = parseInt(input.value) - 1; } updateFrequencyText() } function updateFrequencyText() { const days = document.getElementById('days').value; const hours = document.getElementById('hours').value; const minutes = document.getElementById('minutes').value; const frequencyText = `une image sera prise toutes les ${days} jours ${hours} heures ${minutes} minutes`; document.getElementById('frequency-text').innerHTML = frequencyText; }