added slider and some ui fixes
This commit is contained in:
@@ -11,12 +11,15 @@ export class CodeEditor extends BaseElement {
|
||||
public input: string = "";
|
||||
public language: string = "";
|
||||
public editor!: monaco.editor.IStandaloneCodeEditor;
|
||||
public lastInputCache: any;
|
||||
|
||||
onInit(): void {
|
||||
|
||||
this.initWorkers();
|
||||
this.input = this.setInitInput();
|
||||
this.language = this.tagName.substring(0, this.tagName.indexOf("-")).toLocaleLowerCase();
|
||||
this.lastInputCache = localStorage.getItem(this.language + "LastInputCache");
|
||||
this.input = this.setInitInput();
|
||||
|
||||
this.setInitSettings();
|
||||
|
||||
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
@@ -38,6 +41,8 @@ export class CodeEditor extends BaseElement {
|
||||
this.editor.onDidChangeModelContent((e) => {
|
||||
if (!isSessionPage()) {
|
||||
this.input = this.editor.getValue();
|
||||
this.lastInputCache = this.input;
|
||||
localStorage.setItem(this.language + "LastInputCache", this.input);
|
||||
debounce.ensureDebounce(() => {
|
||||
sessionApi.setSessionData(this.language, this.input);
|
||||
this.outputFrame.setContent(this.language, this.input);
|
||||
@@ -54,13 +59,21 @@ export class CodeEditor extends BaseElement {
|
||||
setInput(input: any) {
|
||||
if (this.input !== input) {
|
||||
this.input = input;
|
||||
this.lastInputCache = this.input;
|
||||
localStorage.setItem(this.language + "LastInputCache", this.input);
|
||||
this.editor.setValue(input);
|
||||
this.outputFrame.setContent(this.language, this.input);
|
||||
}
|
||||
}
|
||||
|
||||
setInitInput(): string {
|
||||
return "";
|
||||
if (!isSessionPage() && sessionApi.hasSession()) {
|
||||
return this.lastInputCache;
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setInitSettings(): void {
|
||||
|
||||
@@ -6,7 +6,13 @@ import flexCss from '!!raw-loader!../../../shared/flex.less';
|
||||
|
||||
export class CssCodeEditor extends CodeEditor {
|
||||
setInitInput(): string {
|
||||
return initCss;
|
||||
var base = super.setInitInput();
|
||||
if (!base) {
|
||||
return initCss;
|
||||
}
|
||||
else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
setInitSettings(): void {
|
||||
|
||||
@@ -4,7 +4,13 @@ import initHtml from '!!raw-loader!./injects/editor-init.html';
|
||||
|
||||
export class HtmlCodeEditor extends CodeEditor {
|
||||
setInitInput(): string {
|
||||
return initHtml;
|
||||
var base = super.setInitInput();
|
||||
if (!base) {
|
||||
return initHtml;
|
||||
}
|
||||
else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
setInitSettings(): void {
|
||||
|
||||
@@ -6,7 +6,13 @@ import declarations from '!!raw-loader!./injects/declarations.d.ts';
|
||||
|
||||
export class JavascriptCodeEditor extends CodeEditor {
|
||||
setInitInput(): string {
|
||||
return initScript;
|
||||
var base = super.setInitInput();
|
||||
if (!base) {
|
||||
return initScript;
|
||||
}
|
||||
else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
setInitSettings(): void {
|
||||
|
||||
@@ -14,8 +14,12 @@ session-list-item.selected {
|
||||
background-color: lighten(@primary-interaction-highlight-white, 30%);
|
||||
}
|
||||
|
||||
session-list-item.selected .slider-wrap {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.session-list-item-session-id::before {
|
||||
content: "Session: ";
|
||||
content: "";
|
||||
}
|
||||
|
||||
.session-list-item-timestamp::before {
|
||||
@@ -25,6 +29,7 @@ session-list-item.selected {
|
||||
.session-list-item-timestamp {
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.session-list-item-session-id {
|
||||
@@ -32,11 +37,24 @@ session-list-item.selected {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.session-list-item-session-id > span {
|
||||
display: inline-block;
|
||||
font-size: 9px;
|
||||
padding: 2px 4px;
|
||||
background-color: @editor-bg-white;
|
||||
border: 1px solid;
|
||||
border-color: darken(@editor-bg-white, 10%);
|
||||
border-radius: 3px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.session-list-item-number-of-changes {
|
||||
font-size: 12px;
|
||||
opacity: 0.6;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.session-list-item-number-of-changes::before {
|
||||
@@ -45,7 +63,54 @@ session-list-item.selected {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.slider-wrap {
|
||||
display: none;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.slider-wrap input {
|
||||
width: 100%; /* Width of the outside container */
|
||||
}
|
||||
|
||||
/* The slider itself */
|
||||
.slider-wrap input {
|
||||
-webkit-appearance: none; /* Override default CSS styles */
|
||||
appearance: none;
|
||||
width: 100%; /* Full-width */
|
||||
height: 25px; /* Specified height */
|
||||
background: @editor-bg-white; /* Grey background */
|
||||
outline: none; /* Remove outline */
|
||||
opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */
|
||||
-webkit-transition: .2s; /* 0.2 seconds transition on hover */
|
||||
transition: opacity .2s;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Mouse-over effects */
|
||||
.slider-wrap input:hover {
|
||||
opacity: 1; /* Fully shown on mouse-over */
|
||||
}
|
||||
|
||||
/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */
|
||||
.slider-wrap input::-webkit-slider-thumb {
|
||||
-webkit-appearance: none; /* Override default look */
|
||||
appearance: none;
|
||||
width: 25px; /* Set a specific slider handle width */
|
||||
height: 25px; /* Slider handle height */
|
||||
background: @primary-interaction-highlight-white; /* Green background */
|
||||
cursor: pointer; /* Cursor on hover */
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.slider-wrap input::-moz-range-thumb {
|
||||
width: 25px; /* Set a specific slider handle width */
|
||||
height: 25px; /* Slider handle height */
|
||||
background: @primary-interaction-highlight-white; /* Green background */
|
||||
cursor: pointer; /* Cursor on hover */
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
session-list-item {
|
||||
border-color: @primary-bg-color-dark;
|
||||
color: @primary-text-color-dark;
|
||||
@@ -54,4 +119,13 @@ session-list-item.selected {
|
||||
session-list-item.selected {
|
||||
background-color: @primary-interaction-highlight-dark;
|
||||
}
|
||||
|
||||
.slider-wrap input {
|
||||
background: @editor-bg-dark; /* Grey background */
|
||||
}
|
||||
|
||||
.session-list-item-session-id > span {
|
||||
background-color: @editor-bg-dark;
|
||||
border-color: lighten(@editor-bg-dark, 10%);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,13 @@ 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() ?? "";
|
||||
sessionIdEle.innerHTML = "<span>" + (this.getAttribute("sessionId")?.toString() ?? "") + "</span>";
|
||||
this.appendChild(sessionIdEle);
|
||||
}
|
||||
|
||||
@@ -25,10 +27,12 @@ export class SessionListItem extends BaseElement {
|
||||
if (this.hasAttribute("numberOfChanges")) {
|
||||
var numberOfChangesEle = document.createElement("div");
|
||||
numberOfChangesEle.classList.add("session-list-item-number-of-changes");
|
||||
numberOfChangesEle.innerHTML = this.getAttribute("numberOfChanges")?.toString() ?? "";
|
||||
numberOfChangesEle.innerHTML = this.getNumberOfChanges().toString();
|
||||
this.appendChild(numberOfChangesEle);
|
||||
}
|
||||
|
||||
this.addSlider(this.getNumberOfChanges());
|
||||
|
||||
this.addEventListener("click", (evt) => {
|
||||
this.itemClicked();
|
||||
});
|
||||
@@ -38,11 +42,73 @@ export class SessionListItem extends BaseElement {
|
||||
}
|
||||
}
|
||||
|
||||
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((<any>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 = <HTMLInputElement>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;
|
||||
}
|
||||
@@ -62,7 +128,7 @@ export class SessionListItem extends BaseElement {
|
||||
this.intervalHandle = window.setInterval(this.updateInputs.bind(this), 1000);
|
||||
}
|
||||
|
||||
updateInputs() {
|
||||
updateInputs(fromCache: boolean = false) {
|
||||
var codeEditorHTMLContainer = <CodeEditorContainer>document.querySelector("code-editor-container[language='HTML']");
|
||||
var codeEditorCSSContainer = <CodeEditorContainer>document.querySelector("code-editor-container[language='CSS']");
|
||||
var codeEditorJavascriptContainer = <CodeEditorContainer>document.querySelector("code-editor-container[language='Javascript']");
|
||||
@@ -71,59 +137,80 @@ export class SessionListItem extends BaseElement {
|
||||
codeEditorJavascriptContainer.setInput(js?.data ?? "");
|
||||
codeEditorHTMLContainer.setInput(html?.data ?? "");
|
||||
codeEditorCSSContainer.setInput(css?.data ?? "");
|
||||
});
|
||||
}, fromCache);
|
||||
|
||||
}
|
||||
|
||||
getSessionData(onGet: (javascript: any, html: any, css: any) => void) {
|
||||
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;
|
||||
|
||||
sessionApi.getSessionData(this.getAttribute("sessionId")?.toString()?? "", (data) => {
|
||||
for (var i = 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
onGet(lastJavascript, lastHtml, lastCSS);
|
||||
});
|
||||
return { lastJavascript, lastHtml, lastCSS };
|
||||
}
|
||||
|
||||
itemClicked() {
|
||||
if (!this.intervalHandle) {
|
||||
var containers = <HTMLElement>document.getElementsByClassName("code-editor-containers")[0];
|
||||
var outputframe = <HTMLElement>document.getElementsByClassName("output-frame-container")[0];
|
||||
if (!this.hasSliderChanges) {
|
||||
if (!this.intervalHandle) {
|
||||
var containers = <HTMLElement>document.getElementsByClassName("code-editor-containers")[0];
|
||||
var outputframe = <HTMLElement>document.getElementsByClassName("output-frame-container")[0];
|
||||
|
||||
containers.style.display = "block";
|
||||
outputframe.style.display = "block";
|
||||
containers.style.display = "block";
|
||||
outputframe.style.display = "block";
|
||||
|
||||
navigateTo("/sessions/" + this.getAttribute("sessionId")?.toString()?? "");
|
||||
navigateTo("/sessions/" + this.getAttribute("sessionId")?.toString()?? "");
|
||||
|
||||
var children = this.parentElement?.children;
|
||||
var children = this.parentElement?.children;
|
||||
|
||||
if (children) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = <SessionListItem>children[i];
|
||||
if (child != this) {
|
||||
child.stopUpdate();
|
||||
}
|
||||
else {
|
||||
child.startUpdate();
|
||||
if (children) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = <SessionListItem>children[i];
|
||||
if (child != this) {
|
||||
child.stopUpdate();
|
||||
}
|
||||
else {
|
||||
child.startUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.stopUpdate();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.stopUpdate();
|
||||
this.hasSliderChanges = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
@import url('../../../shared/theme.less');
|
||||
|
||||
session-list:empty::before {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
color: @primary-text-color-dark;
|
||||
content: "There is no sessions within the last 30 days";
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
session-list {
|
||||
color: @primary-text-color-white;
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,9 @@ export class SessionList extends BaseElement {
|
||||
|
||||
this.appendChild(ele);
|
||||
}
|
||||
//do this in item instead:
|
||||
else {
|
||||
exists.setAttribute("numberOfChanges", session.numberOfChanges);
|
||||
exists.getElementsByClassName("session-list-item-number-of-changes")[0].innerHTML = session.numberOfChanges;
|
||||
(<any>exists).updateNumberOfChanges(session.numberOfChanges);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user