# first: # connection to authd # display the authd widget # # 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" authd = require "./authd.ls" todows = require "./todowebsocket.ls" bulma = require "./bulma.ls" Task = require "./task.ls" Project = require "./project.ls" {create-projector, h} = maquette 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 todod-ws: undefined previous-error: undefined error: undefined # TODO: authentication token jwt: undefined } 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') + '://' + location.hostname + \: + model.port + "/todo.JSON" console.log "authd url: " + model.authd-url console.log "todod url: " + model.todod-url # # network configuration # 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-socket-close ++= [ authd-on-websocket-close ] # authd message handlers model.authd-ws.add-event-listener \token, (message) -> model.jwt := message.token model.current-view := "todo-list" model.todod-ws.list-lists model.jwt projector.schedule-render! model.authd-ws.add-event-listener \error, (message) -> console.log "authd error", message projector.schedule-render! model.authd-ws.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" projector.schedule-render! on-websocket-close = (event) -> model.current-view := "login" console.log "WebSocket has been closed.", event # model.todod-ws.reopen! projector.schedule-render! # TODO # on-websocket-message = (data) -> # message = JSON.parse data # # switch message.type # when "login" # model.current-view := "todo-list" # when "list-projects" # when "project" # model.projects[message.project.id] = Project.new message.project, model # when "user" # if message.user # model.users[message.user.uid] := message.user # record changes that need to happen on a network event model.todod-ws.user-on-socket-error ++= [ on-websocket-error ] model.todod-ws.user-on-socket-close ++= [ on-websocket-close ] model.todod-ws.add-event-listener \lists-list, (message) -> console.log message model.todo-list := message.lists projector.schedule-render! render-navbar = -> h \div.navbar [ h \div.navbar-start [ h \a.navbar-item.is-size-2 { onclick: -> model.viewed-project := undefined model.current-view := "todo-list" } [ "⌂" ] ] h \div.navbar-end [ 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" ] ] ] render-todo-list = -> h \div.section model.todo-list.map (project) -> h \a.box { key: project.id onclick: -> model.current-view := "todo" model.viewed-project := project.id model.todod-ws.get-project project.id } [ bulma.title 4 project.title ] render-new-project-button = -> h \div.button.is-primary.is-large.is-fullwidth { onclick: -> model.todod-ws.new-project "New project" } [ "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: # login # todo-list # todo # network-error # render-body = -> h \div.section [ switch model.current-view when "login" authd.login-page model when "todo-list" h \div#todo-list [ render-navbar! render-todo-list! render-new-project-button! ] when "todo" h \div [ render-navbar! render-todo model.viewed-project ] else h \div.notification.is-error [ "Wait, what? Internal error!" ] ] renderer = -> render-navbar! render-body! document.add-event-listener 'DOMContentLoaded' -> projector.append document.body, renderer