From f7732295a20ea4390b52b7c102ddcdc89c2d784c Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 19 Jun 2017 16:20:46 +0200 Subject: [PATCH] Started working on scripts --- .vscode/settings.json | 9 +++ .vscode/tasks.json | 10 ++++ layout/layout.pixy | 2 +- scripts/Aero/Aero.ts | 126 +++++++++++++++++++++++++++++++++++++++++ scripts/hello.ts | 5 -- scripts/main.ts | 24 +++++++- styles/loading.scarlet | 2 +- tsconfig.json | 4 +- 8 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 scripts/Aero/Aero.ts delete mode 100644 scripts/hello.ts diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..d9d11d03 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "tsimporter.emitSemicolon": false, + "tsimporter.doubleQuotes": true, + "files.exclude": { + "**/*.js": { + "when": "$(basename).ts" + } + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..6aaaf676 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,10 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "0.1.0", + "command": "tsc", + "isShellCommand": true, + "args": ["-p", "."], + "showOutput": "silent", + "problemMatcher": "$tsc" +} \ No newline at end of file diff --git a/layout/layout.pixy b/layout/layout.pixy index a1c0214c..84c4225c 100644 --- a/layout/layout.pixy +++ b/layout/layout.pixy @@ -16,7 +16,7 @@ component Layout(app *aero.Application, user *arn.User, content string) script(src="/scripts.js") component LoadingAnimation - #loading-animation.sk-cube-grid.fade + #loading.sk-cube-grid.fade .sk-cube.hide .sk-cube .sk-cube.hide diff --git a/scripts/Aero/Aero.ts b/scripts/Aero/Aero.ts new file mode 100644 index 00000000..230d530f --- /dev/null +++ b/scripts/Aero/Aero.ts @@ -0,0 +1,126 @@ +class Aero { + ajaxClass: string + fadeOutClass: string + content: HTMLElement + loading: HTMLElement + currentURL: string + originalURL: string + lastRequest: XMLHttpRequest + + constructor() { + this.currentURL = window.location.pathname + this.originalURL = window.location.pathname + this.ajaxClass = "ajax" + this.fadeOutClass = "fade-out" + } + + find(id: string): HTMLElement { + return document.getElementById(id) + } + + get(url: string): Promise { + return new Promise((resolve, reject) => { + let request = new XMLHttpRequest() + + request.onerror = () => reject(new Error("You are either offline or the requested page doesn't exist.")) + request.ontimeout = () => reject(new Error("The page took too much time to respond.")) + request.onload = () => { + if(request.status < 200 || request.status >= 400) + reject(request.responseText) + else + resolve(request.responseText) + } + + request.open("GET", url, true) + request.send() + + this.lastRequest = request + }) + } + + load(url: string, addToHistory: boolean) { + if(this.lastRequest) { + this.lastRequest.abort() + this.lastRequest = null + } + + this.currentURL = url + + console.log(url) + + // function sleep(ms) { + // return new Promise(resolve => setTimeout(resolve, ms)) + // } + + // sleep(500).then(() => { + + // }) + + let request = this.get("/_" + url) + + this.content.addEventListener("transitionend", e => { + request.then(html => { + if(addToHistory) + history.pushState(url, null, url) + + this.setContent(html) + this.scrollToTop() + + this.content.classList.remove(this.fadeOutClass) + this.loading.classList.add(this.fadeOutClass) + }) + }, { once: true }) + + this.content.classList.add(this.fadeOutClass) + this.loading.classList.remove(this.fadeOutClass) + } + + setContent(html: string) { + this.content.innerHTML = html + this.ajaxify(this.content) + } + + ajaxify(element?: HTMLElement) { + if(!element) + element = document.body + + let links = element.querySelectorAll("." + this.ajaxClass) + + for(let i = 0; i < links.length; i++) { + let link = links[i] as HTMLElement + + link.classList.remove(this.ajaxClass) + link.onclick = function(e) { + // Middle mouse button should have standard behaviour + if(e.which === 2) + return + + let url = this.getAttribute("href") + + e.preventDefault() + e.stopPropagation() + + if(!url || url === window.location.pathname) + return + + // Load requested page + aero.load(url, true) + } + } + } + + run() { + this.ajaxify() + this.loading.classList.add(this.fadeOutClass) + } + + scrollToTop() { + let parent = this.content + + while(parent = parent.parentElement) { + parent.scrollTop = 0 + } + } +} + +export var aero = new Aero() \ No newline at end of file diff --git a/scripts/hello.ts b/scripts/hello.ts deleted file mode 100644 index 37ed226b..00000000 --- a/scripts/hello.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class Greeter { - greet(name: string) { - console.log("Hello, " + name) - } -} \ No newline at end of file diff --git a/scripts/main.ts b/scripts/main.ts index b5e9020d..4ccebc0e 100644 --- a/scripts/main.ts +++ b/scripts/main.ts @@ -1,4 +1,22 @@ -import {Greeter} from "scripts/hello" +import { aero as app } from "./Aero/Aero" -var greeter = new Greeter() -greeter.greet("World") \ No newline at end of file +class AnimeNotifier { + constructor() { + app.content = app.find("content") + app.loading = app.find("loading") + app.run() + } +} + +document.onreadystatechange = function() { + if(document.readyState === "interactive") { + let arn = new AnimeNotifier() + } +} + +window.onpopstate = e => { + if(e.state) + app.load(e.state, false) + else if(app.currentURL !== app.originalURL) + app.load(app.originalURL, false) +} \ No newline at end of file diff --git a/styles/loading.scarlet b/styles/loading.scarlet index a979a123..2aebb5b0 100644 --- a/styles/loading.scarlet +++ b/styles/loading.scarlet @@ -1,7 +1,7 @@ loading-anim-duration = 0.8s loading-anim-size = 24px -#loading-animation +#loading position fixed bottom 1.15rem right calc(1.15rem + 17px) diff --git a/tsconfig.json b/tsconfig.json index 297c326b..12fff16d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,8 @@ "target": "es6", "module": "commonjs", "moduleResolution": "node", - "baseUrl": "./" + "baseUrl": "." }, - "compileOnSave": false, + "compileOnSave": true, "buildOnSave": false } \ No newline at end of file