code-editor
Changes
codeeditor-app/app.html 5(+5 -0)
codeeditor-app/boot.ts 21(+20 -1)
shared/page.ts 7(+7 -0)
shared/session-api.ts 90(+90 -0)
Details
codeeditor-app/app.html 5(+5 -0)
diff --git a/codeeditor-app/app.html b/codeeditor-app/app.html
index d803575..2a4fe52 100644
--- a/codeeditor-app/app.html
+++ b/codeeditor-app/app.html
@@ -2,12 +2,17 @@
<div class="flex-shrink section top">
<h1>code editor</h1>
<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='HTML']">HTML</window-control-connector>
<window-control-connector target="code-editor-container[language='CSS']">CSS</window-control-connector>
</window-control>
</div>
<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">
<code-editor-container language="Javascript" dir="vertical" class="first-visible last-visible">
</code-editor-container>
codeeditor-app/boot.ts 21(+20 -1)
diff --git a/codeeditor-app/boot.ts b/codeeditor-app/boot.ts
index b990417..8fd4372 100644
--- a/codeeditor-app/boot.ts
+++ b/codeeditor-app/boot.ts
@@ -12,6 +12,10 @@ import { JavascriptCodeEditor } from './elements/code-editor/javascript-code-edi
import { HtmlCodeEditor } from './elements/code-editor/html-code-editor';
import { CssCodeEditor } from './elements/code-editor/css-code-editor';
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('code-editor-container', CodeEditorContainer);
@@ -24,8 +28,23 @@ window.customElements.define('notification-bubble', NotificationBubble);
window.customElements.define('resize-handle', ResizeHandle);
window.customElements.define('window-control', WindowControl);
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;
+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();
diff --git a/codeeditor-app/elements/code-editor/code-editor.ts b/codeeditor-app/elements/code-editor/code-editor.ts
index 74ca11c..b7390c6 100644
--- a/codeeditor-app/elements/code-editor/code-editor.ts
+++ b/codeeditor-app/elements/code-editor/code-editor.ts
@@ -3,11 +3,14 @@ import './code-editor.less';
import * as monaco from 'monaco-editor';
import { OutputFrame } from "../output-frame/output-frame";
import { debounceManager } from "../../../shared/ensure-debounce";
+import * as sessionApi from '../../../shared/session-api';
+import { isSessionPage } from "../../../shared/page";
export class CodeEditor extends BaseElement {
public input: string = "";
public language: string = "";
+ public editor!: monaco.editor.IStandaloneCodeEditor;
onInit(): void {
@@ -18,11 +21,12 @@ export class CodeEditor extends BaseElement {
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
- var editor = monaco.editor.create(this, {
- value: this.input,
+ this.editor = monaco.editor.create(this, {
+ value: isSessionPage() ? "" : this.input,
language: this.language,
automaticLayout: true,
contextmenu: false,
+ readOnly: isSessionPage(),
minimap: {
enabled: false
},
@@ -31,19 +35,30 @@ export class CodeEditor extends BaseElement {
});
var debounce = debounceManager(1000);
- editor.onDidChangeModelContent((e) => {
- this.input = editor.getValue();
- debounce.ensureDebounce(() => {
- this.outputFrame.setContent(this.language, this.input);
- });
+ this.editor.onDidChangeModelContent((e) => {
+ if (!isSessionPage()) {
+ this.input = this.editor.getValue();
+ debounce.ensureDebounce(() => {
+ sessionApi.setSessionData(this.language, this.input);
+ this.outputFrame.setContent(this.language, this.input);
+ });
+ }
});
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 {
return "";
}
diff --git a/codeeditor-app/elements/code-editor-container/code-editor-container.ts b/codeeditor-app/elements/code-editor-container/code-editor-container.ts
index 665fbd4..ceee3e1 100644
--- a/codeeditor-app/elements/code-editor-container/code-editor-container.ts
+++ b/codeeditor-app/elements/code-editor-container/code-editor-container.ts
@@ -4,6 +4,7 @@ import { ResizeHandle } from "../resize-handle/resize-handle";
import './code-editor-container.less';
export class CodeEditorContainer extends BaseElement {
+ private codeEditor: CodeEditor | null = null;
onInit(): void {
var language = this.getAttribute("language");
this.classList.add("flex-vert");
@@ -22,11 +23,15 @@ export class CodeEditorContainer extends BaseElement {
this.appendChild(div);
}
+ setInput(input: any) {
+ this.codeEditor?.setInput(input);
+ }
+
createCodeEditor(language: string, expandDir: 'vertical' | 'horizontal') {
var codeEditorContent = document.createElement("div");
codeEditorContent.classList.add("code-editor-content");
- var codeEditor = <CodeEditor>document.createElement(language + "-code-editor");
- codeEditorContent.appendChild(codeEditor);
+ this.codeEditor = <CodeEditor>document.createElement(language + "-code-editor");
+ codeEditorContent.appendChild(this.codeEditor);
var resizeHandle = <ResizeHandle>document.createElement("resize-handle");
resizeHandle.setAttribute("dir", expandDir);
diff --git a/codeeditor-app/elements/loading-spinner/loading-spinner.less b/codeeditor-app/elements/loading-spinner/loading-spinner.less
new file mode 100644
index 0000000..715e310
--- /dev/null
+++ b/codeeditor-app/elements/loading-spinner/loading-spinner.less
@@ -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}
+ }
+
\ No newline at end of file
diff --git a/codeeditor-app/elements/loading-spinner/loading-spinner.ts b/codeeditor-app/elements/loading-spinner/loading-spinner.ts
new file mode 100644
index 0000000..bd59f31
--- /dev/null
+++ b/codeeditor-app/elements/loading-spinner/loading-spinner.ts
@@ -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");
+ }
+}
\ No newline at end of file
diff --git a/codeeditor-app/elements/resize-handle/resize-handle.less b/codeeditor-app/elements/resize-handle/resize-handle.less
index 78b4719..daae0bc 100644
--- a/codeeditor-app/elements/resize-handle/resize-handle.less
+++ b/codeeditor-app/elements/resize-handle/resize-handle.less
@@ -34,6 +34,13 @@ resize-handle[dir="vertical"][place='top'] {
bottom: auto;
}
+resize-handle[dir="horizontal"][place='right'] {
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: auto;
+}
+
#fixed-resize-overlay {
position: fixed;
left: 0;
diff --git a/codeeditor-app/elements/session-list/session-list.less b/codeeditor-app/elements/session-list/session-list.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/codeeditor-app/elements/session-list/session-list.less
diff --git a/codeeditor-app/elements/session-list/session-list.ts b/codeeditor-app/elements/session-list/session-list.ts
new file mode 100644
index 0000000..090c041
--- /dev/null
+++ b/codeeditor-app/elements/session-list/session-list.ts
@@ -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;
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/codeeditor-app/elements/session-list-item/session-list-item.less b/codeeditor-app/elements/session-list-item/session-list-item.less
new file mode 100644
index 0000000..9995337
--- /dev/null
+++ b/codeeditor-app/elements/session-list-item/session-list-item.less
@@ -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;
+}
\ No newline at end of file
diff --git a/codeeditor-app/elements/session-list-item/session-list-item.ts b/codeeditor-app/elements/session-list-item/session-list-item.ts
new file mode 100644
index 0000000..3549be3
--- /dev/null
+++ b/codeeditor-app/elements/session-list-item/session-list-item.ts
@@ -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();
+ }
+ }
+}
\ No newline at end of file
shared/page.ts 7(+7 -0)
diff --git a/shared/page.ts b/shared/page.ts
new file mode 100644
index 0000000..cc222c0
--- /dev/null
+++ b/shared/page.ts
@@ -0,0 +1,7 @@
+export function isSessionPage() {
+ return document.URL.indexOf("/sessions") != -1;
+}
+
+export function isRootPage() {
+ return document.URL.indexOf("/sessions") == -1;
+}
\ No newline at end of file
shared/session-api.ts 90(+90 -0)
diff --git a/shared/session-api.ts b/shared/session-api.ts
new file mode 100644
index 0000000..580e158
--- /dev/null
+++ b/shared/session-api.ts
@@ -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();
+ }
+ });
+}
\ No newline at end of file