import { BaseElement } from '../../../shared/_base'; import { CodeEditorContainer } from '../code-editor-container/code-editor-container'; import './session-list-item.less'; import * as sessionApi from '../../../shared/session-api'; import { formatDate } from '../../../shared/date-helper'; import { navigateTo } from '../../../shared/navigation'; import { getSessionDetailsId } from '../../../shared/page'; export class SessionListItem extends BaseElement { historyIndex: number | null = null; onInit(): void { if (this.hasAttribute("sessionId")) { var sessionIdEle = document.createElement("div"); sessionIdEle.classList.add("session-list-item-session-id"); sessionIdEle.innerHTML = "" + (this.getAttribute("sessionId")?.toString() ?? "") + ""; this.appendChild(sessionIdEle); } if (this.hasAttribute("timestamp")) { var timestampEle = document.createElement("div"); timestampEle.classList.add("session-list-item-timestamp"); timestampEle.innerHTML = formatDate(this.getAttribute("timestamp")?.toString() ?? ""); this.appendChild(timestampEle); } if (this.hasAttribute("numberOfChanges")) { var numberOfChangesEle = document.createElement("div"); numberOfChangesEle.classList.add("session-list-item-number-of-changes"); numberOfChangesEle.innerHTML = this.getNumberOfChanges().toString(); this.appendChild(numberOfChangesEle); } this.addSlider(this.getNumberOfChanges()); this.addEventListener("click", (evt) => { this.itemClicked(); }); if (this.isUrlSelected()) { this.itemClicked(); } } getNumberOfChanges() { return parseInt(this.getAttribute("numberOfChanges")?.toString() ?? "0"); } updateNumberOfChanges(numberOfChanges: number) { this.setAttribute("numberOfChanges", numberOfChanges.toString()); this.getElementsByClassName("session-list-item-number-of-changes")[0].innerHTML = (this.historyIndex !== null ? (this.historyIndex + 1) + " / " : "") + numberOfChanges.toString(); this.updateSlider(numberOfChanges); } private hasSliderChanges: boolean = false; private addSlider(numberOfChanges: number) { var sliderEle = document.createElement("div"); sliderEle.classList.add("slider-wrap"); var sliderInput = document.createElement("input"); sliderInput.setAttribute("min", "0"); sliderInput.setAttribute("max", (numberOfChanges - 1).toString()); sliderInput.setAttribute("type", "range"); sliderInput.setAttribute("value", (numberOfChanges - 1).toString()); sliderInput.value = (numberOfChanges - 1).toString(); sliderInput.addEventListener("input", (evt) => { this.hasSliderChanges = true; evt.preventDefault(); evt.stopPropagation(); evt.stopImmediatePropagation(); this.historyIndex = parseInt((evt).target.value); if (this.historyIndex != null && this.historyIndex >= this.getNumberOfChanges() - 1) { this.historyIndex = null; } this.updateNumberOfChanges(this.getNumberOfChanges()); this.updateInputs(true); }); sliderEle.appendChild(sliderInput); this.appendChild(sliderEle); } private updateSlider(numberOfChanges: number) { var sliderInput = this.querySelector(".slider-wrap input"); if (sliderInput) { sliderInput.setAttribute("max", (numberOfChanges - 1).toString()); if (this.historyIndex == null) { sliderInput.setAttribute("value", (numberOfChanges - 1).toString()); sliderInput.value = (numberOfChanges - 1).toString(); } } } private intervalHandle: number | null = null; stopUpdate() { this.classList.remove("selected"); this.historyIndex = null; if (this.intervalHandle) { this.updateNumberOfChanges(this.getNumberOfChanges()); if (this.isUrlSelected()) { navigateTo("/sessions"); } window.clearInterval(this.intervalHandle); this.intervalHandle = null; } } isUrlSelected(): boolean { var selectedId = getSessionDetailsId(); return selectedId === this.getAttribute("sessionId")?.toString()?? ""; } startUpdate() { this.stopUpdate(); this.classList.add("selected"); this.updateInputs(); this.intervalHandle = window.setInterval(this.updateInputs.bind(this), 1000); } updateInputs(fromCache: boolean = false) { var codeEditorHTMLContainer = document.querySelector("code-editor-container[language='HTML']"); var codeEditorCSSContainer = document.querySelector("code-editor-container[language='CSS']"); var codeEditorJavascriptContainer = document.querySelector("code-editor-container[language='Javascript']"); this.getSessionData((js, html, css) => { codeEditorJavascriptContainer.setInput(js?.data ?? ""); codeEditorHTMLContainer.setInput(html?.data ?? ""); codeEditorCSSContainer.setInput(css?.data ?? ""); }, fromCache); } private sessionDataCache: any[] = []; getSessionData(onGet: (javascript: any, html: any, css: any) => void, fromCache: boolean = false) { if (fromCache) { const res = this.findLastContent(this.sessionDataCache); onGet(res.lastJavascript, res.lastHtml, res.lastCSS); this.updateNumberOfChanges(this.sessionDataCache.length); } else { sessionApi.getSessionData(this.getAttribute("sessionId")?.toString()?? "", (data) => { this.sessionDataCache = data; const res = this.findLastContent(data); onGet(res.lastJavascript, res.lastHtml, res.lastCSS); this.updateNumberOfChanges(data.length); }); } } private findLastContent(data: any[]) { var lastJavascript: any | null = null; var lastHtml: any | null = null; var lastCSS: any | null = null; for (var i = (this.historyIndex != null ? (this.historyIndex + 1) : data.length) - 1; i >= 0; i--) { var dataPoint = data[i]; if (!lastJavascript && dataPoint.type == 0) { lastJavascript = dataPoint; } else if (!lastHtml && dataPoint.type == 1) { lastHtml = dataPoint; } else if (!lastCSS && dataPoint.type == 2) { lastCSS = dataPoint; } } return { lastJavascript, lastHtml, lastCSS }; } itemClicked() { if (!this.hasSliderChanges) { if (!this.intervalHandle) { var containers = document.getElementsByClassName("code-editor-containers")[0]; var outputframe = document.getElementsByClassName("output-frame-container")[0]; containers.style.display = "block"; outputframe.style.display = "block"; navigateTo("/sessions/" + this.getAttribute("sessionId")?.toString()?? ""); var children = this.parentElement?.children; if (children) { for (let i = 0; i < children.length; i++) { const child = children[i]; if (child != this) { child.stopUpdate(); } else { child.startUpdate(); } } } } else { this.stopUpdate(); } } else { this.hasSliderChanges = false; } } }