diff --git a/main.go b/main.go index b13d6ca..0dd810b 100644 --- a/main.go +++ b/main.go @@ -67,10 +67,12 @@ func cssUpdateHandler(w http.ResponseWriter, r *http.Request) {// {{{ func sessionCreate(w http.ResponseWriter, r *http.Request) {// {{{ session, err := NewSession() if err != nil { - w.Write() + responseError(w, err) } - - + responseData(w, map[string]interface{}{ + "OK": true, + "Session": session, + }) }// }}} func websocketHandler(w http.ResponseWriter, r *http.Request) {// {{{ var err error @@ -102,6 +104,9 @@ func staticHandler(w http.ResponseWriter, r *http.Request) {// {{{ // For now to get VERSION into files to fix caching. tmpl, err := newTemplate(r.URL.Path) if err != nil { + if os.IsNotExist(err) { + w.WriteHeader(404) + } w.Write([]byte(err.Error())) return } diff --git a/request_response.go b/request_response.go index b8fed15..9306e15 100644 --- a/request_response.go +++ b/request_response.go @@ -3,10 +3,26 @@ package main import ( // Standard "encoding/json" + "net/http" ) type Request struct { ID string } -func (req *Request) +func responseError(w http.ResponseWriter, err error) { + res := map[string]interface{}{ + "ok": false, + "error": err.Error(), + } + resJSON, _ := json.Marshal(res) + + w.Header().Add("Content-Type", "application/json") + w.Write(resJSON) +} + +func responseData(w http.ResponseWriter, data interface{}) { + resJSON, _ := json.Marshal(data) + w.Header().Add("Content-Type", "application/json") + w.Write(resJSON) +} diff --git a/static/css/login.css b/static/css/login.css index ba3c0df..4fdb19f 100644 --- a/static/css/login.css +++ b/static/css/login.css @@ -3,10 +3,8 @@ justify-items: center; height: 100%; } -#login div { +#login input { max-width: 300px; -} -#login div input { margin-bottom: 32px; width: 100%; border: 0px; @@ -15,6 +13,15 @@ color: #fff; background-color: #494949; } -#login div input:focus { +#login input:focus { outline: none; } +#login button { + max-width: 300px; + border: 1px solid #666; + background: #494949; + color: #fff; + padding: 16px 32px; + font-size: 0.8em; + align-self: center; +} diff --git a/static/index.html b/static/index.html index 54e2af9..1cef8b4 100644 --- a/static/index.html +++ b/static/index.html @@ -17,6 +17,8 @@ "@preact/signals-core": "/js/{{ .VERSION }}/lib/signals/signals-core.mjs", "preact/signals": "/js/{{ .VERSION }}/lib/signals/signals.mjs", "htm": "/js/{{ .VERSION }}/lib/htm/htm.mjs" + + "session": "/js/{{ .VERSION }}/session.mjs" } } diff --git a/static/js/app.mjs b/static/js/app.mjs index a27ca1a..3c86a6d 100644 --- a/static/js/app.mjs +++ b/static/js/app.mjs @@ -3,6 +3,7 @@ import 'preact/devtools' //import { signal } from 'preact/signals' import { h, Component, render, createRef } from 'preact' import htm from 'htm' +import Session from 'session' const html = htm.bind(h) class App extends Component { @@ -14,7 +15,7 @@ class App extends Component { this.wsConnect() this.wsLoop() - this.sessionID = window.localStorage.getItem("sessionID") + }//}}} render() {//{{{ if(this.sessionID === null) { @@ -63,6 +64,51 @@ class App extends Component { } }//}}} + responseError({comm, app}) {//{{{ + if(comm !== undefined) { + comm.text().then(body=>alert(body)) + return + } + + if(app !== undefined && app.hasOwnProperty('error')) { + alert(app.error) + return + } + + if(app !== undefined) { + alert(JSON.stringify(app)) + } + }//}}} + async request(url, params) {//{{{ + return new Promise((resolve, reject)=>{ + let headers = { + 'Content-Type': 'application/json', + } + + if(this.sessionID !== null) + headers['X-SESSION-ID'] = this.sessionID + + fetch(url, { + method: 'POST', + headers, + body: JSON.stringify(params), + }) + .then(response=>{ + // A HTTP communication level error occured + if(!response.ok || response.status != 200) + return reject({comm: response}) + return response.json() + }) + .then(json=>{ + // An application level error occured + if(!json.OK) + return reject({app: json}) + return resolve(json) + }) + .catch(err=>reject({comm: err})) + }) + }//}}} + broadcastHandler(msg) {//{{{ switch(msg.Op) { case 'css_reload': @@ -70,20 +116,44 @@ class App extends Component { break; } }//}}} + login(username, password) {//{{{ + this.request('/session/create', {}) + .then(res=>{ + this.setSessionID(res.Session.UUID) + }) + .catch(this.responseError) + }//}}} + + getSessionID() { + return window.localStorage.getItem("sessionID") + } + setSessionID(uuid) { + console.log('wut') + this.sessionID = uuid + window.localStorage.setItem('sessionID', uuid) + } } class Login extends Component { - render() { + render() {//{{{ return html`

Notes

-
- - -
+ { if(evt.code == 'Enter') this.login() }} /> + { if(evt.code == 'Enter') this.login() }} /> +
` - } + }//}}} + componentDidMount() {//{{{ + document.getElementById('username').focus() + }//}}} + + login() {//{{{ + let username = document.getElementById('username').value + let password = document.getElementById('password').value + window._app.current.login(username, password) + }//}}} } // Init{{{ diff --git a/static/less/login.less b/static/less/login.less index 6e4f219..18210cb 100644 --- a/static/less/login.less +++ b/static/less/login.less @@ -5,22 +5,29 @@ justify-items: center; height: 100%; - div { + input { max-width: 300px; + margin-bottom: 32px; + width: 100%; + border: 0px; + border-bottom: 1px solid #fff; - input { - margin-bottom: 32px; - width: 100%; - border: 0px; - border-bottom: 1px solid #fff; - - font-size: 18pt; - color: #fff; - background-color: @background; - - &:focus { - outline: none; - } + font-size: 18pt; + color: #fff; + background-color: @background; + + &:focus { + outline: none; } } + + button { + max-width: 300px; + border: 1px solid #666; + background: @background; + color: #fff; + padding: 16px 32px; + font-size: 0.8em; + align-self: center; + } } diff --git a/static/session.mjs b/static/session.mjs new file mode 100644 index 0000000..d6c1dc7 --- /dev/null +++ b/static/session.mjs @@ -0,0 +1,12 @@ +export class Session { + static createFromStorage() { + let session = new Session() + session.UUID + } + + constructor() { + this.UUID = '' + this.authenticated = false + this.UserID = 0 + } +}