diff --git a/client/authd.ls b/client/authd.ls index 37f8776..1e842e7 100644 --- a/client/authd.ls +++ b/client/authd.ls @@ -6,17 +6,44 @@ module.exports = { create-socket: -> self = {} + request-types = { + \get-token: 0 + \add-user: 1 + \get-user: 2 + \get-user-by-credentials: 3 + \mod-user: 4 + } + + response-types = { + \error: 0 + \token: 1 + \user: 2 + \user-added: 3 + \user-edited: 4 + } + + # TODO: naming convention # users can record functions to run on events - self.user-on-error = [] - self.user-on-close = [] - self.user-on-message = [] + self.user-on-socket-error = [] + self.user-on-close = [] + + self.callbacks = {} + for key, value in response-types + self.callbacks[key] = [] + + # self.user-on-message = [] + + self.add-event-listener = (type, callback) -> + type = response-types[type] + + self.callbacks[type] ++= [callback] self.open-socket = -> console.log "Opening socket to #{socket-url}" self.socket := new WebSocket socket-url self.socket.onerror = (event) -> - for f in self.user-on-error + for f in self.user-on-socket-error f event self.socket.close! @@ -25,10 +52,10 @@ module.exports = { f event self.socket.onmessage = (event) -> - data = JSON.parse(event.data).payload + message = JSON.parse(event.data) - for f in self.user-on-message - f data + for f in self.callbacks[message.type] + f JSON.parse(message.payload) self.reopen = -> self.socket.close! @@ -36,59 +63,50 @@ module.exports = { self.open-socket! - self.send = (opts) -> - console.log JSON.stringify { mtype: 0, payload: opts } - self.socket.send JSON.stringify { mtype: 0, payload: opts } + self.send = (type, opts) -> + console.log JSON.stringify { mtype: type, payload: opts } + self.socket.send JSON.stringify { mtype: type, payload: opts } - self.login = (login, password) -> - self.send JSON.stringify { - type: "login", + self.get-token = (login, password) -> + self.send request-type.get-token, JSON.stringify { login: login password: password } + self.get-user-by-credentials = (login, password) -> + self.send request-type.get-user-by-credentials, JSON.stringify { + login: login + password: password + } + + self.login = (login, password) -> + self.get-token login, password + self.get-user-by-credentials login, password + + + self.get-user = (uid) -> + self.send request-type.get-user, JSON.stringify { + uid: uid + } + + # TODO: authd overhaul + #self.add-user = (login, password) -> + # self.send request-type.add-user, JSON.stringify { + # login: login + # password: password + # } + + # TODO: authd overhaul + #self.mod-user = (uid) -> + # self.send request-type.mod-user, JSON.stringify { + # uid: uid + # } + self - login-widget: (model) -> - h \div.container [ - h \div.box [ - if model.login-error - h \div.notification.is-danger [ - model.login-error - ] - h \form [ - bulma.field [ - bulma.label "Login" - bulma.input { - oninput: (e) -> - model.login = e.target.value - name: \login - id: \login-input - } - ] - bulma.field [ - bulma.label "Password" - bulma.input { - oninput: (e) -> - model.password = e.target.value - name: \password - type: \password - id: \password-input - } - ] - - h \button.button.is-primary { - onclick: (e) -> - e.prevent-default! - - model.login-error = undefined - model.authd-ws.login model.login, model.password - } [ "Connexion" ] - ] - ] - ] - login-page: (model) -> + # XXX: container = marge + # XXX: box = dessiner un contour h \div.container [ h \div.box [ if model.login-error @@ -118,9 +136,10 @@ module.exports = { h \button.button.is-fullwidth.is-primary { onclick: (e) -> + # not to refresh the page since it's a form button e.prevent-default! - model.authd-ws.login model.login, model.password + model.authd-ws.get-token model.login, model.password } [ "Connexion" ] ] ] diff --git a/client/index.ls b/client/index.ls index c0ba4dc..ab1ee02 100644 --- a/client/index.ls +++ b/client/index.ls @@ -6,7 +6,32 @@ # second: # connection to todod # rewrite the whole body component +# page 1: (TODO) list of lists (or todos) +# display: +# navbar # +# "element 1" button +# "element 2" button +# ... +# "element x" button +# +# "new list" button +# widgets: +# navbar: [return to list button] [logout] +# element button: +# [todo list name] +# or +# [todo list name] [RIGTHS] [DELETE] +# +# page 2: +# display: +# (TODO) list of tasks (this client has a kanban display of tasks, with columns) +# (TODO) task widget +# widgets: +# task widget: +# TODO +# +# page 3: (TODO) pages about maquette = require "maquette" nmd = require "nano-markdown" @@ -20,14 +45,24 @@ Project = require "./project.ls" projector = create-projector! model = { + # view: login, todo-list, todo, network-error (TODO: other views, such as rights) current-view: "login" + + # TODO: currently-editing editing: undefined + # TODO: currently-selected selected: undefined + + # { uid => user data } users: {} + + # list of todos-list projects: {} + todo-list: [] port: 9999 + authd-url: undefined todod-url: undefined authd-ws: undefined @@ -36,18 +71,24 @@ model = { previous-error: undefined error: undefined - # authentication token + # TODO: authentication token jwt: undefined } - # '://' + location.hostname + \: + +model.authd-url = + (if location.protocol == 'https' then 'wss' else 'ws') + + '://' + location.hostname + \: + + model.port + + "/auth.JSON" + model.todod-url = - (if location.protocol == 'https' then 'wss' else 'ws') + - "://www.junkos.netlib.re:" + + (if location.protocol == 'https' then 'wss' else 'ws') + + '://' + location.hostname + \: + model.port + "/kanban.JSON" -console.log model.todod-url +console.log "authd url: " + model.authd-url +console.log "todod url: " + model.todod-url # @@ -57,6 +98,54 @@ console.log model.todod-url model.authd-ws = authd.create-socket model.authd-url model.todod-ws = todows.create-socket model.todod-url + +# +# authd messages management +# + +# authd socket errors + +authd-on-websocket-error = (event) -> + console.log "WebSocket error.", event + model.current-view := "network-error" + projector.schedule-render! + +authd-on-websocket-close = (event) -> + model.current-view := "login" + console.log "WebSocket has been closed.", event + # model.todod-ws.reopen! + + projector.schedule-render! + +# record changes that need to happen on a network event +model.authd-ws.user-on-socket-error ++= [ authd-on-websocket-error ] +model.authd-ws.user-on-close ++= [ authd-on-websocket-close ] + + +# authd message handlers + +authd.add-event-listener \token, (message) -> + model.jwt := message.token + model.current-view := "todo-list" + projector.schedule-render! + +authd.add-event-listener \error, (message) -> + console.log "authd error", message + projector.schedule-render! + +authd.add-event-listener \user, (message) -> + model.users[message.user.uid] := message.user + projector.schedule-render! + +# TODO: user-added, user-edited + + +# +# todod messages management +# + +# todod socket errors + on-websocket-error = (event) -> console.log "WebSocket error.", event model.current-view := "network-error" @@ -69,6 +158,7 @@ on-websocket-close = (event) -> projector.schedule-render! + on-websocket-message = (data) -> message = JSON.parse data @@ -92,15 +182,15 @@ on-websocket-message = (data) -> console.log message # record changes that need to happen on a network event -model.todod-ws.user-on-error ++= [ on-websocket-error ] -model.todod-ws.user-on-close ++= [ on-websocket-close ] -model.todod-ws.user-on-message ++= [ on-websocket-message ] +model.todod-ws.user-on-socket-error ++= [ on-websocket-error ] +model.todod-ws.user-on-close ++= [ on-websocket-close ] +model.todod-ws.user-on-message ++= [ on-websocket-message ] render-navbar = -> h \div.navbar [ h \div.navbar-start [ - h \a.navbar-item.is-size-1 { + h \a.navbar-item.is-size-2 { onclick: -> model.viewed-project := undefined model.current-view := "todo-list" @@ -110,10 +200,10 @@ render-navbar = -> h \a.navbar-item { onclick: -> model.current-view := "login" + # TODO: remove anything related to the old session on the client model.todod-ws.reopen! } [ "Logout" ] ] - authd.login-widget model ] render-todo-list = -> @@ -125,18 +215,22 @@ render-todo-list = -> model.viewed-project := project.id model.todod-ws.get-project project.id } [ - bulma.title 3 project.name + bulma.title 4 project.name ] render-new-project-button = -> h \div.button.is-primary.is-large.is-fullwidth { onclick: -> model.todod-ws.new-project "New project" - } [ "New project! (random atm)" ] + } [ "New project!" ] render-todo = (todo-id) -> if model.projects[todo-id] model.projects[todo-id].render! + else + h \div.notification.is-error [ + bulma.title 3 "Error, we did not get the todo id " + todo-id + ] # # Pages: