package main
import (
"fmt"
"gioui.org/app"
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
)
func (a *Application) LoginView(w *app.Window) error {
var (
ops op.Ops
username widget.Editor
password widget.Editor
loginBtn widget.Clickable
syncBtn widget.Clickable
newUserBtn widget.Clickable
optionsBtn widget.Clickable
errorTxt string
)
th := material.NewTheme()
var login = func() {
u, err := a.UserModel.Authenticate(username.Text(), password.Text())
if err != nil {
errorTxt = err.Error()
} else {
a.ActiveUser = &u
w.Perform(system.ActionClose)
}
}
var sync = func() {
err := a.loginSync(username.Text(), password.Text())
if err != nil {
errorTxt = err.Error()
} else {
w.Perform(system.ActionClose)
}
}
var addUser = func() {
go func() {
aw := new(app.Window)
aw.Option(app.Title("New User"))
aw.Option(app.Size(unit.Dp(1280), unit.Dp(720)))
created, err := a.NewUserView(aw)
if err != nil {
fmt.Println(err.Error())
}
if created {
errorTxt = "Successfully added new user! Please log in."
w.Invalidate()
}
}()
}
var options = func() {
go func() {
ow := new(app.Window)
ow.Option(app.Title("Settings"))
ow.Option(app.Size(unit.Dp(1280), unit.Dp(720)))
err := a.OptionView(ow)
if err != nil {
fmt.Println(err.Error())
}
}()
}
for {
switch e := w.Event().(type) {
case app.FrameEvent:
gtx := app.NewContext(&ops, e)
if loginBtn.Clicked(gtx) {
login()
}
if syncBtn.Clicked(gtx) {
sync()
}
if newUserBtn.Clicked(gtx) {
addUser()
}
if optionsBtn.Clicked(gtx) {
options()
}
we, ok := username.Update(gtx)
if ok {
switch we.(type) {
case widget.SubmitEvent:
login()
}
}
we, ok = password.Update(gtx)
if ok {
switch we.(type) {
case widget.SubmitEvent:
login()
}
}
layout.Flex{
Axis: layout.Vertical,
Spacing: layout.SpaceEnd,
}.Layout(gtx,
// Error Text
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(th, unit.Sp(16), errorTxt)
return lbl.Layout(gtx)
},
),
// Username
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
txt := material.Editor(th, &username, "Username")
username.SingleLine = true
username.Submit = true
margins := layout.UniformInset(unit.Dp(10))
padding := layout.UniformInset(inputPadding)
border := widget.Border{
Color: borderColor,
CornerRadius: unit.Dp(1),
Width: unit.Dp(2),
}
return margins.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return border.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return padding.Layout(gtx, txt.Layout)
},
)
},
)
},
),
// Password
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
txt := material.Editor(th, &password, "Password")
password.SingleLine = true
password.Mask = '*'
password.Submit = true
margins := layout.UniformInset(unit.Dp(10))
padding := layout.UniformInset(inputPadding)
border := widget.Border{
Color: borderColor,
CornerRadius: unit.Dp(1),
Width: unit.Dp(2),
}
return margins.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return border.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return padding.Layout(gtx, txt.Layout)
},
)
},
)
},
),
// Buttons
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
lbtn := material.Button(th, &loginBtn, "Log In")
sbtn := material.Button(th, &syncBtn, "Sync")
nubtn := material.Button(th, &newUserBtn, "New User")
obtn := material.Button(th, &optionsBtn, "⚙️")
margins := layout.UniformInset(unit.Dp(5))
return layout.Flex{
Axis: layout.Horizontal,
Spacing: layout.SpaceSides,
}.Layout(gtx,
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
return margins.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return lbtn.Layout(gtx)
},
)
},
),
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
return margins.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return sbtn.Layout(gtx)
},
)
},
),
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
return margins.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
return nubtn.Layout(gtx)
},
)
},
),
layout.Rigid(
func (gtx layout.Context) layout.Dimensions {
return margins.Layout(gtx,
func (gtx layout.Context) layout.Dimensions {
return obtn.Layout(gtx)
},
)
},
),
)
},
),
)
e.Frame(gtx.Ops)
case app.DestroyEvent:
return e.Err
}
}
}