added sessions support
This commit is contained in:
@@ -2,12 +2,17 @@
|
|||||||
<div class="flex-shrink section top">
|
<div class="flex-shrink section top">
|
||||||
<h1>code editor</h1>
|
<h1>code editor</h1>
|
||||||
<window-control distribute=".code-editor-containers">
|
<window-control distribute=".code-editor-containers">
|
||||||
|
<window-control-connector style="display: none;" target=".menu-container" class="active">Sessions</window-control-connector>
|
||||||
<window-control-connector target="code-editor-container[language='Javascript']" class="active">Javascript</window-control-connector>
|
<window-control-connector target="code-editor-container[language='Javascript']" class="active">Javascript</window-control-connector>
|
||||||
<window-control-connector target="code-editor-container[language='HTML']">HTML</window-control-connector>
|
<window-control-connector target="code-editor-container[language='HTML']">HTML</window-control-connector>
|
||||||
<window-control-connector target="code-editor-container[language='CSS']">CSS</window-control-connector>
|
<window-control-connector target="code-editor-container[language='CSS']">CSS</window-control-connector>
|
||||||
</window-control>
|
</window-control>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-dynamic">
|
<div class="flex-dynamic">
|
||||||
|
<div class="menu menu-container" id="session-menu" style="display: none">
|
||||||
|
<resize-handle target=".menu-container" place="right" dir="horizontal"></resize-handle>
|
||||||
|
<session-list></session-list>
|
||||||
|
</div>
|
||||||
<div class="code-editor-containers flex-vert">
|
<div class="code-editor-containers flex-vert">
|
||||||
<code-editor-container language="Javascript" dir="vertical" class="first-visible last-visible">
|
<code-editor-container language="Javascript" dir="vertical" class="first-visible last-visible">
|
||||||
</code-editor-container>
|
</code-editor-container>
|
||||||
|
|||||||
+20
-1
@@ -12,6 +12,10 @@ import { JavascriptCodeEditor } from './elements/code-editor/javascript-code-edi
|
|||||||
import { HtmlCodeEditor } from './elements/code-editor/html-code-editor';
|
import { HtmlCodeEditor } from './elements/code-editor/html-code-editor';
|
||||||
import { CssCodeEditor } from './elements/code-editor/css-code-editor';
|
import { CssCodeEditor } from './elements/code-editor/css-code-editor';
|
||||||
import { setDynamicFlexListener } from '../shared/set-dynamic-flex-listener';
|
import { setDynamicFlexListener } from '../shared/set-dynamic-flex-listener';
|
||||||
|
import { SessionList } from './elements/session-list/session-list';
|
||||||
|
import { SessionListItem } from './elements/session-list-item/session-list-item';
|
||||||
|
import { LoadingSpinner } from './elements/loading-spinner/loading-spinner';
|
||||||
|
import { isSessionPage } from '../shared/page';
|
||||||
|
|
||||||
window.customElements.define('app-root', AppRoot);
|
window.customElements.define('app-root', AppRoot);
|
||||||
window.customElements.define('code-editor-container', CodeEditorContainer);
|
window.customElements.define('code-editor-container', CodeEditorContainer);
|
||||||
@@ -24,8 +28,23 @@ window.customElements.define('notification-bubble', NotificationBubble);
|
|||||||
window.customElements.define('resize-handle', ResizeHandle);
|
window.customElements.define('resize-handle', ResizeHandle);
|
||||||
window.customElements.define('window-control', WindowControl);
|
window.customElements.define('window-control', WindowControl);
|
||||||
window.customElements.define('window-control-connector', WindowControlConnector);
|
window.customElements.define('window-control-connector', WindowControlConnector);
|
||||||
|
window.customElements.define('session-list', SessionList);
|
||||||
|
window.customElements.define('session-list-item', SessionListItem);
|
||||||
|
window.customElements.define('loading-spinner', LoadingSpinner);
|
||||||
|
|
||||||
document.body.innerHTML += bootHtml;
|
document.body.innerHTML += bootHtml;
|
||||||
|
|
||||||
|
if (isSessionPage()) {
|
||||||
|
var menuEle = document.getElementById("session-menu");
|
||||||
|
var containers = <HTMLElement>document.getElementsByClassName("code-editor-containers")[0];
|
||||||
|
var outputframe = <HTMLElement>document.getElementsByClassName("output-frame-container")[0];
|
||||||
|
var sessionMenuItem = <HTMLElement>document.querySelector("window-control-connector[target='.menu-container']");
|
||||||
|
if (menuEle) {
|
||||||
|
menuEle.style.display = "block";
|
||||||
|
sessionMenuItem.style.display = "inline";
|
||||||
|
containers.style.display = "none";
|
||||||
|
outputframe.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setDynamicFlexListener();
|
setDynamicFlexListener();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { ResizeHandle } from "../resize-handle/resize-handle";
|
|||||||
import './code-editor-container.less';
|
import './code-editor-container.less';
|
||||||
|
|
||||||
export class CodeEditorContainer extends BaseElement {
|
export class CodeEditorContainer extends BaseElement {
|
||||||
|
private codeEditor: CodeEditor | null = null;
|
||||||
onInit(): void {
|
onInit(): void {
|
||||||
var language = this.getAttribute("language");
|
var language = this.getAttribute("language");
|
||||||
this.classList.add("flex-vert");
|
this.classList.add("flex-vert");
|
||||||
@@ -22,11 +23,15 @@ export class CodeEditorContainer extends BaseElement {
|
|||||||
this.appendChild(div);
|
this.appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setInput(input: any) {
|
||||||
|
this.codeEditor?.setInput(input);
|
||||||
|
}
|
||||||
|
|
||||||
createCodeEditor(language: string, expandDir: 'vertical' | 'horizontal') {
|
createCodeEditor(language: string, expandDir: 'vertical' | 'horizontal') {
|
||||||
var codeEditorContent = document.createElement("div");
|
var codeEditorContent = document.createElement("div");
|
||||||
codeEditorContent.classList.add("code-editor-content");
|
codeEditorContent.classList.add("code-editor-content");
|
||||||
var codeEditor = <CodeEditor>document.createElement(language + "-code-editor");
|
this.codeEditor = <CodeEditor>document.createElement(language + "-code-editor");
|
||||||
codeEditorContent.appendChild(codeEditor);
|
codeEditorContent.appendChild(this.codeEditor);
|
||||||
|
|
||||||
var resizeHandle = <ResizeHandle>document.createElement("resize-handle");
|
var resizeHandle = <ResizeHandle>document.createElement("resize-handle");
|
||||||
resizeHandle.setAttribute("dir", expandDir);
|
resizeHandle.setAttribute("dir", expandDir);
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ import './code-editor.less';
|
|||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
import { OutputFrame } from "../output-frame/output-frame";
|
import { OutputFrame } from "../output-frame/output-frame";
|
||||||
import { debounceManager } from "../../../shared/ensure-debounce";
|
import { debounceManager } from "../../../shared/ensure-debounce";
|
||||||
|
import * as sessionApi from '../../../shared/session-api';
|
||||||
|
import { isSessionPage } from "../../../shared/page";
|
||||||
|
|
||||||
export class CodeEditor extends BaseElement {
|
export class CodeEditor extends BaseElement {
|
||||||
|
|
||||||
public input: string = "";
|
public input: string = "";
|
||||||
public language: string = "";
|
public language: string = "";
|
||||||
|
public editor!: monaco.editor.IStandaloneCodeEditor;
|
||||||
|
|
||||||
onInit(): void {
|
onInit(): void {
|
||||||
|
|
||||||
@@ -18,11 +21,12 @@ export class CodeEditor extends BaseElement {
|
|||||||
|
|
||||||
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
|
||||||
var editor = monaco.editor.create(this, {
|
this.editor = monaco.editor.create(this, {
|
||||||
value: this.input,
|
value: isSessionPage() ? "" : this.input,
|
||||||
language: this.language,
|
language: this.language,
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
|
readOnly: isSessionPage(),
|
||||||
minimap: {
|
minimap: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
@@ -31,19 +35,30 @@ export class CodeEditor extends BaseElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var debounce = debounceManager(1000);
|
var debounce = debounceManager(1000);
|
||||||
editor.onDidChangeModelContent((e) => {
|
this.editor.onDidChangeModelContent((e) => {
|
||||||
this.input = editor.getValue();
|
if (!isSessionPage()) {
|
||||||
debounce.ensureDebounce(() => {
|
this.input = this.editor.getValue();
|
||||||
this.outputFrame.setContent(this.language, this.input);
|
debounce.ensureDebounce(() => {
|
||||||
});
|
sessionApi.setSessionData(this.language, this.input);
|
||||||
|
this.outputFrame.setContent(this.language, this.input);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.waitFor(this.outputFrame, () => {
|
this.waitFor(this.outputFrame, () => {
|
||||||
this.outputFrame.setContent(this.language, this.input);
|
this.outputFrame.setContent(this.language, isSessionPage() ? "" : this.input);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setInput(input: any) {
|
||||||
|
if (this.input !== input) {
|
||||||
|
this.input = input;
|
||||||
|
this.editor.setValue(input);
|
||||||
|
this.outputFrame.setContent(this.language, this.input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setInitInput(): string {
|
setInitInput(): string {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
loading-spinner {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-1 {
|
||||||
|
width:90px;
|
||||||
|
height:14px;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle 7px at bottom, #fff 92%,#0000 ) 0 0,
|
||||||
|
radial-gradient(circle 7px at top , #fff 92%,#0000 ) 0 100%;
|
||||||
|
background-size:calc(100%/4) 50%;
|
||||||
|
background-repeat:repeat-x;
|
||||||
|
animation:i1 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i1 {
|
||||||
|
80%,100% {background-position: calc(100%/3) 0,calc(100%/-3) 100%}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-2 {
|
||||||
|
width:90px;
|
||||||
|
height:14px;
|
||||||
|
background:
|
||||||
|
conic-gradient(from 135deg at top ,#fff 90deg,#0000 0) 0 0,
|
||||||
|
conic-gradient(from -45deg at bottom,#fff 90deg,#0000 0) 0 100%;
|
||||||
|
background-size:calc(100%/4) 50%;
|
||||||
|
background-repeat:repeat-x;
|
||||||
|
animation:i2 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i2 {
|
||||||
|
80%,100% {background-position: calc(100%/3) 0,calc(100%/-3) 100%}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-3 {
|
||||||
|
width:90px;
|
||||||
|
height:14px;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle 7px at bottom, #fff 92%,#0000 ) calc(100%/2) 0,
|
||||||
|
radial-gradient(circle 7px at top , #fff 92%,#0000 ) calc(100%/2) 100%,
|
||||||
|
conic-gradient(from 135deg at top ,#fff 90deg,#0000 0) 0 0,
|
||||||
|
conic-gradient(from -45deg at bottom,#fff 90deg,#0000 0) 0 100%;
|
||||||
|
background-size:calc(100%/2) 50%;
|
||||||
|
background-repeat:repeat-x;
|
||||||
|
animation:i3 3s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i3 {
|
||||||
|
0% {background-position: calc(100%/2) 0,calc(100%/2) 100%,0 0, 0 100%}
|
||||||
|
20%,
|
||||||
|
30% {background-position: calc(3*100%/4) 0,calc(100%/4) 100%,calc(100%/4) 0, calc(100%/-4) 100%}
|
||||||
|
45%,
|
||||||
|
55% {background-position: 100% 0,0 100%,calc(100%/2) 0, calc(100%/-2) 100%}
|
||||||
|
70%,
|
||||||
|
80% {background-position: calc(5*100%/4) 0,calc(100%/-4) 100%,calc(3*100%/4) 0, calc(3*100%/-4) 100%}
|
||||||
|
100%{background-position: calc(3*100%/2) 0,calc(100%/-2) 100%,100% 0, -100% 100%}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-4 {
|
||||||
|
width:90px;
|
||||||
|
height:14px;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle closest-side, #fff 92%,#0000 ) calc(100%/-4) 0,
|
||||||
|
radial-gradient(circle closest-side, #fff 92%,#0000 ) calc(100%/4) 0;
|
||||||
|
background-size:calc(100%/2) 100%;
|
||||||
|
animation:i4 1.5s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i4 {
|
||||||
|
0% {background-position: calc(100%/-4) 0 ,calc(100%/4) 0}
|
||||||
|
50% {background-position: calc(100%/-4) -14px,calc(100%/4) 14px}
|
||||||
|
100% {background-position: calc(100%/4) -14px,calc(3*100%/4) 14px}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-5 {
|
||||||
|
width:60px;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background:
|
||||||
|
var(--g),
|
||||||
|
var(--g) 10px 10px,
|
||||||
|
var(--g) 20px 20px;
|
||||||
|
background-size: 50% 50%;
|
||||||
|
animation:i5 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i5 {
|
||||||
|
90%,100% {background-position: -30px 30px,-20px 40px,-10px 50px}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-6 {
|
||||||
|
width:60px;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background: var(--g), var(--g), var(--g);
|
||||||
|
background-size: 50% 50%;
|
||||||
|
animation:i6 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i6 {
|
||||||
|
0% {background-position:0 0 ,10px 10px,20px 20px}
|
||||||
|
50% {background-position:0 20px,10px 10px,20px 0 }
|
||||||
|
100% {background-position:20px 20px,10px 10px,0 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-7 {
|
||||||
|
width:60px;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background: var(--g), var(--g), var(--g);
|
||||||
|
background-size: 50% 50%;
|
||||||
|
animation:i7 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i7 {
|
||||||
|
0% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
33% {background-position:-30px 0, 10px 10px, 20px 20px}
|
||||||
|
66% {background-position:-30px 0,-20px 10px, 20px 20px}
|
||||||
|
100% {background-position:-30px 0,-20px 10px,-10px 20px}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-8 {
|
||||||
|
width:60px;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background: var(--g), var(--g), var(--g);
|
||||||
|
background-size: 50% 50%;
|
||||||
|
animation:i8 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i8 {
|
||||||
|
0% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
33% {background-position:-30px 0, 10px 10px, 20px 20px}
|
||||||
|
66% {background-position:-30px 0, 10px 40px, 20px 20px}
|
||||||
|
100% {background-position:-30px 0, 10px 40px, 50px 20px}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-9 {
|
||||||
|
width:60px;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background: var(--g), var(--g), var(--g);
|
||||||
|
background-size: 50% 50%;
|
||||||
|
animation:i9 1s infinite;
|
||||||
|
}
|
||||||
|
@keyframes i9 {
|
||||||
|
0% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
33% {background-position:10px 10px}
|
||||||
|
66% {background-position:0 20px,10px 10px,20px 0 }
|
||||||
|
100% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
}
|
||||||
|
|
||||||
|
.infinity-10 {
|
||||||
|
width:60px;
|
||||||
|
display:flex;
|
||||||
|
align-items:flex-start;
|
||||||
|
aspect-ratio:1;
|
||||||
|
}
|
||||||
|
.infinity-10:before,
|
||||||
|
.infinity-10:after {
|
||||||
|
content:"";
|
||||||
|
flex:1;
|
||||||
|
aspect-ratio:1;
|
||||||
|
--g: conic-gradient(from -90deg at 10px 10px,#fff 90deg,#0000 0);
|
||||||
|
background: var(--g), var(--g), var(--g);
|
||||||
|
filter:drop-shadow(30px 30px 0 #fff);
|
||||||
|
animation:i10 1s infinite;
|
||||||
|
}
|
||||||
|
.infinity-10:after {
|
||||||
|
transform:scaleX(-1);
|
||||||
|
}
|
||||||
|
@keyframes i10 {
|
||||||
|
0% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
33% {background-position:10px 10px}
|
||||||
|
66% {background-position:0 20px,10px 10px,20px 0 }
|
||||||
|
100% {background-position:0 0, 10px 10px, 20px 20px}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { BaseElement } from '../../../shared/_base';
|
||||||
|
import './loading-spinner.less';
|
||||||
|
|
||||||
|
export class LoadingSpinner extends BaseElement {
|
||||||
|
onInit(): void {
|
||||||
|
this.classList.add("infinity-5");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,13 @@ resize-handle[dir="vertical"][place='top'] {
|
|||||||
bottom: auto;
|
bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resize-handle[dir="horizontal"][place='right'] {
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
#fixed-resize-overlay {
|
#fixed-resize-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
session-list-item {
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
session-list-item.selected {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list-item-session-id::before {
|
||||||
|
content: "Session: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list-item-session-id {
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list-item-number-of-changes {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list-item-number-of-changes::before {
|
||||||
|
content: "Number of changes: ";
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
export class SessionListItem extends BaseElement {
|
||||||
|
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("numberOfChanges")) {
|
||||||
|
var numberOfChangesEle = document.createElement("div");
|
||||||
|
numberOfChangesEle.classList.add("session-list-item-number-of-changes");
|
||||||
|
numberOfChangesEle.innerHTML = this.getAttribute("numberOfChanges")?.toString() ?? "";
|
||||||
|
this.appendChild(numberOfChangesEle);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addEventListener("click", (evt) => {
|
||||||
|
this.itemClicked();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private intervalHandle: number | null = null;
|
||||||
|
stopUpdate() {
|
||||||
|
this.classList.remove("selected");
|
||||||
|
|
||||||
|
if (this.intervalHandle) {
|
||||||
|
window.clearInterval(this.intervalHandle);
|
||||||
|
this.intervalHandle = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startUpdate() {
|
||||||
|
this.stopUpdate();
|
||||||
|
|
||||||
|
this.classList.add("selected");
|
||||||
|
|
||||||
|
this.intervalHandle = window.setInterval(this.updateInputs.bind(this), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInputs() {
|
||||||
|
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']");
|
||||||
|
|
||||||
|
this.getSessionData((js, html, css) => {
|
||||||
|
codeEditorJavascriptContainer.setInput(js?.data ?? "");
|
||||||
|
codeEditorHTMLContainer.setInput(html?.data ?? "");
|
||||||
|
codeEditorCSSContainer.setInput(css?.data ?? "");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getSessionData(onGet: (javascript: any, html: any, css: any) => void) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onGet(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];
|
||||||
|
|
||||||
|
containers.style.display = "block";
|
||||||
|
outputframe.style.display = "block";
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("WOULD STOP!");
|
||||||
|
this.stopUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { BaseElement } from '../../../shared/_base';
|
||||||
|
import './session-list.less';
|
||||||
|
import * as sessionApi from '../../../shared/session-api';
|
||||||
|
import { isSessionPage } from '../../../shared/page';
|
||||||
|
|
||||||
|
export class SessionList extends BaseElement {
|
||||||
|
onInit(): void {
|
||||||
|
|
||||||
|
if (isSessionPage()) {
|
||||||
|
var loadingSpinner = document.createElement("loading-spinner");
|
||||||
|
this.appendChild(loadingSpinner);
|
||||||
|
|
||||||
|
this.setUpdate();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.setUpdate();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpdate() {
|
||||||
|
|
||||||
|
sessionApi.getSessions((sessions) => {
|
||||||
|
var loadingSpinner = this.getElementsByTagName("loading-spinner")[0];
|
||||||
|
|
||||||
|
console.log(loadingSpinner);
|
||||||
|
|
||||||
|
if (loadingSpinner) {
|
||||||
|
this.removeChild(loadingSpinner);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let session of sessions) {
|
||||||
|
var exists = document.querySelector("session-list-item[sessionId='" + session.id + "']");
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
var ele = document.createElement("session-list-item");
|
||||||
|
ele.setAttribute("sessionId", session.id);
|
||||||
|
ele.setAttribute("numberOfChanges", session.numberOfChanges);
|
||||||
|
|
||||||
|
this.appendChild(ele);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
exists.setAttribute("numberOfChanges", session.numberOfChanges);
|
||||||
|
exists.getElementsByClassName("session-list-item-number-of-changes")[0].innerHTML = session.numberOfChanges;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function isSessionPage() {
|
||||||
|
return document.URL.indexOf("/sessions") != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isRootPage() {
|
||||||
|
return document.URL.indexOf("/sessions") == -1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
var apiUrl = "https://codeeditor-api.davidssoft.com/";
|
||||||
|
|
||||||
|
function getSessionId() {
|
||||||
|
var localstorageSessionId = localStorage.getItem("sessionId");
|
||||||
|
|
||||||
|
if (!localstorageSessionId) {
|
||||||
|
return setNewSession();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var expiration = localStorage.getItem("sessionIdExpiration");
|
||||||
|
|
||||||
|
if (expiration) {
|
||||||
|
var expirationDate = new Date(expiration);
|
||||||
|
|
||||||
|
if (dateDiff(expirationDate, new Date()) > 120) {
|
||||||
|
return setNewSession();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
localStorage.setItem("sessionIdExpiration", (new Date()).toString());
|
||||||
|
return localstorageSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return setNewSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNewSession() {
|
||||||
|
var newSessionId = uuidv4();
|
||||||
|
localStorage.setItem("sessionIdExpiration", (new Date()).toString());
|
||||||
|
localStorage.setItem("sessionId", newSessionId);
|
||||||
|
|
||||||
|
return newSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dateDiff(startTime: Date, endTime: Date) {
|
||||||
|
var difference = endTime.getTime() - startTime.getTime(); // This will give difference in milliseconds
|
||||||
|
var resultInMinutes = Math.round(difference / 60000);
|
||||||
|
return resultInMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uuidv4() {
|
||||||
|
//@ts-ignore
|
||||||
|
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||||
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSessions(onGet: (sessions: any[]) => void) {
|
||||||
|
fetch(apiUrl + "session/all").then((res) => {
|
||||||
|
res.json().then((jsonRes) => {
|
||||||
|
onGet(jsonRes as any);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSessionData(sessionId: string, onGet: (sessions: any[]) => void) {
|
||||||
|
fetch(apiUrl + "session/data/" + sessionId, { method: "GET" }).then((res) => {
|
||||||
|
res.json().then((jsonRes) => {
|
||||||
|
onGet(jsonRes as any);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSessionData(language: string, input: any, onSet?: () => void) {
|
||||||
|
var type = 0;
|
||||||
|
|
||||||
|
if (language.toLowerCase() == "javascript") {
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
else if (language.toLowerCase() == "html") {
|
||||||
|
type = 1;
|
||||||
|
}
|
||||||
|
else if (language.toLowerCase() == "css") {
|
||||||
|
type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(apiUrl + "session/set", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ sessionId: getSessionId(), timestamp: new Date(), type: type, data: input }) }).then((res) => {
|
||||||
|
if (onSet) {
|
||||||
|
onSet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user