Format with purty.
[?]
Jan 25, 2021, 12:54 AM
QH4UB73NUR2XPHZQ2RGJBKKUBN43RKC7ZJBCFPP4ESUIIEDDR5XQCDependencies
- [2]
B4MTB6UOPersist project across pages. - [3]
ZIG57EE6Fix project selection, end log end on project switch. - [4]
TKGBRIQTLogin component now raises LoginComplete message. - [5]
QMEYU4MWAdd display for prior intervals. - [6]
5R2Z7FSXInitial rendering for signup controls. - [7]
ARX7SHY5Begin work on login UI. - [8]
EA5BFM5GSplit Login component into its own module. - [9]
IR75ZMX3Return actual events for interval ends, not just timestamps. - [10]
OUR4PAOTUse local dates for display of intervals. - [11]
ENNZIQJGUse live signup API for client. - [12]
PT4276XCAdd logout functionality. - [13]
BFZN4SUAMake timeline component work. - [14]
NJNMO72SAdd zcash.com submodule and update client to modern halogen. - [15]
TUA4HMUDUse real API capability for login. - [16]
2J37EVJMCheck for an open interval on project switch. - [17]
RSF6UAJKBreak out api module for timeline. - [18]
J6S23MDGUse server timestamps for interval start and end. - [19]
HO2PFRABClient login now handles response correctly. - [20]
JXG3FCXYUpgrade ps + halogen versions. - [21]
QAC2QJ32Add project overview page to client. - [22]
3LMXT7Z6preventDefault on login form submission. - [23]
SAESJLLYInitial experiments in hash routing. - [24]
U256ZALIAdd captcha check to register route. - [25]
5IDB3IWSIntegrate zcashd-based zaddr validation. - [26]
QU5FW67RAdd project selection to time tracker. - [27]
AAALU5A2Fix client routing - [28]
QQXR7DTORework login component to use more appropriate Bootstrap theme. - [29]
WRPIYG3EUse project listing functionality to check for whether we have a cookie. - [30]
O2BZOX7MAdd signup form, captcha check. - [*]
RB2ETNIFAdd skeletal PureScript client project.
Change contents
- edit in client/.gitignore at line 12
.nvimrc - edit in client/package-lock.json at line 5856
"purty": {"version": "6.3.0","resolved": "https://registry.npmjs.org/purty/-/purty-6.3.0.tgz","integrity": "sha512-l70uQyz+t5GvCPzOorUbIhRX3oQW9i8Kgwr0LvS6nUq+UM4rMJdYcHazuupcLVInvNsbd290EnpjaRgAITt0dw=="}, - edit in client/package.json at line 17
"purty": "^6.3.0", - edit in client/src/Aftok/Api/Account.purs at line 4
- edit in client/src/Aftok/Api/Account.purs at line 8
- replacement in client/src/Aftok/Api/Account.purs at line 15
type LoginRequest = { username :: String, password :: String }type LoginRequest= { username :: String, password :: String } - replacement in client/src/Aftok/Api/Account.purs at line 27
result <- post RF.ignore "/api/login" (Just <<< RB.Json <<< encodeJson $ { username: user, password : pass })result <- post RF.ignore "/api/login" (Just <<< RB.Json <<< encodeJson $ { username: user, password: pass }) - replacement in client/src/Aftok/Api/Account.purs at line 29
Left err -> log ("Login failed: " <> printError err)Right r -> log ("Login status: " <> show r.status)pure $ case result ofLeft err -> LoginError { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 -> LoginForbiddenStatusCode 200 -> LoginOKother -> LoginError { status: Just other, message: r.statusText }Left err -> log ("Login failed: " <> printError err)Right r -> log ("Login status: " <> show r.status)pure$ case result ofLeft err -> LoginError { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 -> LoginForbiddenStatusCode 200 -> LoginOKother -> LoginError { status: Just other, message: r.statusText } - replacement in client/src/Aftok/Api/Account.purs at line 46
pure $ case r.status ofStatusCode 200 -> LoginOKStatusCode _ -> LoginForbiddenpure$ case r.status ofStatusCode 200 -> LoginOKStatusCode _ -> LoginForbidden - replacement in client/src/Aftok/Api/Account.purs at line 56
| RecoverByZAddr String| RecoverByZAddr String - replacement in client/src/Aftok/Api/Account.purs at line 58
type SignupRequest ={ username :: String, password :: String, recoverBy :: RecoverBy, captchaToken :: String}type SignupRequest= { username :: String, password :: String, recoverBy :: RecoverBy, captchaToken :: String} - replacement in client/src/Aftok/Api/Account.purs at line 66
signupRequest username password recoverBy captchaToken ={ username, password, recoverBy, captchaToken }signupRequest username password recoverBy captchaToken = { username, password, recoverBy, captchaToken } - replacement in client/src/Aftok/Api/Account.purs at line 97
result <- get RF.ignore ("/api/validate_zaddr?zaddr=" <> zaddr)result <- get RF.ignore ("/api/validate_zaddr?zaddr=" <> zaddr) - replacement in client/src/Aftok/Api/Account.purs at line 102
Right r | r.status == StatusCode 200 -> dopure ZAddrCheckValidRight r| r.status == StatusCode 200 -> dopure ZAddrCheckValid - replacement in client/src/Aftok/Api/Account.purs at line 111[3.2985]→[3.121:154](∅→∅),[3.154]→[3.456:568](∅→∅),[3.456]→[3.456:568](∅→∅),[3.568]→[3.833:1189](∅→∅),[3.1189]→[3.155:196](∅→∅),[3.974]→[3.155:196](∅→∅),[3.196]→[3.974:984](∅→∅),[3.974]→[3.974:984](∅→∅)
let signupJSON = encodeJson ${ username: req.username, password: req.password, recoveryType: case req.recoverBy ofRecoverByEmail _ -> "email"RecoverByZAddr _ -> "zaddr", recoveryEmail: case req.recoverBy ofRecoverByEmail email -> Just emailRecoverByZAddr _ -> Nothing, recoveryZAddr: case req.recoverBy ofRecoverByEmail _ -> NothingRecoverByZAddr zaddr -> Just zaddr, captchaToken: req.captchaToken}letsignupJSON =encodeJson$ { username: req.username, password: req.password, recoveryType:case req.recoverBy ofRecoverByEmail _ -> "email"RecoverByZAddr _ -> "zaddr", recoveryEmail:case req.recoverBy ofRecoverByEmail email -> Just emailRecoverByZAddr _ -> Nothing, recoveryZAddr:case req.recoverBy ofRecoverByEmail _ -> NothingRecoverByZAddr zaddr -> Just zaddr, captchaToken: req.captchaToken} - replacement in client/src/Aftok/Api/Account.purs at line 136
Right r | r.status == StatusCode 200 -> dolog "Registration succeeded!"pure SignupOKRight r | r.status == StatusCode 403 -> dolog ("Registration failed: Capcha Invalid")pure CaptchaInvalidRight r | r.status == StatusCode 400 -> dolog ("Registration failed: Z-Address Invalid")pure ZAddrInvalidRight r| r.status == StatusCode 200 -> dolog "Registration succeeded!"pure SignupOKRight r| r.status == StatusCode 403 -> dolog ("Registration failed: Capcha Invalid")pure CaptchaInvalidRight r| r.status == StatusCode 400 -> dolog ("Registration failed: Z-Address Invalid")pure ZAddrInvalid - edit in client/src/Aftok/Api/Account.purs at line 151[3.1922]→[3.1922:1926](∅→∅),[3.1926]→[3.422:423](∅→∅),[3.422]→[3.422:423](∅→∅),[3.423]→[3.3001:3004](∅→∅),[3.984]→[3.3001:3004](∅→∅),[3.3001]→[3.3001:3004](∅→∅)
- replacement in client/src/Aftok/Api/Recaptcha.purs at line 1
module Aftok.Api.Recaptchamodule Aftok.Api.Recaptcha - replacement in client/src/Aftok/Api/Recaptcha.purs at line 13
Nothing -> getRecaptchaResponseInternal false ""Nothing -> getRecaptchaResponseInternal false "" - edit in client/src/Aftok/Api/Timeline.purs at line 4
- edit in client/src/Aftok/Api/Timeline.purs at line 7
- edit in client/src/Aftok/Api/Timeline.purs at line 22
- edit in client/src/Aftok/Api/Timeline.purs at line 24
- edit in client/src/Aftok/Api/Timeline.purs at line 27
- edit in client/src/Aftok/Api/Timeline.purs at line 28
- replacement in client/src/Aftok/Api/Timeline.purs at line 46
StopEvent t -> tStopEvent t -> t - replacement in client/src/Aftok/Api/Timeline.purs at line 67
StopEvent a -> StopEvent <$> f aStopEvent a -> StopEvent <$> f a - replacement in client/src/Aftok/Api/Timeline.purs at line 74
stop' <- traverse (_ .: "eventTime") =<< ev .:? "stop"note "Only 'stop' and 'start' events are supported." $(StartEvent <$> start') <|>(StopEvent <$> stop')stop' <- traverse (_ .: "eventTime") =<< ev .:? "stop"note "Only 'stop' and 'start' events are supported."$ (StartEvent <$> start')<|> (StopEvent <$> stop') - replacement in client/src/Aftok/Api/Timeline.purs at line 82
newtype KeyedEvent i = KeyedEventnewtype KeyedEvent i= KeyedEvent - replacement in client/src/Aftok/Api/Timeline.purs at line 113
newtype Interval i = Intervalnewtype Interval i= Interval - edit in client/src/Aftok/Api/Timeline.purs at line 120
- replacement in client/src/Aftok/Api/Timeline.purs at line 126
type TimeInterval = Interval Instanttype TimeInterval= Interval Instant - replacement in client/src/Aftok/Api/Timeline.purs at line 159
type TimeSpan = TimeSpan' DateTimetype TimeSpan= TimeSpan' DateTime - edit in client/src/Aftok/Api/Timeline.purs at line 163
- replacement in client/src/Aftok/Api/Timeline.purs at line 168
After a -> f a bAfter a -> f a b - replacement in client/src/Aftok/Api/Timeline.purs at line 172
After a -> f b aAfter a -> f b a - replacement in client/src/Aftok/Api/Timeline.purs at line 179
After a -> After <$> f aAfter a -> After <$> f a - replacement in client/src/Aftok/Api/Timeline.purs at line 184
let requestBody = Just <<< RB.Json <<< encodeJson $ { schemaVersion: "2.0" }letrequestBody = Just <<< RB.Json <<< encodeJson $ { schemaVersion: "2.0" } - replacement in client/src/Aftok/Api/Timeline.purs at line 187
liftEffect <<< runExceptT $ dokev <- withExceptT LogFailure $ parseDatedResponse responsecase event kev ofStartEvent _ -> pure kevStopEvent _ -> throwError <<< Unexpected $ "Expected start event, got stop."liftEffect <<< runExceptT$ dokev <- withExceptT LogFailure $ parseDatedResponse responsecase event kev ofStartEvent _ -> pure kevStopEvent _ -> throwError <<< Unexpected $ "Expected start event, got stop." - replacement in client/src/Aftok/Api/Timeline.purs at line 196
let requestBody = Just <<< RB.Json <<< encodeJson $ { schemaVersion: "2.0" }letrequestBody = Just <<< RB.Json <<< encodeJson $ { schemaVersion: "2.0" } - replacement in client/src/Aftok/Api/Timeline.purs at line 199[3.4431]→[3.4431:4464](∅→∅),[3.4464]→[3.5076:5162](∅→∅),[3.5162]→[3.4548:4632](∅→∅),[3.4548]→[3.4548:4632](∅→∅),[3.4632]→[3.5163:5194](∅→∅)
liftEffect <<< runExceptT $ dokev <- withExceptT LogFailure $ parseDatedResponse responsecase event kev ofStartEvent _ -> throwError <<< Unexpected $ "Expected stop event, got start."StopEvent _ -> pure kevliftEffect <<< runExceptT$ dokev <- withExceptT LogFailure $ parseDatedResponse responsecase event kev ofStartEvent _ -> throwError <<< Unexpected $ "Expected stop event, got start."StopEvent _ -> pure kev - replacement in client/src/Aftok/Api/Timeline.purs at line 206
newtype ListIntervalsResponse a = ListIntervalsResponsenewtype ListIntervalsResponse a= ListIntervalsResponse - edit in client/src/Aftok/Api/Timeline.purs at line 212
- replacement in client/src/Aftok/Api/Timeline.purs at line 222
let traverseCreditRow r' = ({ intervals: _ }) <$> traverse f r'.intervalsin (ListIntervalsResponse <<< ({ workIndex: _ })) <$> traverse traverseCreditRow r.workIndexlettraverseCreditRow r' = ({ intervals: _ }) <$> traverse f r'.intervalsin(ListIntervalsResponse <<< ({ workIndex: _ })) <$> traverse traverseCreditRow r.workIndex - replacement in client/src/Aftok/Api/Timeline.purs at line 234
let queryElements = case ts' ofBefore t -> ["before=" <> t, "limit=100"]During (Interval x) -> ["after=" <> x.start, "before=" <> x.end, "limit=100"]After t -> ["after=" <> t, "limit=100"]letqueryElements = case ts' ofBefore t -> [ "before=" <> t, "limit=100" ]During (Interval x) -> [ "after=" <> x.start, "before=" <> x.end, "limit=100" ]After t -> [ "after=" <> t, "limit=100" ] - replacement in client/src/Aftok/Api/Timeline.purs at line 245
$ parseDatedResponse response$ parseDatedResponse response - replacement in client/src/Aftok/Api/Timeline.purs at line 255
$ parseDatedResponse response[3.5660]$ parseDatedResponse response - edit in client/src/Aftok/Login.purs at line 4
- edit in client/src/Aftok/Login.purs at line 5
- edit in client/src/Aftok/Login.purs at line 6
- edit in client/src/Aftok/Login.purs at line 7
- edit in client/src/Aftok/Login.purs at line 14
- edit in client/src/Aftok/Login.purs at line 15
- edit in client/src/Aftok/Login.purs at line 16
- replacement in client/src/Aftok/Login.purs at line 20
= Forbidden= Forbidden - replacement in client/src/Aftok/Login.purs at line 23[3.269]→[3.295797:295815](∅→∅),[3.295815]→[3.288:311](∅→∅),[3.288]→[3.288:311](∅→∅),[3.311]→[3.295816:295839](∅→∅),[3.295839]→[3.3969:4004](∅→∅),[3.4004]→[3.376:380](∅→∅),[3.376]→[3.376:380](∅→∅)
type LoginState ={ username :: String, password :: String, loginError :: Maybe LoginError}type LoginState= { username :: String, password :: String, loginError :: Maybe LoginError} - replacement in client/src/Aftok/Login.purs at line 34
data LoginResultdata LoginResult - replacement in client/src/Aftok/Login.purs at line 37
type Slot id = forall query. H.Slot query LoginResult idtype Slot id= forall query. H.Slot query LoginResult id - replacement in client/src/Aftok/Login.purs at line 40[3.833]→[3.296010:296080](∅→∅),[3.296080]→[3.161:216](∅→∅),[3.216]→[3.296080:296084](∅→∅),[3.296080]→[3.296080:296084](∅→∅)
type Capability m ={ login :: String -> String -> m LoginResponse, checkLogin :: m LoginResponse, logout :: m Unit}type Capability m= { login :: String -> String -> m LoginResponse, checkLogin :: m LoginResponse, logout :: m Unit} - replacement in client/src/Aftok/Login.purs at line 46[3.488]→[3.296085:296122](∅→∅),[3.296122]→[3.86:132](∅→∅),[3.132]→[3.295:346](∅→∅),[3.346]→[3.133:171](∅→∅),[3.296208]→[3.133:171](∅→∅),[3.171]→[3.296239:296326](∅→∅),[3.296239]→[3.296239:296326](∅→∅),[3.296326]→[3.1092:1102](∅→∅),[3.1092]→[3.1092:1102](∅→∅),[3.1102]→[3.296327:296368](∅→∅),[3.296368]→[3.4005:4078](∅→∅)
component:: forall query input m. Monad m=> System m-> Capability m-> H.Component HH.HTML query input LoginResult mcomponent system caps = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval { handleAction = eval }} whereinitialState :: input -> LoginStateinitialState _ = { username: "", password: "", loginError: Nothing }component ::forall query input m.Monad m =>System m ->Capability m ->H.Component HH.HTML query input LoginResult mcomponent system caps =H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval { handleAction = eval }}whereinitialState :: input -> LoginStateinitialState _ = { username: "", password: "", loginError: Nothing } - replacement in client/src/Aftok/Login.purs at line 62[3.296446]→[3.193:271](∅→∅),[3.271]→[3.296526:296580](∅→∅),[3.296526]→[3.296526:296580](∅→∅),[3.296580]→[3.4:79](∅→∅)
render :: forall slots. LoginState -> H.ComponentHTML LoginAction slots mrender st =Card.component $HH.div[ P.classes (ClassName <$> ["row", "no-gutters", "container"]) ]render :: forall slots. LoginState -> H.ComponentHTML LoginAction slots mrender st =Card.component$ HH.div[ P.classes (ClassName <$> [ "row", "no-gutters", "container" ]) ] - replacement in client/src/Aftok/Login.purs at line 68
[ P.classes (ClassName <$> ["col-12", "col-md-6", "bg-cover", "card-img-left"]), CSS.style $ backgroundImage (url "/assets/img/photos/latch.jpg")][HH.div[ P.classes (ClassName <$> ["shape", "shape-right", "shape-fluid-y", "svg-shim", "text-white", "d-none", "d-md-block"])][ HH.img [ P.src "/assets/img/shapes/curves/curve-4.svg" ]]][ P.classes (ClassName <$> [ "col-12", "col-md-6", "bg-cover", "card-img-left" ]), CSS.style $ backgroundImage (url "/assets/img/photos/latch.jpg")][ HH.div[ P.classes (ClassName <$> [ "shape", "shape-right", "shape-fluid-y", "svg-shim", "text-white", "d-none", "d-md-block" ]) ][ HH.img [ P.src "/assets/img/shapes/curves/curve-4.svg" ] ]] - replacement in client/src/Aftok/Login.purs at line 76[3.297127]→[3.297127:297419](∅→∅),[3.1102]→[3.997:998](∅→∅),[3.297419]→[3.997:998](∅→∅),[3.997]→[3.997:998](∅→∅),[3.998]→[3.297420:297497](∅→∅),[3.297497]→[3.105:151](∅→∅),[3.151]→[3.297545:298308](∅→∅),[3.297545]→[3.297545:298308](∅→∅)
[ P.classes (ClassName <$> ["col-12", "col-md-6"]) ][ HH.div[ P.classes (ClassName <$> ["card-body"]) ][ HH.h2[ P.classes (ClassName <$> ["mb-0", "font-weight-bold", "text-center"])][ HH.text "Sign In"], HH.form[ P.classes (ClassName <$> ["mb-6"]), E.onSubmit (Just <<< Login)][ HH.div[ P.classes (ClassName <$> ["form-group"])][ HH.label[ P.classes (ClassName <$> ["sr-only"]), P.for "modalSigninHorizontalUsername"][ HH.text "Username" ], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> ["form-control"]), P.id_ "modalSigninHorizontalUsername", P.placeholder "Username", P.required true, P.autofocus true, P.value st.username, E.onValueInput (Just <<< SetUsername)][ P.classes (ClassName <$> [ "col-12", "col-md-6" ]) ][ HH.div[ P.classes (ClassName <$> [ "card-body" ]) ][ HH.h2[ P.classes (ClassName <$> [ "mb-0", "font-weight-bold", "text-center" ]) ][ HH.text "Sign In" ], HH.form[ P.classes (ClassName <$> [ "mb-6" ]), E.onSubmit (Just <<< Login)][ HH.div[ P.classes (ClassName <$> [ "form-group" ]) ][ HH.label[ P.classes (ClassName <$> [ "sr-only" ]), P.for "modalSigninHorizontalUsername"][ HH.text "Username" ], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> [ "form-control" ]), P.id_ "modalSigninHorizontalUsername", P.placeholder "Username", P.required true, P.autofocus true, P.value st.username, E.onValueInput (Just <<< SetUsername)]], HH.div[ P.classes (ClassName <$> [ "form-group" ]) ][ HH.label[ P.classes (ClassName <$> [ "sr-only" ]), P.for "modalSigninHorizontalPassword"][ HH.text "Password" ], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> [ "form-control" ]), P.id_ "modalSigninHorizontalPassword", P.placeholder "Password", P.required true, P.value st.password, E.onValueInput (Just <<< SetPassword)]], case st.loginError ofNothing -> HH.div_ []Just err ->letmessage = case err ofForbidden -> "Login failed. Check your username and password."ServerError -> "Login failed due to an internal error. Please contact support."inHH.div[ P.classes (ClassName <$> [ "alert alert-danger" ]) ][ HH.text message ], HH.button[ P.classes (ClassName <$> [ "btn", "btn-block", "btn-primary" ]) ][ HH.text "Sign in" ]] - replacement in client/src/Aftok/Login.purs at line 137
, HH.div[ P.classes (ClassName <$> ["form-group"])][ HH.label[ P.classes (ClassName <$> ["sr-only"]), P.for "modalSigninHorizontalPassword"][ HH.text "Password" ], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> ["form-control"]), P.id_ "modalSigninHorizontalPassword", P.placeholder "Password", P.required true, P.value st.password, E.onValueInput (Just <<< SetPassword)], HH.p[ P.classes (ClassName <$> [ "mb-0", "font-size-sm", "text-center", "text-muted" ]) ][ HH.text "Need an account? ", HH.a[ P.href "#signup" ][ HH.text "Sign up" ] - edit in client/src/Aftok/Login.purs at line 144[3.299058]→[3.4079:4119](∅→∅),[3.4119]→[3.299101:299165](∅→∅),[3.299101]→[3.299101:299165](∅→∅),[3.299165]→[3.4120:4562](∅→∅),[3.4562]→[3.299842:299871](∅→∅),[3.299842]→[3.299842:299871](∅→∅),[3.299871]→[3.4563:4647](∅→∅),[3.4647]→[3.299973:300031](∅→∅),[3.299973]→[3.299973:300031](∅→∅)
, case st.loginError ofNothing ->HH.div_ []Just err ->let message = case err ofForbidden -> "Login failed. Check your username and password."ServerError -> "Login failed due to an internal error. Please contact support."in HH.div[ P.classes (ClassName <$> ["alert alert-danger"]) ][ HH.text message ], HH.button[ P.classes (ClassName <$> ["btn", "btn-block", "btn-primary"]) ][ HH.text "Sign in" ]] - edit in client/src/Aftok/Login.purs at line 145[3.300047]→[3.347:541](∅→∅),[3.541]→[3.4:43](∅→∅),[3.43]→[3.582:640](∅→∅),[3.582]→[3.582:640](∅→∅),[3.640]→[3.300047:300061](∅→∅),[3.300047]→[3.300047:300061](∅→∅)
, HH.p[ P.classes (ClassName <$> ["mb-0", "font-size-sm", "text-center", "text-muted"]) ][ HH.text "Need an account? ", HH.a[ P.href "#signup" ][ HH.text "Sign up" ]]] - replacement in client/src/Aftok/Login.purs at line 147[3.2139]→[3.641:724](∅→∅),[3.724]→[3.300147:300288](∅→∅),[3.300147]→[3.300147:300288](∅→∅),[3.300288]→[3.152:173](∅→∅),[3.173]→[3.172:212](∅→∅),[3.212]→[3.300306:300426](∅→∅),[3.218]→[3.300306:300426](∅→∅),[3.300306]→[3.300306:300426](∅→∅),[3.300482]→[3.300482:300507](∅→∅),[3.300507]→[3.4648:4869](∅→∅)
eval :: LoginAction -> H.HalogenM LoginState LoginAction () LoginResult m Uniteval = case _ ofSetUsername user -> H.modify_ (_ { username = user })SetPassword pass -> H.modify_ (_ { password = pass })Login ev -> dolift $ system.preventDefault evuser <- H.gets (_.username)pass <- H.gets (_.password)response <- lift (caps.login user pass)case response ofLoginOK -> H.raise (LoginComplete { username: user })LoginForbidden -> H.modify_ (_ { loginError = Just Forbidden })LoginError _ -> H.modify_ (_ { loginError = Just ServerError })eval :: LoginAction -> H.HalogenM LoginState LoginAction () LoginResult m Uniteval = case _ ofSetUsername user -> H.modify_ (_ { username = user })SetPassword pass -> H.modify_ (_ { password = pass })Login ev -> dolift $ system.preventDefault evuser <- H.gets (_.username)pass <- H.gets (_.password)response <- lift (caps.login user pass)case response ofLoginOK -> H.raise (LoginComplete { username: user })LoginForbidden -> H.modify_ (_ { loginError = Just Forbidden })LoginError _ -> H.modify_ (_ { loginError = Just ServerError }) - replacement in client/src/Aftok/Login.purs at line 165
mockCapability ={ login: \_ _ -> pure LoginOKmockCapability ={ login: \_ _ -> pure LoginOK - edit in client/src/Aftok/Overview.purs at line 4
- edit in client/src/Aftok/Overview.purs at line 27
- edit in client/src/Aftok/Overview.purs at line 32
- edit in client/src/Aftok/Overview.purs at line 35
- edit in client/src/Aftok/Overview.purs at line 40
- edit in client/src/Aftok/Overview.purs at line 44
- edit in client/src/Aftok/Overview.purs at line 58
- replacement in client/src/Aftok/Overview.purs at line 59
type OverviewInput = Maybe Projecttype OverviewInput= Maybe Project - replacement in client/src/Aftok/Overview.purs at line 62
type OverviewState ={ selectedProject :: Maybe Project}type OverviewState= { selectedProject :: Maybe Project} - replacement in client/src/Aftok/Overview.purs at line 75
type Slot id = forall query. H.Slot query ProjectEvent idtype Slot id= forall query. H.Slot query ProjectEvent id - replacement in client/src/Aftok/Overview.purs at line 78
type Slots =( projectList :: Project.ProjectListSlot Unit)type Slots= ( projectList :: Project.ProjectListSlot Unit) - replacement in client/src/Aftok/Overview.purs at line 84
type Capability (m :: Type -> Type) ={}type Capability (m :: Type -> Type)= {} - replacement in client/src/Aftok/Overview.purs at line 88
component:: forall query m. Monad m=> System m-> Capability m-> Project.Capability m-> H.Component HH.HTML query OverviewInput ProjectEvent mcomponent system caps pcaps = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval{ handleAction = eval, initialize = Just Initialize}} whereinitialState :: OverviewInput -> OverviewStateinitialState input ={ selectedProject: input}component ::forall query m.Monad m =>System m ->Capability m ->Project.Capability m ->H.Component HH.HTML query OverviewInput ProjectEvent mcomponent system caps pcaps =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = eval, initialize = Just Initialize}}whereinitialState :: OverviewInput -> OverviewStateinitialState input ={ selectedProject: input} - replacement in client/src/Aftok/Overview.purs at line 112[3.3083]→[3.3083:3651](∅→∅),[3.3651]→[2.32:162](∅→∅),[2.162]→[3.3767:3898](∅→∅),[3.3767]→[3.3767:3898](∅→∅)
render :: OverviewState -> H.ComponentHTML OverviewAction Slots mrender st =HH.section[P.classes (ClassName <$> ["section-border", "border-primary"])][HH.div[P.classes (ClassName <$> ["container", "pt-6"])][HH.h1[P.classes (ClassName <$> ["mb-0", "font-weight-bold", "text-center"])][HH.text "Project Overview"],HH.p[P.classes (ClassName <$> ["col-md-5", "text-muted", "text-center", "mx-auto"])][HH.text "Your project timeline"],HH.div_[HH.slot _projectList unit (Project.projectListComponent system pcaps) st.selectedProject (Just <<< ProjectSelected)],HH.div[P.classes (ClassName <$> if isNothing st.selectedProject then ["collapse"] else [])][]render :: OverviewState -> H.ComponentHTML OverviewAction Slots mrender st =HH.section[ P.classes (ClassName <$> [ "section-border", "border-primary" ]) ][ HH.div[ P.classes (ClassName <$> [ "container", "pt-6" ]) ][ HH.h1[ P.classes (ClassName <$> [ "mb-0", "font-weight-bold", "text-center" ]) ][ HH.text "Project Overview" ], HH.p[ P.classes (ClassName <$> [ "col-md-5", "text-muted", "text-center", "mx-auto" ]) ][ HH.text "Your project timeline" ], HH.div_[ HH.slot _projectList unit (Project.projectListComponent system pcaps) st.selectedProject (Just <<< ProjectSelected) ], HH.div[ P.classes (ClassName <$> if isNothing st.selectedProject then [ "collapse" ] else []) ][] - replacement in client/src/Aftok/Overview.purs at line 130
]] - replacement in client/src/Aftok/Overview.purs at line 132
eval :: OverviewAction -> H.HalogenM OverviewState OverviewAction Slots ProjectEvent m Uniteval action = docase action ofInitialize -> dopure uniteval :: OverviewAction -> H.HalogenM OverviewState OverviewAction Slots ProjectEvent m Uniteval action = docase action ofInitialize -> dopure unitInvite _ -> dopure unitProjectSelected p -> docurrentProject <- H.gets (_.selectedProject)when (all (\p' -> (unwrap p').projectId /= (unwrap p).projectId) currentProject)$ doH.raise (ProjectChange p)H.modify_ (_ { selectedProject = Just p }) - edit in client/src/Aftok/Overview.purs at line 146[3.4105]→[3.4105:4247](∅→∅),[3.4247]→[2.163:259](∅→∅),[2.259]→[3.4343:4438](∅→∅),[3.4343]→[3.4343:4438](∅→∅)
Invite _ -> dopure unitProjectSelected p -> docurrentProject <- H.gets (_.selectedProject)when (all (\p' -> (unwrap p').projectId /= (unwrap p).projectId) currentProject) $ doH.raise (ProjectChange p)H.modify_ (_ { selectedProject = Just p }) - replacement in client/src/Aftok/Overview.purs at line 147
apiCapability = { }apiCapability = {} - replacement in client/src/Aftok/Overview.purs at line 150
mockCapability = { }[3.4524]mockCapability = {} - edit in client/src/Aftok/Project.purs at line 4
- edit in client/src/Aftok/Project.purs at line 7
- edit in client/src/Aftok/Project.purs at line 15
- replacement in client/src/Aftok/Project.purs at line 21
import Aftok.Typesimport Aftok.Types - edit in client/src/Aftok/Project.purs at line 29[3.127]→[3.216:217](∅→∅),[3.313]→[3.216:217](∅→∅),[3.4766]→[3.216:217](∅→∅),[3.216]→[3.216:217](∅→∅)
- replacement in client/src/Aftok/Project.purs at line 35
type ProjectInput = Maybe Projecttype ProjectInput= Maybe Project - replacement in client/src/Aftok/Project.purs at line 38[2.365]→[3.527:548](∅→∅),[3.527]→[3.527:548](∅→∅),[3.548]→[2.366:433](∅→∅),[2.433]→[3.578:582](∅→∅),[3.578]→[3.578:582](∅→∅)
type ProjectCState ={ selectedProject :: Maybe Project, projects :: Array Project}type ProjectCState= { selectedProject :: Maybe Project, projects :: Array Project} - replacement in client/src/Aftok/Project.purs at line 43
data ProjectActiondata ProjectAction - replacement in client/src/Aftok/Project.purs at line 47
type ProjectListSlot id = forall query. H.Slot query Project idtype ProjectListSlot id= forall query. H.Slot query Project id - replacement in client/src/Aftok/Project.purs at line 50
type Capability m ={ listProjects :: m (Either APIError (Array Project))}type Capability m= { listProjects :: m (Either APIError (Array Project))} - replacement in client/src/Aftok/Project.purs at line 54[3.1751]→[3.699:746](∅→∅),[3.746]→[3.412:458](∅→∅),[3.458]→[2.434:488](∅→∅),[2.488]→[3.459:509](∅→∅),[3.834]→[3.459:509](∅→∅),[3.509]→[3.876:1025](∅→∅),[3.876]→[3.876:1025](∅→∅),[3.1025]→[2.489:605](∅→∅)
projectListComponent:: forall query input m. Monad m=> System m-> Capability m-> H.Component HH.HTML query ProjectInput Project mprojectListComponent console caps = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval{ handleAction = eval, initialize = Just Initialize}} whereinitialState :: ProjectInput -> ProjectCStateinitialState input = { selectedProject: input, projects: [] }projectListComponent ::forall query input m.Monad m =>System m ->Capability m ->H.Component HH.HTML query ProjectInput Project mprojectListComponent console caps =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = eval, initialize = Just Initialize}}whereinitialState :: ProjectInput -> ProjectCStateinitialState input = { selectedProject: input, projects: [] } - replacement in client/src/Aftok/Project.purs at line 75
render :: forall slots. ProjectCState -> H.ComponentHTML ProjectAction slots mrender st =HH.div[P.classes (ClassName <$> ["form-group"])][ HH.label[ P.classes (ClassName <$> ["sr-only"])render :: forall slots. ProjectCState -> H.ComponentHTML ProjectAction slots mrender st =HH.div[ P.classes (ClassName <$> [ "form-group" ]) ][ HH.label[ P.classes (ClassName <$> [ "sr-only" ]) - replacement in client/src/Aftok/Project.purs at line 84
, HH.select[P.classes (ClassName <$> ["form-control"]),P.id_ "projectSelect",E.onSelectedIndexChange (Just <<< Select), HH.select[ P.classes (ClassName <$> [ "form-control" ]), P.id_ "projectSelect", E.onSelectedIndexChange (Just <<< Select) - replacement in client/src/Aftok/Project.purs at line 89
( [HH.option [P.selected (isNothing st.selectedProject), P.disabled true] [HH.text "Select a project"]]<> map renderOption st.projects( [ HH.option [ P.selected (isNothing st.selectedProject), P.disabled true ] [ HH.text "Select a project" ] ]<> map renderOption st.projects - edit in client/src/Aftok/Project.purs at line 92
]whererenderOption (Project' p) =HH.option[ P.selected (any (\(Project' p') -> p'.projectId == p.projectId) st.selectedProject), P.value $ pidStr p.projectId - replacement in client/src/Aftok/Project.purs at line 99
whererenderOption (Project' p) =HH.option[ P.selected (any (\(Project' p') -> p'.projectId == p.projectId) st.selectedProject), P.value $ pidStr p.projectId][HH.text p.projectName][ HH.text p.projectName ] - replacement in client/src/Aftok/Project.purs at line 101[3.1519]→[3.1519:1709](∅→∅),[3.1709]→[3.510:592](∅→∅),[3.592]→[3.1772:1840](∅→∅),[3.1772]→[3.1772:1840](∅→∅)
eval :: ProjectAction -> H.HalogenM ProjectCState ProjectAction () Project m Uniteval = case _ ofInitialize -> dores <- lift caps.listProjectscase res ofLeft _ -> lift <<< console.error $ "Could not retrieve project list."Right projects -> H.modify_ (_ { projects = projects })eval :: ProjectAction -> H.HalogenM ProjectCState ProjectAction () Project m Uniteval = case _ ofInitialize -> dores <- lift caps.listProjectscase res ofLeft _ -> lift <<< console.error $ "Could not retrieve project list."Right projects -> H.modify_ (_ { projects = projects })Select i -> doprojects <- H.gets (_.projects)lift <<< console.log $ "Selected project index " <> show itraverse_ H.raise (index projects (i - 1)) - edit in client/src/Aftok/Project.purs at line 113[3.1841]→[3.1841:1902](∅→∅),[3.1902]→[3.593:660](∅→∅),[3.660]→[3.918:969](∅→∅),[3.918]→[3.918:969](∅→∅),[3.969]→[3.1869:1870](∅→∅),[3.1947]→[3.1869:1870](∅→∅),[3.1869]→[3.1869:1870](∅→∅)
Select i -> doprojects <- H.gets (_.projects)lift <<< console.log $ "Selected project index " <> show itraverse_ H.raise (index projects (i - 1)) - replacement in client/src/Aftok/Project.purs at line 115[3.2320]→[3.2320:2361](∅→∅),[3.2361]→[3.2412:2460](∅→∅),[3.2460]→[3.2406:2801](∅→∅),[3.2406]→[3.2406:2801](∅→∅)
result <- get RF.json "/api/projects"EC.liftEffect <<< runExceptT $ case result ofLeft err -> throwError $ Error { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 ->throwError ForbiddenStatusCode 200 -> dorecords <- except $ lmap (ParseFailure r.body) (decodeJson r.body)traverse parseProject recordsother ->throwError $ Error { status: Just other, message: r.statusText }result <- get RF.json "/api/projects"EC.liftEffect <<< runExceptT$ case result ofLeft err -> throwError $ Error { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 -> throwError ForbiddenStatusCode 200 -> dorecords <- except $ lmap (ParseFailure r.body) (decodeJson r.body)traverse parseProject recordsother -> throwError $ Error { status: Just other, message: r.statusText } - edit in client/src/Aftok/Project.purs at line 137
- edit in client/src/Aftok/Signup.purs at line 4
- edit in client/src/Aftok/Signup.purs at line 5
- edit in client/src/Aftok/Signup.purs at line 9
- edit in client/src/Aftok/Signup.purs at line 15
- edit in client/src/Aftok/Signup.purs at line 23
- edit in client/src/Aftok/Signup.purs at line 26
- replacement in client/src/Aftok/Signup.purs at line 49[3.814]→[3.814:1028](∅→∅),[3.1028]→[3.5576:5614](∅→∅),[3.5614]→[3.1070:1074](∅→∅),[3.1070]→[3.1070:1074](∅→∅)
type SignupState ={ username :: Maybe String, password :: Maybe String, passwordConfirm :: Maybe String, recoveryType :: RecoveryType, recoveryEmail :: Maybe String, recoveryZAddr :: Maybe String, signupErrors :: Array SignupError}type SignupState= { username :: Maybe String, password :: Maybe String, passwordConfirm :: Maybe String, recoveryType :: RecoveryType, recoveryEmail :: Maybe String, recoveryZAddr :: Maybe String, signupErrors :: Array SignupError} - replacement in client/src/Aftok/Signup.purs at line 69
data SignupResult= SignupComplete Stringdata SignupResult= SignupComplete String - replacement in client/src/Aftok/Signup.purs at line 73
type Slot id = forall query. H.Slot query SignupResult idtype Slot id= forall query. H.Slot query SignupResult id - replacement in client/src/Aftok/Signup.purs at line 76[3.1438]→[3.1438:1459](∅→∅),[3.1459]→[3.5657:5878](∅→∅),[3.5878]→[3.1510:1514](∅→∅),[3.1510]→[3.1510:1514](∅→∅)
type Capability m ={ checkUsername :: String -> m Acc.UsernameCheckResponse, checkZAddr :: String -> m Acc.ZAddrCheckResponse, signup :: SignupRequest -> m SignupResponse, getRecaptchaResponse :: Maybe String -> m (Maybe String)}type Capability m= { checkUsername :: String -> m Acc.UsernameCheckResponse, checkZAddr :: String -> m Acc.ZAddrCheckResponse, signup :: SignupRequest -> m SignupResponse, getRecaptchaResponse :: Maybe String -> m (Maybe String)} - replacement in client/src/Aftok/Signup.purs at line 83
type Config ={ recaptchaKey :: String}type Config= { recaptchaKey :: String} - replacement in client/src/Aftok/Signup.purs at line 87[3.1561]→[3.1561:2095](∅→∅),[3.2095]→[3.5879:5904](∅→∅),[3.5904]→[3.2126:2134](∅→∅),[3.2126]→[3.2126:2134](∅→∅)
component:: forall query input m. Monad m=> System m-> Capability m-> Config-> H.Component HH.HTML query input SignupResult mcomponent system caps conf = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval { handleAction = eval }} whereinitialState :: input -> SignupStateinitialState _ ={ username: Nothing, password: Nothing, passwordConfirm: Nothing, recoveryType: RecoveryEmail, recoveryEmail: Nothing, recoveryZAddr: Nothing, signupErrors: []}component ::forall query input m.Monad m =>System m ->Capability m ->Config ->H.Component HH.HTML query input SignupResult mcomponent system caps conf =H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval { handleAction = eval }}whereinitialState :: input -> SignupStateinitialState _ ={ username: Nothing, password: Nothing, passwordConfirm: Nothing, recoveryType: RecoveryEmail, recoveryEmail: Nothing, recoveryZAddr: Nothing, signupErrors: []} - replacement in client/src/Aftok/Signup.purs at line 112
render :: forall slots. SignupState -> H.ComponentHTML SignupAction slots mrender st =HH.section[ P.classes (ClassName <$> ["section-border", "border-primary"]) ][ HH.div[ P.classes (ClassName <$> ["container", "d-flex", "flex-column"]) ]render :: forall slots. SignupState -> H.ComponentHTML SignupAction slots mrender st =HH.section[ P.classes (ClassName <$> [ "section-border", "border-primary" ]) ][ HH.div[ P.classes (ClassName <$> [ "container", "d-flex", "flex-column" ]) ] - replacement in client/src/Aftok/Signup.purs at line 119
[ P.classes (ClassName <$> ["align-items-center", "pt-6"]) ][ HH.h1[ P.classes (ClassName <$> ["mb-0", "font-weight-bold", "text-center"]) ][ HH.text "Sign up" ], HH.p[ P.classes (ClassName <$> ["text-center", "text-muted", "col-md-5", "mx-auto"]) ][ HH.text "You can use either an email address or zcash payment address for account recovery." ]][ P.classes (ClassName <$> [ "align-items-center", "pt-6" ]) ][ HH.h1[ P.classes (ClassName <$> [ "mb-0", "font-weight-bold", "text-center" ]) ][ HH.text "Sign up" ], HH.p[ P.classes (ClassName <$> [ "text-center", "text-muted", "col-md-5", "mx-auto" ]) ][ HH.text "You can use either an email address or zcash payment address for account recovery." ]] - replacement in client/src/Aftok/Signup.purs at line 128[3.2920]→[3.837:949](∅→∅),[3.949]→[3.3025:3157](∅→∅),[3.3025]→[3.3025:3157](∅→∅),[3.3157]→[3.5905:6024](∅→∅),[3.6024]→[3.3212:4571](∅→∅),[3.3212]→[3.3212:4571](∅→∅),[3.4571]→[3.6025:6071](∅→∅),[3.6071]→[3.4610:5087](∅→∅),[3.4610]→[3.4610:5087](∅→∅),[3.5087]→[3.6072:6148](∅→∅),[3.6148]→[3.5159:5257](∅→∅),[3.5159]→[3.5159:5257](∅→∅)
[ P.classes (ClassName <$> ["row", "align-items-center", "justify-content-center", "no-gutters"]) ][ HH.div[ P.classes (ClassName <$> ["col-12", "col-lg-4", "py-8", "py-md-0"]) ][ HH.form[ P.classes (ClassName <$> ["mb-6"]), E.onSubmit (Just <<< Signup)][ HH.div[ P.classes (ClassName <$> ["form-group"]) ][ HH.label [ P.for "username" ] [ HH.text "Username" ], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> ["form-control"]), P.id_ "username", P.placeholder "Choose a handle (username)", P.required true, P.autofocus true, P.value (fromMaybe "" st.username), E.onValueInput (Just <<< SetUsername)]], HH.div[ P.classes (ClassName <$> ["form-group"]) ][ HH.label [ P.for "password" ] [ HH.text "Password" ], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> ["form-control"]), P.id_ "password", P.placeholder "Enter a unique password", P.required true, P.value (fromMaybe "" st.password), E.onValueInput (Just <<< SetPassword)], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> ["form-control"]), P.id_ "passwordConfirm", P.placeholder "Enter a unique password", P.required true, P.value (fromMaybe "" st.passwordConfirm), E.onValueInput (Just <<< ConfirmPassword)]], recoverySwitch st.recoveryType, recoveryField st, HH.div[ P.classes (ClassName <$> ["form-group", "mb-3"]) ][ HH.div[ P.classes (ClassName <$> ["g-recaptcha", "mx-auto"]), P.attr (AttrName "data-sitekey") conf.recaptchaKey] [][ P.classes (ClassName <$> [ "row", "align-items-center", "justify-content-center", "no-gutters" ]) ][ HH.div[ P.classes (ClassName <$> [ "col-12", "col-lg-4", "py-8", "py-md-0" ]) ][ HH.form[ P.classes (ClassName <$> [ "mb-6" ]), E.onSubmit (Just <<< Signup)][ HH.div[ P.classes (ClassName <$> [ "form-group" ]) ][ HH.label [ P.for "username" ] [ HH.text "Username" ], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> [ "form-control" ]), P.id_ "username", P.placeholder "Choose a handle (username)", P.required true, P.autofocus true, P.value (fromMaybe "" st.username), E.onValueInput (Just <<< SetUsername)]], HH.div[ P.classes (ClassName <$> [ "form-group" ]) ][ HH.label [ P.for "password" ] [ HH.text "Password" ], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> [ "form-control" ]), P.id_ "password", P.placeholder "Enter a unique password", P.required true, P.value (fromMaybe "" st.password), E.onValueInput (Just <<< SetPassword)], HH.input[ P.type_ P.InputPassword, P.classes (ClassName <$> [ "form-control" ]), P.id_ "passwordConfirm", P.placeholder "Enter a unique password", P.required true, P.value (fromMaybe "" st.passwordConfirm), E.onValueInput (Just <<< ConfirmPassword)]], recoverySwitch st.recoveryType, recoveryField st, HH.div[ P.classes (ClassName <$> [ "form-group", "mb-3" ]) ][ HH.div[ P.classes (ClassName <$> [ "g-recaptcha", "mx-auto" ]), P.attr (AttrName "data-sitekey") conf.recaptchaKey][]], HH.button[ P.classes (ClassName <$> [ "btn", "btn-block", "btn-primary" ]) ][ HH.text "Sign up" ]], HH.p[ P.classes (ClassName <$> [ "mb-0", "font-size-sm", "text-center", "text-muted" ]) ][ HH.text "Already have an account? ", HH.a[ P.href "#login" ][ HH.text "Sign in" ]] - edit in client/src/Aftok/Signup.purs at line 193[3.5277]→[3.5277:5570](∅→∅),[3.5570]→[3.45:100](∅→∅),[3.100]→[3.5624:5648](∅→∅),[3.5624]→[3.5624:5648](∅→∅),[3.5648]→[3.101:139](∅→∅),[3.139]→[3.5710:5768](∅→∅),[3.5710]→[3.5710:5768](∅→∅)
, HH.button[ P.classes (ClassName <$> ["btn", "btn-block", "btn-primary"]) ][ HH.text "Sign up" ]], HH.p[ P.classes (ClassName <$> ["mb-0", "font-size-sm", "text-center", "text-muted"]) ][ HH.text "Already have an account? ", HH.a[ P.href "#login" ][ HH.text "Sign in" ]] - edit in client/src/Aftok/Signup.purs at line 194
] - replacement in client/src/Aftok/Signup.purs at line 195
]] - replacement in client/src/Aftok/Signup.purs at line 197[3.5821]→[3.5821:5929](∅→∅),[3.5929]→[3.6149:6885](∅→∅),[3.6885]→[3.950:1012](∅→∅),[3.6059]→[3.950:1012](∅→∅),[3.1012]→[3.6886:6997](∅→∅),[3.6997]→[3.1928:1979](∅→∅),[3.1979]→[3.6997:7114](∅→∅),[3.6997]→[3.6997:7114](∅→∅),[3.7114]→[3.1980:2023](∅→∅),[3.2023]→[3.7154:7237](∅→∅),[3.7154]→[3.7154:7237](∅→∅),[3.7237]→[3.6156:6157](∅→∅),[3.6156]→[3.6156:6157](∅→∅),[3.6157]→[3.7238:7261](∅→∅),[3.7261]→[3.2024:2075](∅→∅),[3.2075]→[3.7261:7340](∅→∅),[3.7261]→[3.7261:7340](∅→∅)
eval :: SignupAction -> H.HalogenM SignupState SignupAction () SignupResult m Uniteval = case _ ofSetUsername user -> doures <- lift $ caps.checkUsername userH.modify_ (_ { username = Just user })case ures ofAcc.UsernameCheckOK -> pure unitAcc.UsernameCheckTaken -> H.modify_ (_ { signupErrors = [UsernameTaken] })SetPassword pass -> doH.modify_ (_ { password = Just pass })confirm <- H.gets (_.passwordConfirm)when (any (notEq pass) confirm) (H.modify_ (_ { signupErrors = [PasswordMismatch] }))ConfirmPassword confirm -> doH.modify_ (_ { passwordConfirm = Just confirm })password <- H.gets (_.password)when (any (notEq confirm) password) (H.modify_ (_ { signupErrors = [PasswordMismatch] }))SetRecoveryType t -> H.modify_ (_ { recoveryType = t })SetRecoveryEmail email -> H.modify_ (_ { recoveryEmail = Just email })SetRecoveryZAddr addr -> dolift $ system.log "Switching to signin..."zres <- lift $ caps.checkZAddr addrH.modify_ (_ { recoveryZAddr = Just addr })case zres ofAcc.ZAddrCheckValid -> pure unitAcc.ZAddrCheckInvalid -> H.modify_ (_ { signupErrors = [ZAddrInvalid] })Signin ev -> dolift $ system.log "Switching to signin..."lift $ system.preventDefault (ME.toEvent ev)H.raise SigninNaveval :: SignupAction -> H.HalogenM SignupState SignupAction () SignupResult m Uniteval = case _ ofSetUsername user -> doures <- lift $ caps.checkUsername userH.modify_ (_ { username = Just user })case ures ofAcc.UsernameCheckOK -> pure unitAcc.UsernameCheckTaken -> H.modify_ (_ { signupErrors = [ UsernameTaken ] })SetPassword pass -> doH.modify_ (_ { password = Just pass })confirm <- H.gets (_.passwordConfirm)when (any (notEq pass) confirm) (H.modify_ (_ { signupErrors = [ PasswordMismatch ] }))ConfirmPassword confirm -> doH.modify_ (_ { passwordConfirm = Just confirm })password <- H.gets (_.password)when (any (notEq confirm) password) (H.modify_ (_ { signupErrors = [ PasswordMismatch ] }))SetRecoveryType t -> H.modify_ (_ { recoveryType = t })SetRecoveryEmail email -> H.modify_ (_ { recoveryEmail = Just email })SetRecoveryZAddr addr -> dolift $ system.log "Switching to signin..."zres <- lift $ caps.checkZAddr addrH.modify_ (_ { recoveryZAddr = Just addr })case zres ofAcc.ZAddrCheckValid -> pure unitAcc.ZAddrCheckInvalid -> H.modify_ (_ { signupErrors = [ ZAddrInvalid ] })Signin ev -> dolift $ system.log "Switching to signin..."lift $ system.preventDefault (ME.toEvent ev)H.raise SigninNavSignup ev -> dolift $ system.preventDefault evrecType <- H.gets (_.recoveryType)usernameV <- V <<< note [ UsernameRequired ] <$> H.gets (_.username)pwdFormV <- V <<< note [ PasswordRequired ] <$> H.gets (_.password)pwdConfV <- V <<< note [ ConfirmRequired ] <$> H.gets (_.passwordConfirm)recoveryType <- H.gets (_.recoveryType)recoveryV <- case recoveryType ofRecoveryEmail -> V <<< note [ EmailRequired ] <<< map Acc.RecoverByEmail <$> H.gets (_.recoveryEmail)RecoveryZAddr -> V <<< note [ ZAddrRequired ] <<< map Acc.RecoverByZAddr <$> H.gets (_.recoveryZAddr)recapV <- lift $ V <<< note [ CaptchaError ] <$> caps.getRecaptchaResponse Nothinglift $ system.log "Sending signup request..."letreqV :: V (Array SignupError) Acc.SignupRequestreqV =signupRequest <$> usernameV<*> ( (eq <$> pwdFormV <*> pwdConfV)`andThen`(if _ then pwdFormV else invalid [ PasswordMismatch ]))<*> recoveryV<*> recapVcase toEither reqV ofLeft errors -> dolift $ system.log "Got signup HTTP error."H.modify_ (_ { signupErrors = errors })Right req -> doresponse <- lift (caps.signup req)lift <<< system.log $ "Got signup response " <> show responsecase response ofAcc.SignupOK -> H.raise (SignupComplete $ req.username)Acc.CaptchaInvalid -> H.modify_ (_ { signupErrors = [ CaptchaError ] })Acc.ZAddrInvalid -> H.modify_ (_ { signupErrors = [ ZAddrInvalid ] })Acc.UsernameTaken -> H.modify_ (_ { signupErrors = [ UsernameTaken ] })Acc.ServiceError c m -> H.modify_ (_ { signupErrors = [ APIError { status: c, message: m } ] }) - edit in client/src/Aftok/Signup.purs at line 262[3.7341]→[3.7341:8103](∅→∅),[3.8103]→[3.2076:2130](∅→∅),[3.2130]→[3.8103:8503](∅→∅),[3.8103]→[3.8103:8503](∅→∅),[3.8503]→[3.2131:2214](∅→∅),[3.2214]→[3.8529:8654](∅→∅),[3.8529]→[3.8529:8654](∅→∅),[3.8654]→[3.2215:2289](∅→∅),[3.2289]→[3.8654:8683](∅→∅),[3.8654]→[3.8654:8683](∅→∅),[3.8683]→[3.2290:2734](∅→∅),[3.2734]→[3.6157:6158](∅→∅),[3.9003]→[3.6157:6158](∅→∅),[3.6157]→[3.6157:6158](∅→∅)
Signup ev -> dolift $ system.preventDefault evrecType <- H.gets (_.recoveryType)usernameV <- V <<< note [UsernameRequired] <$> H.gets (_.username)pwdFormV <- V <<< note [PasswordRequired] <$> H.gets (_.password)pwdConfV <- V <<< note [ConfirmRequired ] <$> H.gets (_.passwordConfirm)recoveryType <- H.gets (_.recoveryType)recoveryV <- case recoveryType ofRecoveryEmail ->V <<< note [EmailRequired] <<< map Acc.RecoverByEmail <$> H.gets (_.recoveryEmail)RecoveryZAddr ->V <<< note [ZAddrRequired] <<< map Acc.RecoverByZAddr <$> H.gets (_.recoveryZAddr)recapV <- lift $ V <<< note [CaptchaError] <$> caps.getRecaptchaResponse Nothinglift $ system.log "Sending signup request..."let reqV :: V (Array SignupError) Acc.SignupRequestreqV = signupRequest <$> usernameV<*> ((eq <$> pwdFormV <*> pwdConfV) `andThen`(if _ then pwdFormV else invalid [PasswordMismatch]))<*> recoveryV<*> recapVcase toEither reqV ofLeft errors -> dolift $ system.log "Got signup HTTP error."H.modify_ (_ { signupErrors = errors })Right req -> doresponse <- lift (caps.signup req)lift <<< system.log $ "Got signup response " <> show responsecase response ofAcc.SignupOK -> H.raise (SignupComplete $ req.username)Acc.CaptchaInvalid -> H.modify_ (_ { signupErrors = [CaptchaError] })Acc.ZAddrInvalid -> H.modify_ (_ { signupErrors = [ZAddrInvalid] })Acc.UsernameTaken -> H.modify_ (_ { signupErrors = [UsernameTaken] })Acc.ServiceError c m -> H.modify_ (_ { signupErrors = [APIError { status: c, message: m }]}) - replacement in client/src/Aftok/Signup.purs at line 263
recoverySwitch rt =recoverySwitch rt = - replacement in client/src/Aftok/Signup.purs at line 265
[ P.classes (ClassName <$> ["form-group", "mb-3"]) ][ HH.label[ P.for "recoverySwitch" ][ HH.text "Choose a recovery method" ][ P.classes (ClassName <$> [ "form-group", "mb-3" ]) ][ HH.label[ P.for "recoverySwitch" ][ HH.text "Choose a recovery method" ] - replacement in client/src/Aftok/Signup.purs at line 270[3.6420]→[3.1013:1153](∅→∅),[3.1153]→[3.6479:7015](∅→∅),[3.6479]→[3.6479:7015](∅→∅),[3.7015]→[3.1154:1257](∅→∅)
[ P.classes (ClassName <$> ["form-group", "mb-3"]), CSS.style dodisplay flexflexFlow row nowrap][ HH.span[ P.classes (ClassName <$> [ if rt == RecoveryEmail then "text-success" else "text-muted"]) ][ HH.text "Email" ], HH.div[ P.classes (ClassName <$> ["custom-control", "custom-switch", "custom-switch-light", "mx-3"]) ][ HH.input[ P.type_ P.InputCheckbox, P.classes (ClassName <$> ["custom-control-input"]), P.id_ "recoverySwitch", E.onChecked (\b -> Just <<< SetRecoveryType $ if b then RecoveryZAddr else RecoveryEmail)], HH.label [ P.classes (ClassName <$> [ "custom-control-label" ]), P.for "recoverySwitch" ] [][ P.classes (ClassName <$> [ "form-group", "mb-3" ]), CSS.style dodisplay flexflexFlow row nowrap][ HH.span[ P.classes (ClassName <$> [ if rt == RecoveryEmail then "text-success" else "text-muted" ]) ][ HH.text "Email" ], HH.div[ P.classes (ClassName <$> [ "custom-control", "custom-switch", "custom-switch-light", "mx-3" ]) ][ HH.input[ P.type_ P.InputCheckbox, P.classes (ClassName <$> [ "custom-control-input" ]), P.id_ "recoverySwitch", E.onChecked (\b -> Just <<< SetRecoveryType $ if b then RecoveryZAddr else RecoveryEmail)], HH.label [ P.classes (ClassName <$> [ "custom-control-label" ]), P.for "recoverySwitch" ] []], HH.span[ P.classes (ClassName <$> [ if rt == RecoveryZAddr then "text-success" else "text-muted" ]) ][ HH.text "Z-Address" ] - edit in client/src/Aftok/Signup.purs at line 292
, HH.span[ P.classes (ClassName <$> [if rt == RecoveryZAddr then "text-success" else "text-muted"]) ][ HH.text "Z-Address" ]] - replacement in client/src/Aftok/Signup.purs at line 296
RecoveryEmail ->HH.divRecoveryEmail ->HH.div - replacement in client/src/Aftok/Signup.purs at line 300
, HH.input[ P.type_ P.InputEmail, P.classes (ClassName <$> ["form-control"]), P.id_ "email", P.placeholder "name@address.com", P.value (fromMaybe "" st.recoveryEmail), E.onValueInput (Just <<< SetRecoveryEmail)], HH.input[ P.type_ P.InputEmail, P.classes (ClassName <$> [ "form-control" ]), P.id_ "email", P.placeholder "name@address.com", P.value (fromMaybe "" st.recoveryEmail), E.onValueInput (Just <<< SetRecoveryEmail)] - replacement in client/src/Aftok/Signup.purs at line 310
HH.divHH.div - replacement in client/src/Aftok/Signup.purs at line 312
[ HH.label[ P.for "zaddr" ][ HH.text "Zcash Shielded Address", HH.a[ P.attr (AttrName "data-toggle") "modal", P.href "#modalAboutZAddr"[ HH.label[ P.for "zaddr" ][ HH.text "Zcash Shielded Address", HH.a[ P.attr (AttrName "data-toggle") "modal", P.href "#modalAboutZAddr"][ HH.img [ P.src "/assets/img/icons/duotone-icons/Code/Info-circle.svg" ]] - replacement in client/src/Aftok/Signup.purs at line 322
[ HH.img [ P.src "/assets/img/icons/duotone-icons/Code/Info-circle.svg" ], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> [ "form-control" ]), P.id_ "email", P.placeholder "Enter a Zcash shielded address", P.value (fromMaybe "" st.recoveryZAddr), E.onValueInput (Just <<< SetRecoveryZAddr) - edit in client/src/Aftok/Signup.purs at line 330
], HH.input[ P.type_ P.InputText, P.classes (ClassName <$> ["form-control"]), P.id_ "email", P.placeholder "Enter a Zcash shielded address", P.value (fromMaybe "" st.recoveryZAddr), E.onValueInput (Just <<< SetRecoveryZAddr)] - replacement in client/src/Aftok/Signup.purs at line 333
apiCapability =apiCapability = - replacement in client/src/Aftok/Signup.purs at line 337
, getRecaptchaResponse: liftEffect <<< getRecaptchaResponse, getRecaptchaResponse: liftEffect <<< getRecaptchaResponse - replacement in client/src/Aftok/Signup.purs at line 341
mockCapability =mockCapability = - replacement in client/src/Aftok/Signup.purs at line 345
, getRecaptchaResponse: liftEffect <<< getRecaptchaResponse, getRecaptchaResponse: liftEffect <<< getRecaptchaResponse - edit in client/src/Aftok/Timeline.purs at line 4
- edit in client/src/Aftok/Timeline.purs at line 9[3.44]→[3.2520:2521](∅→∅),[3.401]→[3.2520:2521](∅→∅),[3.301277]→[3.2520:2521](∅→∅),[3.2520]→[3.2520:2521](∅→∅)
- edit in client/src/Aftok/Timeline.purs at line 26
- edit in client/src/Aftok/Timeline.purs at line 31
- edit in client/src/Aftok/Timeline.purs at line 34
- edit in client/src/Aftok/Timeline.purs at line 39
- edit in client/src/Aftok/Timeline.purs at line 43
- replacement in client/src/Aftok/Timeline.purs at line 44
import Aftok.Api.Timeline( TimelineError,Event(..),Interval(..),TimeInterval,KeyedEvent,TimeSpan,start, end, interval,event, eventTime, keyedEvent)import Aftok.Api.Timeline( TimelineError, Event(..), Interval(..), TimeInterval, KeyedEvent, TimeSpan, start, end, interval, event, eventTime, keyedEvent) - replacement in client/src/Aftok/Timeline.purs at line 59
import Aftok.Types( System,ProjectEvent(..),Project,Project'(..),ProjectId)import Aftok.Types( System, ProjectEvent(..), Project, Project'(..), ProjectId) - replacement in client/src/Aftok/Timeline.purs at line 67[3.3283]→[3.1101:1123](∅→∅),[3.1123]→[3.5961:5989](∅→∅),[3.4012]→[3.3327:3350](∅→∅),[3.5989]→[3.3327:3350](∅→∅),[3.301951]→[3.3327:3350](∅→∅),[3.3327]→[3.3327:3350](∅→∅),[3.301975]→[3.3417:3421](∅→∅),[3.3417]→[3.3417:3421](∅→∅)
type TimelineLimits ={ bounds :: TimeInterval, current :: Instant}type TimelineLimits= { bounds :: TimeInterval, current :: Instant} - replacement in client/src/Aftok/Timeline.purs at line 86[3.6387]→[3.990:1011](∅→∅),[3.3422]→[3.990:1011](∅→∅),[3.1011]→[3.6388:6472](∅→∅),[3.6472]→[3.1075:1079](∅→∅),[3.1075]→[3.1075:1079](∅→∅)
type DayIntervals ={ dayBounds :: TimeInterval, loggedIntervals :: Array (Interval TimelineEvent)}type DayIntervals= { dayBounds :: TimeInterval, loggedIntervals :: Array (Interval TimelineEvent)} - replacement in client/src/Aftok/Timeline.purs at line 91
type History = M.Map Date DayIntervalstype History= M.Map Date DayIntervals - replacement in client/src/Aftok/Timeline.purs at line 94
type TimelineInput = Maybe Projecttype TimelineInput= Maybe Project - replacement in client/src/Aftok/Timeline.purs at line 97[3.1120]→[3.1124:1145](∅→∅),[3.3422]→[3.1124:1145](∅→∅),[3.1145]→[3.1121:1197](∅→∅),[3.1197]→[3.6473:6519](∅→∅),[3.6519]→[3.1198:1243](∅→∅),[3.302037]→[3.1198:1243](∅→∅),[3.1243]→[3.3532:3536](∅→∅),[3.3074]→[3.3532:3536](∅→∅),[3.302037]→[3.3532:3536](∅→∅),[3.3532]→[3.3532:3536](∅→∅)
type TimelineState ={ selectedProject :: Maybe Project, history :: M.Map Date DayIntervals, active :: Maybe (Interval TimelineEvent), activeHistory :: M.Map Date DayIntervals}type TimelineState= { selectedProject :: Maybe Project, history :: M.Map Date DayIntervals, active :: Maybe (Interval TimelineEvent), activeHistory :: M.Map Date DayIntervals} - replacement in client/src/Aftok/Timeline.purs at line 111
type Slot id = forall query. H.Slot query ProjectEvent idtype Slot id= forall query. H.Slot query ProjectEvent id - replacement in client/src/Aftok/Timeline.purs at line 114
type Slots =( projectList :: Project.ProjectListSlot Unit)type Slots= ( projectList :: Project.ProjectListSlot Unit) - replacement in client/src/Aftok/Timeline.purs at line 120[3.3273]→[3.184:204](∅→∅),[3.3688]→[3.184:204](∅→∅),[3.204]→[3.4103:4145](∅→∅),[3.4145]→[3.6520:6868](∅→∅),[3.682]→[3.254:258](∅→∅),[3.3396]→[3.254:258](∅→∅),[3.4296]→[3.254:258](∅→∅),[3.6868]→[3.254:258](∅→∅),[3.254]→[3.254:258](∅→∅)
type Capability m ={ timer :: EventSource m TimelineAction, logStart :: ProjectId -> m (Either TimelineError (KeyedEvent Instant)), logEnd :: ProjectId -> m (Either TimelineError (KeyedEvent Instant)), listIntervals :: ProjectId -> TimeSpan -> m (Either TimelineError (Array (Interval (KeyedEvent Instant)))), getLatestEvent :: ProjectId -> m (Either TimelineError (Maybe (KeyedEvent Instant)))}type Capability m= { timer :: EventSource m TimelineAction, logStart :: ProjectId -> m (Either TimelineError (KeyedEvent Instant)), logEnd :: ProjectId -> m (Either TimelineError (KeyedEvent Instant)), listIntervals :: ProjectId -> TimeSpan -> m (Either TimelineError (Array (Interval (KeyedEvent Instant)))), getLatestEvent :: ProjectId -> m (Either TimelineError (Maybe (KeyedEvent Instant)))} - replacement in client/src/Aftok/Timeline.purs at line 128[3.259]→[3.1160:1170](∅→∅),[3.1170]→[2.1469:1489](∅→∅),[2.1489]→[3.4330:4401](∅→∅),[3.4992]→[3.4330:4401](∅→∅),[3.4330]→[3.4330:4401](∅→∅),[3.4401]→[2.1490:1550](∅→∅),[2.1550]→[3.4447:4491](∅→∅),[3.5045]→[3.4447:4491](∅→∅),[3.4447]→[3.4447:4491](∅→∅),[3.415]→[3.302289:302306](∅→∅),[3.1229]→[3.302289:302306](∅→∅),[3.3574]→[3.302289:302306](∅→∅),[3.4491]→[3.302289:302306](∅→∅),[3.302289]→[3.302289:302306](∅→∅),[3.302306]→[3.1230:1276](∅→∅),[3.1276]→[3.302343:302371](∅→∅),[3.302343]→[3.302343:302371](∅→∅),[3.302371]→[3.1277:1314](∅→∅),[3.1314]→[3.302409:302417](∅→∅),[3.302409]→[3.302409:302417](∅→∅),[3.302417]→[3.4419:4429](∅→∅),[3.4419]→[3.4419:4429](∅→∅),[3.4429]→[2.1551:1658](∅→∅),[3.1277]→[3.4560:4585](∅→∅),[2.1658]→[3.4560:4585](∅→∅),[3.6944]→[3.4560:4585](∅→∅),[3.4560]→[3.4560:4585](∅→∅),[3.4585]→[3.3659:3683](∅→∅),[3.3659]→[3.3659:3683](∅→∅),[3.3683]→[3.1278:1309](∅→∅),[3.1309]→[3.3716:3724](∅→∅),[3.3716]→[3.3716:3724](∅→∅)
component:: forall query m. Monad m=> System m-> Capability m-> Project.Capability m-> H.Component HH.HTML query TimelineInput ProjectEvent mcomponent system caps pcaps = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval{ handleAction = eval, initialize = Just Initialize}} whereinitialState :: TimelineInput -> TimelineStateinitialState input ={ selectedProject: input, history: M.empty, active: Nothing, activeHistory: M.empty}component ::forall query m.Monad m =>System m ->Capability m ->Project.Capability m ->H.Component HH.HTML query TimelineInput ProjectEvent mcomponent system caps pcaps =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = eval, initialize = Just Initialize}}whereinitialState :: TimelineInput -> TimelineStateinitialState input ={ selectedProject: input, history: M.empty, active: Nothing, activeHistory: M.empty} - replacement in client/src/Aftok/Timeline.purs at line 155[3.4430]→[3.4586:4656](∅→∅),[3.4656]→[3.1337:1766](∅→∅),[3.3797]→[3.1337:1766](∅→∅),[3.1766]→[3.4657:4703](∅→∅),[3.4703]→[3.1815:1834](∅→∅),[3.1815]→[3.1815:1834](∅→∅),[3.1834]→[2.1659:1789](∅→∅),[2.1789]→[3.1955:2071](∅→∅),[3.4820]→[3.1955:2071](∅→∅),[3.1955]→[3.1955:2071](∅→∅),[3.2071]→[3.4821:4843](∅→∅),[3.4843]→[3.3926:3951](∅→∅),[3.3926]→[3.3926:3951](∅→∅),[3.3951]→[3.4844:4932](∅→∅),[3.4932]→[3.4031:4075](∅→∅),[3.4031]→[3.4031:4075](∅→∅),[3.4075]→[3.2072:2119](∅→∅)
render :: TimelineState -> H.ComponentHTML TimelineAction Slots mrender st =HH.section[P.classes (ClassName <$> ["section-border", "border-primary"])][HH.div[P.classes (ClassName <$> ["container", "pt-6"])][HH.h1[P.classes (ClassName <$> ["mb-0", "font-weight-bold", "text-center"])][HH.text "Time Tracker"],HH.p[P.classes (ClassName <$> ["col-md-5", "text-muted", "text-center", "mx-auto"])][HH.text "Your project timeline"],HH.div_[HH.slot _projectList unit (Project.projectListComponent system pcaps) st.selectedProject (Just <<< ProjectSelected)],HH.div[P.classes (ClassName <$> if isNothing st.selectedProject then ["collapse"] else [])]([HH.div_[HH.button[P.classes (ClassName <$> ["btn", "btn-primary", "float-left", "my-2"]),E.onClick \_ -> Just Start,P.disabled (isJust st.active)render :: TimelineState -> H.ComponentHTML TimelineAction Slots mrender st =HH.section[ P.classes (ClassName <$> [ "section-border", "border-primary" ]) ][ HH.div[ P.classes (ClassName <$> [ "container", "pt-6" ]) ][ HH.h1[ P.classes (ClassName <$> [ "mb-0", "font-weight-bold", "text-center" ]) ][ HH.text "Time Tracker" ], HH.p[ P.classes (ClassName <$> [ "col-md-5", "text-muted", "text-center", "mx-auto" ]) ][ HH.text "Your project timeline" ], HH.div_[ HH.slot _projectList unit (Project.projectListComponent system pcaps) st.selectedProject (Just <<< ProjectSelected) ], HH.div[ P.classes (ClassName <$> if isNothing st.selectedProject then [ "collapse" ] else []) ]( [ HH.div_[ HH.button[ P.classes (ClassName <$> [ "btn", "btn-primary", "float-left", "my-2" ]), E.onClick \_ -> Just Start, P.disabled (isJust st.active)][ HH.text "Start Work" ], HH.button[ P.classes (ClassName <$> [ "btn", "btn-primary", "float-right", "my-2" ]), E.onClick \_ -> Just Stop, P.disabled (isNothing st.active)][ HH.text "Stop Work" ]] - replacement in client/src/Aftok/Timeline.purs at line 186[3.4093]→[3.4093:4157](∅→∅),[3.4157]→[3.4933:5022](∅→∅),[3.5022]→[3.4238:4281](∅→∅),[3.4238]→[3.4238:4281](∅→∅),[3.4281]→[3.2120:2170](∅→∅),[3.2170]→[3.4281:4337](∅→∅),[3.4281]→[3.4281:4337](∅→∅),[3.4337]→[3.849:865](∅→∅),[3.849]→[3.849:865](∅→∅),[3.865]→[3.1310:1430](∅→∅)
[HH.text "Start Work"],HH.button[P.classes (ClassName <$> ["btn", "btn-primary", "float-right", "my-2"]),E.onClick \_ -> Just Stop,P.disabled (isNothing st.active)][HH.text "Stop Work"]]] <> (historyLine <$> reverse (M.toUnfoldable $ unionHistories st.history st.activeHistory)))<> (historyLine <$> reverse (M.toUnfoldable $ unionHistories st.history st.activeHistory))) - replacement in client/src/Aftok/Timeline.purs at line 189
]] - replacement in client/src/Aftok/Timeline.purs at line 191[3.4813]→[3.5046:5142](∅→∅),[3.5142]→[3.1431:1538](∅→∅),[3.5279]→[3.1431:1538](∅→∅),[3.1538]→[2.1790:1899](∅→∅),[3.1016]→[3.5214:5215](∅→∅),[3.1538]→[3.5214:5215](∅→∅),[2.1899]→[3.5214:5215](∅→∅),[3.304245]→[3.5214:5215](∅→∅),[3.5214]→[3.5214:5215](∅→∅),[3.5215]→[3.1539:1571](∅→∅),[3.1571]→[3.683:735](∅→∅),[3.735]→[3.1620:1675](∅→∅),[3.1620]→[3.1620:1675](∅→∅),[3.1675]→[3.736:810](∅→∅),[3.810]→[3.5143:5252](∅→∅),[3.5291]→[3.5291:5337](∅→∅),[3.5337]→[3.915:916](∅→∅),[3.1825]→[3.915:916](∅→∅),[3.916]→[2.1900:1968](∅→∅),[2.1968]→[3.1138:1139](∅→∅),[3.6922]→[3.1138:1139](∅→∅),[3.2377]→[3.1138:1139](∅→∅),[3.2051]→[3.2671:2898](∅→∅),[3.5265]→[3.2671:2898](∅→∅),[3.2688]→[3.304322:304323](∅→∅),[3.2898]→[3.304322:304323](∅→∅),[3.5641]→[3.304322:304323](∅→∅),[3.304322]→[3.304322:304323](∅→∅),[3.304323]→[3.2899:2986](∅→∅),[3.2782]→[3.304398:304399](∅→∅),[3.2986]→[3.304398:304399](∅→∅),[3.5953]→[3.304398:304399](∅→∅),[3.304398]→[3.304398:304399](∅→∅),[3.304399]→[3.2987:3233](∅→∅),[3.3233]→[3.304477:304478](∅→∅),[3.304477]→[3.304477:304478](∅→∅),[3.304478]→[3.5338:5431](∅→∅),[3.5431]→[3.2872:2973](∅→∅),[3.6040]→[3.2872:2973](∅→∅),[3.2872]→[3.2872:2973](∅→∅),[3.2973]→[3.6041:6121](∅→∅),[3.6121]→[3.3234:3279](∅→∅),[3.3279]→[3.3059:3060](∅→∅),[3.3059]→[3.3059:3060](∅→∅),[3.3060]→[3.5432:5523](∅→∅),[3.5523]→[3.3147:3244](∅→∅),[3.6207]→[3.3147:3244](∅→∅),[3.3147]→[3.3147:3244](∅→∅),[3.3244]→[3.6208:6287](∅→∅),[3.6287]→[3.3280:3429](∅→∅)
eval :: TimelineAction -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m Uniteval action = docase action ofInitialize -> dovoid $ H.subscribe caps.timercurrentProject <- H.gets (_.selectedProject)traverse_ setStateForProject currentProjectProjectSelected p -> dooldActive <- isJust <$> H.gets (_.active)currentProject <- H.gets (_.selectedProject)-- End any active intervals when switching projects.when (oldActive && any (\p' -> (unwrap p').projectId /= (unwrap p).projectId) currentProject) $ do(traverse_ logEnd currentProject)H.raise (ProjectChange p)setStateForProject pStart -> doproject <- H.gets (_.selectedProject)traverse_ logStart projectStop -> docurrentProject <- H.gets (_.selectedProject)traverse_ logEnd currentProjectRefresh -> dot <- lift $ system.nowH.modify_ (refresh t)-- common updates, irrespective of actionactive <- H.gets (_.active)activeHistory <- lift <<< map (fromMaybe M.empty) <<< runMaybeT $ toHistory system (U.fromMaybe active)H.modify_ (_ { activeHistory = activeHistory })logStart :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitlogStart (Project' p) = dologged <- lift $ caps.logStart p.projectIdcase logged ofLeft err -> lift <<< system.log $ "Failed to start timer: " <> show errRight t -> H.modify_ (updateStart t)logEnd :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitlogEnd (Project' p) = dologged <- lift $ caps.logEnd p.projectIdcase logged ofLeft err -> lift <<< system.log $ "Failed to stop timer: " <> show errRight t -> docurrentState <- H.getupdatedState <- lift $ updateStop system t currentStateH.put updatedStateeval :: TimelineAction -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m Uniteval action = docase action ofInitialize -> dovoid $ H.subscribe caps.timercurrentProject <- H.gets (_.selectedProject)traverse_ setStateForProject currentProjectProjectSelected p -> dooldActive <- isJust <$> H.gets (_.active)currentProject <- H.gets (_.selectedProject)-- End any active intervals when switching projects.when (oldActive && any (\p' -> (unwrap p').projectId /= (unwrap p).projectId) currentProject)$ do(traverse_ logEnd currentProject)H.raise (ProjectChange p)setStateForProject pStart -> doproject <- H.gets (_.selectedProject)traverse_ logStart projectStop -> docurrentProject <- H.gets (_.selectedProject)traverse_ logEnd currentProjectRefresh -> dot <- lift $ system.nowH.modify_ (refresh t)-- common updates, irrespective of actionactive <- H.gets (_.active)activeHistory <- lift <<< map (fromMaybe M.empty) <<< runMaybeT $ toHistory system (U.fromMaybe active)H.modify_ (_ { activeHistory = activeHistory }) - replacement in client/src/Aftok/Timeline.purs at line 221
setStateForProject :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitsetStateForProject p = dotimeSpan <- TL.Before <$> lift system.nowDateTime -- FIXME, should come from a form controlintervals' <- lift $ caps.listIntervals (unwrap p).projectId timeSpanintervals <- lift $ case intervals' ofLeft err ->(system.log $ "Error occurred listing intervals" <> show err ) *>pure []Right ivals ->pure $ map (map LoggedEvent) ivalslogStart :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitlogStart (Project' p) = dologged <- lift $ caps.logStart p.projectIdcase logged ofLeft err -> lift <<< system.log $ "Failed to start timer: " <> show errRight t -> H.modify_ (updateStart t) - replacement in client/src/Aftok/Timeline.purs at line 228
history' <- lift <<< runMaybeT $ toHistory system intervalshist <- case history' ofNothing -> lift $ system.log "Project history was empty." *> pure M.emptyJust h -> pure hlogEnd :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitlogEnd (Project' p) = dologged <- lift $ caps.logEnd p.projectIdcase logged ofLeft err -> lift <<< system.log $ "Failed to stop timer: " <> show errRight t -> docurrentState <- H.getupdatedState <- lift $ updateStop system t currentStateH.put updatedState - replacement in client/src/Aftok/Timeline.purs at line 238
latestEventResponse <- lift $ caps.getLatestEvent (unwrap p).projectIdnow <- lift $ system.nowactive <- lift $ case latestEventResponse ofLeft err ->(system.log $ "Error occurred retrieving the latest event: " <> show err) *>pure NothingRight latestEvent -> dolet activeInterval :: TL.KeyedEvent Instant -> m (Maybe (Interval TimelineEvent))setStateForProject :: Project -> H.HalogenM TimelineState TimelineAction Slots ProjectEvent m UnitsetStateForProject p = dotimeSpan <- TL.Before <$> lift system.nowDateTime -- FIXME, should come from a form controlintervals' <- lift $ caps.listIntervals (unwrap p).projectId timeSpanintervals <-lift$ case intervals' ofLeft err ->(system.log $ "Error occurred listing intervals" <> show err)*> pure []Right ivals -> pure $ map (map LoggedEvent) ivalshistory' <- lift <<< runMaybeT $ toHistory system intervalshist <- case history' ofNothing -> lift $ system.log "Project history was empty." *> pure M.emptyJust h -> pure hlatestEventResponse <- lift $ caps.getLatestEvent (unwrap p).projectIdnow <- lift $ system.nowactive <-lift$ case latestEventResponse ofLeft err ->(system.log $ "Error occurred retrieving the latest event: " <> show err)*> pure NothingRight latestEvent -> doletactiveInterval :: TL.KeyedEvent Instant -> m (Maybe (Interval TimelineEvent)) - replacement in client/src/Aftok/Timeline.purs at line 265
TL.StartEvent i ->(system.log $ "Project has an open active interval starting " <> show i) *>(Just <<< interval (LoggedEvent ev) <<< PhantomEvent <$> system.now)TL.StopEvent _ ->pure Nothingjoin <$> traverse activeInterval latestEventTL.StartEvent i ->(system.log $ "Project has an open active interval starting " <> show i)*> (Just <<< interval (LoggedEvent ev) <<< PhantomEvent <$> system.now)TL.StopEvent _ -> pure Nothingjoin <$> traverse activeInterval latestEventH.modify_ (_ { selectedProject = Just p, history = hist, active = active }) - replacement in client/src/Aftok/Timeline.purs at line 272
H.modify_ (_ { selectedProject = Just p, history = hist, active = active })historyLine:: forall w i. Tuple Date DayIntervals-> HH.HTML w ihistoryLine (Tuple d xs) =datedLine d xs.dayBounds xs.loggedIntervalshistoryLine ::forall w i.Tuple Date DayIntervals ->HH.HTML w ihistoryLine (Tuple d xs) = datedLine d xs.dayBounds xs.loggedIntervals - replacement in client/src/Aftok/Timeline.purs at line 278[3.6541]→[3.3580:3617](∅→∅),[3.3617]→[3.7173:7228](∅→∅),[3.7228]→[3.3633:3650](∅→∅),[3.6596]→[3.3633:3650](∅→∅)
datedLine:: forall w i. Date-> TimeInterval-> Array (Interval TimelineEvent)-> HH.HTML w idatedLine ::forall w i.Date ->TimeInterval ->Array (Interval TimelineEvent) ->HH.HTML w i - replacement in client/src/Aftok/Timeline.purs at line 287
clear clearBothclear clearBoth - replacement in client/src/Aftok/Timeline.purs at line 291
[ CSS.style doborder solid (px 3.0) (rgb 0x00 0xFF 0x00)borderRadius px5 px5 px5 px5height (px $ 44.0)display flex, P.classes (ClassName <$> ["my-2"])](evalState (traverse (intervalHtml dateBounds) xs) 0.0)[ CSS.style doborder solid (px 3.0) (rgb 0x00 0xFF 0x00)borderRadius px5 px5 px5 px5height (px $ 44.0)display flex, P.classes (ClassName <$> [ "my-2" ])](evalState (traverse (intervalHtml dateBounds) xs) 0.0) - replacement in client/src/Aftok/Timeline.purs at line 300
wherepx5 = px 5.0wherepx5 = px 5.0 - replacement in client/src/Aftok/Timeline.purs at line 304
dateStr d = (show <<< fromEnum $ year d) <> "-"<> (show <<< fromEnum $ month d) <> "-"<> (show <<< fromEnum $ day d)dateStr d =(show <<< fromEnum $ year d) <> "-"<> (show <<< fromEnum $ month d)<> "-"<> (show <<< fromEnum $ day d) - replacement in client/src/Aftok/Timeline.purs at line 310[3.5481]→[3.3339:3352](∅→∅),[3.3352]→[3.4049:4066](∅→∅),[3.4066]→[3.7229:7275](∅→∅),[3.7275]→[3.4067:4099](∅→∅),[3.3387]→[3.4067:4099](∅→∅)
intervalHtml:: forall w i. TimeInterval-> Interval TimelineEvent-> State Number (HH.HTML w i)intervalHtml ::forall w i.TimeInterval ->Interval TimelineEvent ->State Number (HH.HTML w i) - replacement in client/src/Aftok/Timeline.purs at line 317[3.3412]→[3.1082:1128](∅→∅),[3.4164]→[3.1082:1128](∅→∅),[3.6001]→[3.1082:1128](∅→∅),[3.7523]→[3.1082:1128](∅→∅),[3.305031]→[3.1082:1128](∅→∅),[3.1128]→[3.7276:7392](∅→∅),[3.3487]→[3.3544:3565](∅→∅),[3.7392]→[3.3544:3565](∅→∅),[3.1204]→[3.3544:3565](∅→∅),[3.3565]→[3.936:973](∅→∅)
let maxWidth = ilen limits.start limits.endileft = ilen limits.start (tlEventTime i.start)iwidth = ilen (tlEventTime i.start) (tlEventTime i.end)px5 = px (5.0)toPct n = 100.0 * n / maxWidthletmaxWidth = ilen limits.start limits.endileft = ilen limits.start (tlEventTime i.start)iwidth = ilen (tlEventTime i.start) (tlEventTime i.end)px5 = px (5.0)toPct n = 100.0 * n / maxWidth - replacement in client/src/Aftok/Timeline.purs at line 328[3.7447]→[3.4247:4263](∅→∅),[3.4247]→[3.4247:4263](∅→∅),[3.4263]→[3.3488:3507](∅→∅),[3.305233]→[3.3488:3507](∅→∅),[3.305280]→[3.305280:305325](∅→∅),[3.305325]→[3.4264:4312](∅→∅),[3.4312]→[3.1007:1052](∅→∅),[3.1007]→[3.1007:1052](∅→∅),[3.1052]→[3.305417:305467](∅→∅),[3.1346]→[3.305417:305467](∅→∅),[3.305417]→[3.305417:305467](∅→∅)
pure $ HH.div[ CSS.style dobackgroundColor (rgb 0xf0 0x98 0x18)marginLeft (pct $ toPct ileft - offset)width (pct $ max (toPct iwidth) 0.5)borderRadius px5 px5 px5 px5][]pure$ HH.div[ CSS.style dobackgroundColor (rgb 0xf0 0x98 0x18)marginLeft (pct $ toPct ileft - offset)width (pct $ max (toPct iwidth) 0.5)borderRadius px5 px5 px5 px5][] - replacement in client/src/Aftok/Timeline.purs at line 339[3.305508]→[3.305508:305594](∅→∅),[3.305594]→[3.3637:3678](∅→∅),[3.3678]→[3.305634:305671](∅→∅),[3.305634]→[3.305634:305671](∅→∅),[3.305671]→[3.6221:6222](∅→∅),[3.6221]→[3.6221:6222](∅→∅),[3.6222]→[3.305672:305763](∅→∅),[3.1936]→[3.6222:6223](∅→∅),[3.305763]→[3.6222:6223](∅→∅),[3.6222]→[3.6222:6223](∅→∅)
timer = EventSource.affEventSource \emitter -> dofiber <- Aff.forkAff $ forever doAff.delay $ Aff.Milliseconds 10000.0EventSource.emit emitter Refreshpure $ EventSource.Finalizer doAff.killFiber (error "Event source finalized") fibertimer =EventSource.affEventSource \emitter -> dofiber <-Aff.forkAff$ forever doAff.delay $ Aff.Milliseconds 10000.0EventSource.emit emitter Refreshpure$ EventSource.Finalizer doAff.killFiber (error "Event source finalized") fiber - replacement in client/src/Aftok/Timeline.purs at line 351
updateStart ev s =s { active = s.active <|> Just (TL.interval (LoggedEvent ev) (PhantomEvent <<< eventTime <<< event $ ev)) }updateStart ev s = s { active = s.active <|> Just (TL.interval (LoggedEvent ev) (PhantomEvent <<< eventTime <<< event $ ev)) } - replacement in client/src/Aftok/Timeline.purs at line 353[3.6388]→[3.4443:4497](∅→∅),[3.4497]→[3.7647:7672](∅→∅),[3.7672]→[3.4511:4552](∅→∅),[3.4511]→[3.4511:4552](∅→∅)
updateStop:: forall m. Monad m=> System m-> KeyedEvent Instant-> TimelineState-> m TimelineStateupdateStop ::forall m.Monad m =>System m ->KeyedEvent Instant ->TimelineState ->m TimelineState - replacement in client/src/Aftok/Timeline.purs at line 361
let updateHistory i = runMaybeT $ toHistory system [TL.interval (start i) (LoggedEvent ev)]letupdateHistory i = runMaybeT $ toHistory system [ TL.interval (start i) (LoggedEvent ev) ] - replacement in client/src/Aftok/Timeline.purs at line 364
pure { selectedProject: st.selectedProject, history: maybe st.history (unionHistories st.history) newHistory, active: Nothing, activeHistory: M.empty}pure{ selectedProject: st.selectedProject, history: maybe st.history (unionHistories st.history) newHistory, active: Nothing, activeHistory: M.empty} - replacement in client/src/Aftok/Timeline.purs at line 373
s { active = map (\i -> TL.interval (start i) (PhantomEvent t)) s.actives{ active = map (\i -> TL.interval (start i) (PhantomEvent t)) s.active - replacement in client/src/Aftok/Timeline.purs at line 379[3.3612]→[3.6813:6842](∅→∅),[3.306039]→[3.6813:6842](∅→∅),[3.6813]→[3.6813:6842](∅→∅),[3.6842]→[3.4944:4992](∅→∅)
let n (Milliseconds x) = xin n (unInstant _end) - n (unInstant _start)letn (Milliseconds x) = xinn (unInstant _end) - n (unInstant _start) - replacement in client/src/Aftok/Timeline.purs at line 385
apiCapability =apiCapability = - replacement in client/src/Aftok/Timeline.purs at line 388
, logEnd: TL.apiLogEnd, logEnd: TL.apiLogEnd - replacement in client/src/Aftok/Timeline.purs at line 397
, logEnd: \_ -> Right <<< keyedEvent "" <<< StopEvent <$> liftEffect now, logEnd: \_ -> Right <<< keyedEvent "" <<< StopEvent <$> liftEffect now - replacement in client/src/Aftok/Timeline.purs at line 402
utcDayBounds :: Instant -> TimeIntervalutcDayBounds :: Instant -> TimeInterval - replacement in client/src/Aftok/Timeline.purs at line 404
let startOfDay = DateTime (date $ toDateTime i) bottomendOfDay = DT.adjust (Days 1.0) startOfDaystartInstant = fromDateTime startOfDayin TL.interval startInstant (maybe startInstant fromDateTime endOfDay)letstartOfDay = DateTime (date $ toDateTime i) bottomendOfDay = DT.adjust (Days 1.0) startOfDay - replacement in client/src/Aftok/Timeline.purs at line 409
localDayBounds:: forall m. Monad m=> System m-> Instant-> MaybeT m (Tuple Date TimeInterval)startInstant = fromDateTime startOfDayinTL.interval startInstant (maybe startInstant fromDateTime endOfDay)localDayBounds ::forall m.Monad m =>System m ->Instant ->MaybeT m (Tuple Date TimeInterval) - replacement in client/src/Aftok/Timeline.purs at line 421
nextNoon <- MaybeT <<< pure $fromDateTime <$> (DT.adjust (Hours 12.0) <=< DT.adjust (Days 1.0) $(toDateTime start))nextNoon <-MaybeT <<< pure$ fromDateTime<$> ( DT.adjust (Hours 12.0) <=< DT.adjust (Days 1.0)$ (toDateTime start)) - replacement in client/src/Aftok/Timeline.purs at line 430[3.5866]→[3.5866:5922](∅→∅),[3.5922]→[3.8379:8408](∅→∅),[3.8408]→[3.5937:5985](∅→∅),[3.5937]→[3.5937:5985](∅→∅)
splitInterval:: forall m. Monad m=> System m-> Interval TimelineEvent-> MaybeT m (Array (Tuple Date DayIntervals))splitInterval ::forall m.Monad m =>System m ->Interval TimelineEvent ->MaybeT m (Array (Tuple Date DayIntervals)) - replacement in client/src/Aftok/Timeline.purs at line 441
split <- if tlEventTime (end i) < end boundsthen dosplit <-if tlEventTime (end i) < end bounds then do - replacement in client/src/Aftok/Timeline.purs at line 444
pure [Tuple date { dayBounds: bounds, loggedIntervals: [i] }]pure [ Tuple date { dayBounds: bounds, loggedIntervals: [ i ] } ] - replacement in client/src/Aftok/Timeline.purs at line 446
let splitEvent = PhantomEvent (end bounds)currInterval = Tuple date { dayBounds: bounds, loggedIntervals: [interval (start i) splitEvent] }nextInterval = interval splitEvent (end i)letsplitEvent = PhantomEvent (end bounds)currInterval = Tuple date { dayBounds: bounds, loggedIntervals: [ interval (start i) splitEvent ] }nextInterval = interval splitEvent (end i) - replacement in client/src/Aftok/Timeline.purs at line 457[3.6592]→[3.6592:6644](∅→∅),[3.6644]→[3.9271:9307](∅→∅),[3.9307]→[3.6665:6705](∅→∅),[3.6665]→[3.6665:6705](∅→∅)
toHistory:: forall m. Monad m=> System m-> Array (Interval TimelineEvent)-> MaybeT m (M.Map Date DayIntervals)toHistory ::forall m.Monad m =>System m ->Array (Interval TimelineEvent) ->MaybeT m (M.Map Date DayIntervals) - replacement in client/src/Aftok/Timeline.purs at line 468
unionDayIntervals d1 d2 =unionDayIntervals d1 d2 = - replacement in client/src/Aftok/Timeline.purs at line 470
, loggedIntervals: d1.loggedIntervals <> d2.loggedIntervals, loggedIntervals: d1.loggedIntervals <> d2.loggedIntervals - edit in client/src/Aftok/Timeline.purs at line 475
- edit in client/src/Aftok/Types.purs at line 4
- edit in client/src/Aftok/Types.purs at line 7
- edit in client/src/Aftok/Types.purs at line 21[3.5636]→[3.3525:3526](∅→∅),[3.7262]→[3.3525:3526](∅→∅),[3.11251]→[3.3525:3526](∅→∅),[3.7486]→[3.3525:3526](∅→∅)
- edit in client/src/Aftok/Types.purs at line 28
- replacement in client/src/Aftok/Types.purs at line 32[3.7525]→[3.11511:11606](∅→∅),[3.11606]→[3.1480:1504](∅→∅),[3.1504]→[3.141:173](∅→∅),[3.173]→[3.11606:11677](∅→∅),[3.1504]→[3.11606:11677](∅→∅),[3.11606]→[3.11606:11677](∅→∅),[3.11677]→[3.7263:7288](∅→∅),[3.7288]→[3.11677:11681](∅→∅),[3.11677]→[3.11677:11681](∅→∅)
type System m ={ log :: String -> m Unit, error :: String -> m Unit, now :: m Instant, getHash :: m String, setHash :: String -> m Unit, nowDateTime :: m DateTime, preventDefault :: WE.Event -> m Unit, dateFFI :: DateFFI m}type System m= { log :: String -> m Unit, error :: String -> m Unit, now :: m Instant, getHash :: m String, setHash :: String -> m Unit, nowDateTime :: m DateTime, preventDefault :: WE.Event -> m Unit, dateFFI :: DateFFI m} - replacement in client/src/Aftok/Types.purs at line 44
liveSystem =liveSystem = - replacement in client/src/Aftok/Types.purs at line 55
type DateFFI m ={ midnightLocal :: Instant -> m (Maybe (Tuple Date Instant))}type DateFFI m= { midnightLocal :: Instant -> m (Maybe (Tuple Date Instant))} - replacement in client/src/Aftok/Types.purs at line 60
jsDateFFI =jsDateFFI = - replacement in client/src/Aftok/Types.purs at line 66
let jsDate = JD.fromInstant iyear <- JD.getFullYear jsDateletjsDate = JD.fromInstant iyear <- JD.getFullYear jsDate - replacement in client/src/Aftok/Types.purs at line 70
day <- JD.getDate jsDateday <- JD.getDate jsDate - replacement in client/src/Aftok/Types.purs at line 72
let date = JD.toDate jsMidnightletdate = JD.toDate jsMidnight - replacement in client/src/Aftok/Types.purs at line 77
midnightLocalJS year month day = JD.jsdateLocal{ year, month, day, hour: 0.0, minute: 0.0, second: 0.0, millisecond: 0.0}midnightLocalJS year month day =JD.jsdateLocal{ year, month, day, hour: 0.0, minute: 0.0, second: 0.0, millisecond: 0.0} - replacement in client/src/Aftok/Types.purs at line 89
hoistDateFFI nt ffi ={ midnightLocal: \i -> nt (ffi.midnightLocal i)}hoistDateFFI nt ffi ={ midnightLocal: \i -> nt (ffi.midnightLocal i)} - replacement in client/src/Aftok/Types.purs at line 93
data APIErrordata APIError - replacement in client/src/Aftok/Types.purs at line 101
ParseFailure js e -> "ParseFailure (" <> show (stringify js) <> ") " <> show eParseFailure js e -> "ParseFailure (" <> show (stringify js) <> ") " <> show e - replacement in client/src/Aftok/Types.purs at line 104
newtype ProjectId = ProjectId UUIDnewtype ProjectId= ProjectId UUID - edit in client/src/Aftok/Types.purs at line 108
- replacement in client/src/Aftok/Types.purs at line 114
newtype Project' date = Project'newtype Project' date= Project' - edit in client/src/Aftok/Types.purs at line 121
- replacement in client/src/Aftok/Types.purs at line 124
type Project = Project' DateTimetype Project= Project' DateTime - edit in client/src/Aftok/Types.purs at line 134
- replacement in client/src/Aftok/Types.purs at line 135
projectId <- ProjectId <$> (note "Failed to decode project UUID" $ parseUUID projectIdStr)projectName <- project .: "projectName"projectId <- ProjectId <$> (note "Failed to decode project UUID" $ parseUUID projectIdStr)projectName <- project .: "projectName" - replacement in client/src/Aftok/Types.purs at line 138
initiatorStr <- project .: "initiator"initiator <- note "Failed to decode initiator UUID" $ parseUUID initiatorStrinitiatorStr <- project .: "initiator"initiator <- note "Failed to decode initiator UUID" $ parseUUID initiatorStr - replacement in client/src/Aftok/Types.purs at line 142
newtype JsonCompose f g a = JsonCompose (Compose f g a)newtype JsonCompose f g a= JsonCompose (Compose f g a) - replacement in client/src/Aftok/Types.purs at line 167
str <- except $ decodeJson jsonstr <- except $ decodeJson json - replacement in client/src/Aftok/Types.purs at line 173
except $ note ("Unable to convert date " <> show jsDate <> " to a valid DateTime value.")(JD.toDateTime jsDate)except$ note ("Unable to convert date " <> show jsDate <> " to a valid DateTime value.")(JD.toDateTime jsDate) - replacement in client/src/Aftok/Types.purs at line 182
parseDatedResponse:: forall t. Traversable t=> DecodeJson (t String)=> Either AJAX.Error (Response Json)-> ExceptT APIError Effect (t Instant)parseDatedResponse ::forall t.Traversable t =>DecodeJson (t String) =>Either AJAX.Error (Response Json) ->ExceptT APIError Effect (t Instant) - replacement in client/src/Aftok/Types.purs at line 189
Left err ->throwError $ Error { status: Nothing, message: printError err }Left err -> throwError $ Error { status: Nothing, message: printError err } - replacement in client/src/Aftok/Types.purs at line 191
StatusCode 403 ->throwError $ ForbiddenStatusCode 200 ->withExceptT (ParseFailure r.body) $ map fromDateTime <$> decodeDatedJson r.bodyother ->throwError $ Error { status: Just other, message: r.statusText }[3.13331]StatusCode 403 -> throwError $ ForbiddenStatusCode 200 -> withExceptT (ParseFailure r.body) $ map fromDateTime <$> decodeDatedJson r.bodyother -> throwError $ Error { status: Just other, message: r.statusText } - edit in client/src/Landkit/Card.purs at line 4
- replacement in client/src/Landkit/Card.purs at line 15
[ P.classes (ClassName <$> ["card", "card-row"]) ][ P.classes (ClassName <$> [ "card", "card-row" ]) ] - edit in client/src/Landkit/Modal.purs at line 4
- replacement in client/src/Landkit/Modal.purs at line 16
[ P.classes (ClassName <$> ["modal", "fade"])[ P.classes (ClassName <$> [ "modal", "fade" ]) - replacement in client/src/Landkit/Modal.purs at line 24
[ P.classes (ClassName <$> ["modal-dialog", "modal-lg", "modal-dialog-centered"])-- , P.role "document"][ HH.div[ P.classes (ClassName <$> ["modal-content"])]children][ P.classes (ClassName <$> [ "modal-dialog", "modal-lg", "modal-dialog-centered" ])-- , P.role "document"][ HH.div[ P.classes (ClassName <$> [ "modal-content" ]) ]children] - edit in client/src/Main.purs at line 4
- edit in client/src/Main.purs at line 5[3.932]→[3.492:493](∅→∅),[3.3721]→[3.492:493](∅→∅),[3.6963]→[3.492:493](∅→∅),[3.307475]→[3.492:493](∅→∅),[3.492]→[3.492:493](∅→∅)
- edit in client/src/Main.purs at line 8
- edit in client/src/Main.purs at line 11
- edit in client/src/Main.purs at line 14
- edit in client/src/Main.purs at line 22[3.400]→[3.1094:1095](∅→∅),[3.1158]→[3.1094:1095](∅→∅),[3.1485]→[3.1094:1095](∅→∅),[3.3360]→[3.1094:1095](∅→∅),[3.7084]→[3.1094:1095](∅→∅),[3.1094]→[3.1094:1095](∅→∅)
- replacement in client/src/Main.purs at line 31
main = runHalogenAff dobody <- awaitBodylet --login = Login.mockCapabilitymain =runHalogenAff dobody <- awaitBodylet --login = Login.mockCapability - edit in client/src/Main.purs at line 36
- edit in client/src/Main.purs at line 38
- edit in client/src/Main.purs at line 40
- edit in client/src/Main.purs at line 42
- edit in client/src/Main.purs at line 44
mainComponent = component liveSystem login signup timeline project overviewhalogenIO <- runUI mainComponent unit body - replacement in client/src/Main.purs at line 45
void $ liftEffect $ matchesWith (match mainRoute) \oldMay new ->when (oldMay /= Just new) dolaunchAff_ <<< halogenIO.query <<< H.tell $ Navigate newmainComponent = component liveSystem login signup timeline project overviewhalogenIO <- runUI mainComponent unit bodyvoid $ liftEffect$ matchesWith (match mainRoute) \oldMay new ->when (oldMay /= Just new) dolaunchAff_ <<< halogenIO.query <<< H.tell $ Navigate new - replacement in client/src/Main.purs at line 52
data Viewdata View - replacement in client/src/Main.purs at line 57
| VTimeline| VTimeline - replacement in client/src/Main.purs at line 60[3.649]→[3.649:721](∅→∅),[3.721]→[3.7032:7064](∅→∅),[3.7064]→[3.721:757](∅→∅),[3.721]→[3.721:757](∅→∅)
mainRoute = oneOf[ VSignup <$ lit "signup", VLogin <$ lit "login", VOverview <$ lit "overview", VTimeline <$ lit "timeline"]mainRoute =oneOf[ VSignup <$ lit "signup", VLogin <$ lit "login", VOverview <$ lit "overview", VTimeline <$ lit "timeline"] - edit in client/src/Main.purs at line 78
- replacement in client/src/Main.purs at line 81
data MainQuery a = Navigate View adata MainQuery a= Navigate View a - replacement in client/src/Main.purs at line 84[3.1050]→[3.1752:1769](∅→∅),[3.1117]→[3.1752:1769](∅→∅),[3.1769]→[3.1051:1068](∅→∅),[3.1068]→[3.1790:1818](∅→∅),[3.1790]→[3.1790:1818](∅→∅),[3.1818]→[3.7092:7129](∅→∅),[3.7129]→[3.1818:1822](∅→∅),[3.1818]→[3.1818:1822](∅→∅)
type MainState ={ view :: View, config :: Signup.Config, selectedProject :: Maybe Project}type MainState= { view :: View, config :: Signup.Config, selectedProject :: Maybe Project} - replacement in client/src/Main.purs at line 97[3.1119]→[3.308119:308133](∅→∅),[3.308133]→[3.1694:1723](∅→∅),[3.1723]→[3.1912:1943](∅→∅),[3.1943]→[3.7162:7197](∅→∅),[3.1943]→[3.1723:1758](∅→∅),[3.7197]→[3.1723:1758](∅→∅),[3.1723]→[3.1723:1758](∅→∅),[3.282]→[3.308197:308201](∅→∅),[3.1758]→[3.308197:308201](∅→∅),[3.308197]→[3.308197:308201](∅→∅)
type Slots =( login :: Login.Slot Unit, signup :: Signup.Slot Unit, overview :: Overview.Slot Unit, timeline :: Timeline.Slot Unit)type Slots= ( login :: Login.Slot Unit, signup :: Signup.Slot Unit, overview :: Overview.Slot Unit, timeline :: Timeline.Slot Unit) - edit in client/src/Main.purs at line 105
- edit in client/src/Main.purs at line 107
- edit in client/src/Main.purs at line 109
- replacement in client/src/Main.purs at line 112[3.1182]→[3.308277:308288](∅→∅),[3.308288]→[3.1069:1096](∅→∅),[3.1096]→[3.13721:13772](∅→∅),[3.13721]→[3.13721:13772](∅→∅),[3.13772]→[3.1981:2006](∅→∅),[3.2006]→[3.13772:13825](∅→∅),[3.13772]→[3.13772:13825](∅→∅),[3.13825]→[3.7239:7266](∅→∅),[3.7266]→[3.1097:1147](∅→∅),[3.13825]→[3.1097:1147](∅→∅),[3.1147]→[3.7267:7337](∅→∅),[3.1831]→[3.308429:308458](∅→∅),[3.2071]→[3.308429:308458](∅→∅),[3.4028]→[3.308429:308458](∅→∅),[3.7337]→[3.308429:308458](∅→∅),[3.13925]→[3.308429:308458](∅→∅),[3.308429]→[3.308429:308458](∅→∅),[3.308458]→[3.4029:4065](∅→∅),[3.4065]→[3.1148:1219](∅→∅),[3.1219]→[3.4094:4140](∅→∅),[3.4094]→[3.4094:4140](∅→∅),[3.4140]→[3.1220:1224](∅→∅)
component:: forall input output m. Monad m=> System m-> Login.Capability m-> Signup.Capability m-> Timeline.Capability m-> Project.Capability m-> Overview.Capability m-> H.Component HH.HTML MainQuery input output mcomponent system loginCap signupCap tlCap pCap ovCap = H.mkComponent{ initialState, render, eval: H.mkEval $ H.defaultEval{ handleAction = handleAction, handleQuery = handleQuery, initialize = Just Initialize}}component ::forall input output m.Monad m =>System m ->Login.Capability m ->Signup.Capability m ->Timeline.Capability m ->Project.Capability m ->Overview.Capability m ->H.Component HH.HTML MainQuery input output mcomponent system loginCap signupCap tlCap pCap ovCap =H.mkComponent{ initialState, render, eval:H.mkEval$ H.defaultEval{ handleAction = handleAction, handleQuery = handleQuery, initialize = Just Initialize}} - replacement in client/src/Main.purs at line 135[3.1232]→[3.308528:308567](∅→∅),[3.308528]→[3.308528:308567](∅→∅),[3.308567]→[3.9266:9389](∅→∅),[3.9389]→[3.7338:7371](∅→∅),[3.7371]→[3.9389:9397](∅→∅),[3.9389]→[3.9389:9397](∅→∅)
initialState :: input -> MainStateinitialState _ ={ view: VLoading, config: { recaptchaKey: "6LdiA78ZAAAAAGGvDId_JmDbhalduIDZSqbuikfq" }, selectedProject: Nothing}initialState :: input -> MainStateinitialState _ ={ view: VLoading, config: { recaptchaKey: "6LdiA78ZAAAAAGGvDId_JmDbhalduIDZSqbuikfq" }, selectedProject: Nothing} - replacement in client/src/Main.purs at line 142[3.308599]→[3.13926:13988](∅→∅),[3.13988]→[3.2143:2193](∅→∅),[3.2193]→[3.1631:1702](∅→∅),[3.1631]→[3.1631:1702](∅→∅)
render :: MainState -> H.ComponentHTML MainAction Slots mrender st = case st.view ofVLoading ->HH.div [P.classes [ClassName "loader"]] [HH.text "Loading..."]render :: MainState -> H.ComponentHTML MainAction Slots mrender st = case st.view ofVLoading -> HH.div [ P.classes [ ClassName "loader" ] ] [ HH.text "Loading..." ]VSignup ->HH.div_[ HH.slot _signup unit (Signup.component system signupCap st.config) unit (Just <<< SignupAction) ]VLogin ->HH.div_[ HH.slot _login unit (Login.component system loginCap) unit (Just <<< LoginAction) ]VOverview ->withNavBar$ HH.div_[ HH.slot _overview unit (Overview.component system ovCap pCap) st.selectedProject (Just <<< ProjectAction) ]VTimeline ->withNavBar$ HH.div_[ HH.slot _timeline unit (Timeline.component system tlCap pCap) st.selectedProject (Just <<< ProjectAction) ] - replacement in client/src/Main.purs at line 160[3.1703]→[3.2194:2212](∅→∅),[3.2212]→[3.1704:1721](∅→∅),[3.308708]→[3.1704:1721](∅→∅),[3.1721]→[3.2213:2323](∅→∅),[3.2323]→[3.1812:1813](∅→∅),[3.14087]→[3.1812:1813](∅→∅),[3.1812]→[3.1812:1813](∅→∅),[3.1813]→[3.2324:2454](∅→∅)
VSignup ->HH.div_[ HH.slot _signup unit (Signup.component system signupCap st.config) unit (Just <<< SignupAction) ]VLogin ->HH.div_[ HH.slot _login unit (Login.component system loginCap) unit (Just <<< LoginAction) ]handleAction :: MainAction -> H.HalogenM MainState MainAction Slots output m UnithandleAction = case _ ofInitialize -> doroute <- lift system.getHashnextView <- case route of"login" -> pure VLogin"signup" -> pure VSignupother -> doresult <- lift loginCap.checkLogincase result ofAcc.LoginForbidden -> pure VLoginAcc.LoginError _ -> pure VLogin_ -> pure VTimelinenavigate nextViewSignupAction (Signup.SignupComplete _) -> navigate VTimelineSignupAction (Signup.SigninNav) -> navigate VLoginLoginAction (Login.LoginComplete _) -> navigate VTimelineLogoutAction -> dolift loginCap.logoutnavigate VLoginProjectAction (ProjectChange p) -> H.modify_ (_ { selectedProject = Just p }) - replacement in client/src/Main.purs at line 182[3.2455]→[3.7372:7391](∅→∅),[3.7391]→[2.3653:3683](∅→∅),[2.3683]→[3.7408:7528](∅→∅),[3.7408]→[3.7408:7528](∅→∅)
VOverview ->withNavBar $ HH.div_[ HH.slot _overview unit (Overview.component system ovCap pCap) st.selectedProject (Just <<< ProjectAction) ]handleQuery :: forall a. MainQuery a -> H.HalogenM MainState MainAction Slots output m (Maybe a)handleQuery = case _ ofNavigate view a -> docurrentView <- H.gets _.viewwhen (currentView /= view) $ navigate viewpure (Just a) - replacement in client/src/Main.purs at line 189[3.7529]→[3.2455:2475](∅→∅),[3.2455]→[3.2455:2475](∅→∅),[3.2475]→[3.1814:1844](∅→∅),[3.308824]→[3.1814:1844](∅→∅),[3.1844]→[2.3684:3804](∅→∅)
VTimeline ->withNavBar $ HH.div_[ HH.slot _timeline unit (Timeline.component system tlCap pCap) st.selectedProject (Just <<< ProjectAction) ]navigate :: View -> H.HalogenM MainState MainAction Slots output m Unitnavigate view = dolift $ system.setHash (routeHash view)H.modify_ (_ { view = view }) - edit in client/src/Main.purs at line 194[3.308925]→[3.1233:1348](∅→∅),[3.1348]→[3.4241:4264](∅→∅),[3.2509]→[3.4241:4264](∅→∅),[3.309026]→[3.4241:4264](∅→∅),[3.4264]→[3.2510:2747](∅→∅),[3.2747]→[3.9398:9496](∅→∅),[3.9496]→[3.2794:2830](∅→∅),[3.2794]→[3.2794:2830](∅→∅),[3.2830]→[3.1349:1375](∅→∅),[3.1403]→[3.2081:2082](∅→∅),[3.2962]→[3.2081:2082](∅→∅),[3.4480]→[3.2081:2082](∅→∅),[3.2082]→[3.2963:3011](∅→∅),[3.3011]→[3.1404:1431](∅→∅),[3.1431]→[3.3054:3055](∅→∅),[3.3054]→[3.3054:3055](∅→∅),[3.3055]→[3.9497:9538](∅→∅),[3.9538]→[3.1432:1456](∅→∅),[3.1456]→[3.7637:7711](∅→∅),[3.1456]→[3.9578:9579](∅→∅),[3.7711]→[3.9578:9579](∅→∅),[3.9578]→[3.9578:9579](∅→∅),[3.9579]→[3.3055:3080](∅→∅),[3.3055]→[3.3055:3080](∅→∅),[3.3080]→[3.2101:2130](∅→∅),[3.2101]→[3.2101:2130](∅→∅),[3.2130]→[3.1457:1482](∅→∅),[3.1482]→[3.7712:7814](∅→∅),[3.7814]→[3.1482:1749](∅→∅),[3.1482]→[3.1482:1749](∅→∅),[3.1749]→[3.3121:3122](∅→∅),[3.3121]→[3.3121:3122](∅→∅),[3.3122]→[3.1750:1930](∅→∅),[3.1930]→[3.2154:2155](∅→∅),[3.3122]→[3.2154:2155](∅→∅),[3.2154]→[3.2154:2155](∅→∅)
handleAction :: MainAction -> H.HalogenM MainState MainAction Slots output m UnithandleAction = case _ ofInitialize -> doroute <- lift system.getHashnextView <- case route of"login" -> pure VLogin"signup" -> pure VSignupother -> doresult <- lift loginCap.checkLogincase result ofAcc.LoginForbidden -> pure VLoginAcc.LoginError _ -> pure VLogin_ -> pure VTimelinenavigate nextViewSignupAction (Signup.SignupComplete _) ->navigate VTimelineSignupAction (Signup.SigninNav) ->navigate VLoginLoginAction (Login.LoginComplete _) ->navigate VTimelineLogoutAction -> dolift loginCap.logoutnavigate VLoginProjectAction (ProjectChange p) ->H.modify_ (_ { selectedProject = Just p })handleQuery :: forall a. MainQuery a -> H.HalogenM MainState MainAction Slots output m (Maybe a)handleQuery = case _ ofNavigate view a -> docurrentView <- H.gets _.viewwhen (currentView /= view) $ navigate viewpure (Just a)navigate :: View -> H.HalogenM MainState MainAction Slots output m Unitnavigate view = dolift $ system.setHash (routeHash view)H.modify_ (_ { view = view }) - replacement in client/src/Main.purs at line 196
HH.div_[HH.nav[P.classes (ClassName <$> ["navbar", "navbar-expand-lg", "navbar-light", "bg-white"])][HH.div[P.classes (ClassName <$> ["container-fluid"])][ brand, HH.ul [P.classes (ClassName <$> ["navbar-nav", "ml-auto"])] (map navItem nav), logoutHH.div_[ HH.nav[ P.classes (ClassName <$> [ "navbar", "navbar-expand-lg", "navbar-light", "bg-white" ]) ][ HH.div[ P.classes (ClassName <$> [ "container-fluid" ]) ][ brand, HH.ul [ P.classes (ClassName <$> [ "navbar-nav", "ml-auto" ]) ] (map navItem nav), logout] - replacement in client/src/Main.purs at line 206
],body], body] - replacement in client/src/Main.purs at line 210
nav = [ { label: "Overview", path: "overview" }, { label: "Timeline", path: "timeline" }]nav =[ { label: "Overview", path: "overview" }, { label: "Timeline", path: "timeline" }] - replacement in client/src/Main.purs at line 216
brand = HH.div[P.classes (ClassName <$> ["navbar-brand"])][HH.h4[P.classes (ClassName <$> ["font-weight-bold"])][HH.text "Aftok"]]brand =HH.div[ P.classes (ClassName <$> [ "navbar-brand" ]) ][ HH.h4[ P.classes (ClassName <$> [ "font-weight-bold" ]) ][ HH.text "Aftok" ]] - replacement in client/src/Main.purs at line 225[3.2755]→[3.2755:2869](∅→∅),[3.2869]→[3.3123:3161](∅→∅),[3.3161]→[3.2901:2926](∅→∅),[3.2901]→[3.2901:2926](∅→∅)
logout = HH.button[P.classes (ClassName <$> ["btn", "navbar-btn", "btn-sm", "btn-primary", "lift", "ml-auto"]),E.onClick \_ -> Just LogoutAction][HH.text "Logout"]logout =HH.button[ P.classes (ClassName <$> [ "btn", "navbar-btn", "btn-sm", "btn-primary", "lift", "ml-auto" ]), E.onClick \_ -> Just LogoutAction][ HH.text "Logout" ] - replacement in client/src/Main.purs at line 232
type NavTop ={ label :: String, items :: Array NavItem}type NavTop= { label :: String, items :: Array NavItem} - replacement in client/src/Main.purs at line 237
type NavItem ={ label :: String, path :: String}type NavItem= { label :: String, path :: String} - replacement in client/src/Main.purs at line 243
navItem ni =navItem ni = - replacement in client/src/Main.purs at line 245
[P.classes (ClassName <$> ["nav-item"]) ][ P.classes (ClassName <$> [ "nav-item" ]) ] - replacement in client/src/Main.purs at line 247
[ P.classes (ClassName <$> ["nav-link"]), P.href ("#" <> ni.path)][ HH.text ni.label ][ P.classes (ClassName <$> [ "nav-link" ]), P.href ("#" <> ni.path)][ HH.text ni.label ]