Skip to content

Commit

Permalink
add & remove user.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwarzlichtbezirk committed Nov 23, 2024
1 parent 93c963d commit 9b50a97
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 17 deletions.
4 changes: 2 additions & 2 deletions api/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ type (
}
)

func ReqSignIs(email string) (user User, err error) {
func ReqSignIs(email string) (user User, status int, err error) {
var arg = ArgSignIs{
Email: email,
}
var ret RetSignIs
ret, _, err = HttpPost[ArgSignIs, RetSignIs]("/signin", Admin.Access, &arg)
ret, status, err = HttpPost[ArgSignIs, RetSignIs]("/signis", Admin.Access, &arg)
user.UID = ret.UID
user.Email = ret.Email
user.Name = ret.Name
Expand Down
17 changes: 16 additions & 1 deletion config/cfgpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ func init() {
log.Printf("can not obtain user config directory, any settings can not be saved: %s", err.Error())
return
}
CfgPath = filepath.Join(oscfgpath, "fyne", AppID)
var appdata = filepath.Join(oscfgpath, "fyne", AppID)
if err = os.MkdirAll(appdata, 0750); err != nil {
log.Printf("cannot create application config directory: %s\n", err.Error())
return
}
CfgPath = appdata
log.Printf("config path: %s\n", CfgPath)

if err = ReadCredentials(); err != nil {
Expand Down Expand Up @@ -71,6 +76,11 @@ func ReadCredentials() (err error) {
}

func SaveCredentials() (err error) {
defer func() {
if err != nil {
log.Printf("can not save credentials: %s", err.Error())
}
}()
if CfgPath == "" {
return ErrNoCfgPath
}
Expand Down Expand Up @@ -99,6 +109,11 @@ func ReadUserList() (err error) {
}

func SaveUserList() (err error) {
defer func() {
if err != nil {
log.Printf("can not save user list: %s", err.Error())
}
}()
if CfgPath == "" {
return ErrNoCfgPath
}
Expand Down
103 changes: 99 additions & 4 deletions ui/frame.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package ui

import (
"errors"
"fmt"
"log"
"net/http"
"strconv"
"strings"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/data/validation"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"github.com/slotopol/balance/api"
Expand All @@ -29,6 +32,11 @@ var (
Cfg = cfg.Cfg // shortcut
)

var (
ErrBadEmail = errors.New("not a valid email")
ErrNoUser = errors.New("given email does not registered")
)

func GetProp(cid uint64, user *api.User) (p api.Props, err error) {
if p, _ = user.GetProps(curcid); !p.Expired() {
return // return cached
Expand Down Expand Up @@ -60,6 +68,23 @@ func FormatAL(al api.AL) string {
return strings.Join(items, ", ")
}

func EmailValidator() fyne.StringValidator {
return func(str string) error {
var err error
var status int
if _, status, err = api.ReqSignIs(str); err != nil {
switch status {
case http.StatusBadRequest:
return ErrBadEmail
case http.StatusNotFound:
return ErrNoUser
}
return err
}
return nil
}
}

type Frame struct {
fyne.Window
SigninPage
Expand Down Expand Up @@ -91,7 +116,7 @@ const (
emailRx = `^\w[\w_\-\.]*@\w+\.\w{1,4}$`
)

func (p *SigninPage) Create() {
func (p *SigninPage) Create(w fyne.Window) {
// Backgroud image
p.underlay = &canvas.Image{
Resource: AnyUnderlay(),
Expand Down Expand Up @@ -139,6 +164,8 @@ func (p *SigninPage) Create() {
}

type MainPage struct {
selected int // current selected row index

// Backgroud image
underlay *canvas.Image

Expand All @@ -163,7 +190,7 @@ type MainPage struct {

var colhdr = []string{"email", "wallet", "MRTP", "access"}

func (p *MainPage) Create() {
func (p *MainPage) Create(w fyne.Window) {
// Backgroud image
p.underlay = &canvas.Image{
Resource: AnyUnderlay(),
Expand All @@ -172,8 +199,8 @@ func (p *MainPage) Create() {
}

// Toolbar buttons
p.useraddBut = widget.NewToolbarAction(useraddIconRes, func() { fmt.Println("useradd") })
p.userdelBut = widget.NewToolbarAction(userdelIconRes, func() { fmt.Println("userdel") })
p.useraddBut = widget.NewToolbarAction(useraddIconRes, func() { p.OnUserAdd(w) })
p.userdelBut = widget.NewToolbarAction(userdelIconRes, func() { p.OnUserRemove(w) })
p.walletBut = widget.NewToolbarAction(walletIconRes, func() { fmt.Println("wallet") })
p.mrtpBut = widget.NewToolbarAction(percentIconRes, func() { fmt.Println("mrtp") })
p.accessBut = widget.NewToolbarAction(accessIconRes, func() { fmt.Println("access") })
Expand Down Expand Up @@ -256,10 +283,15 @@ func (p *MainPage) Create() {
label.SetText("")
}
},
OnSelected: p.OnCellSelected,
OnUnselected: func(id widget.TableCellID) { p.OnCellUnselect() },
ShowHeaderRow: true,
ShowHeaderColumn: true,
}

p.selected = -1
p.userdelBut.Disable()

// Main page
p.mainPage = container.NewStack(
NewImageFit(p.underlay),
Expand All @@ -270,6 +302,69 @@ func (p *MainPage) Create() {
)
}

func (p *MainPage) OnCellSelected(id widget.TableCellID) {
log.Println(id)
if id.Row < 0 || id.Col < 0 {
p.OnCellUnselect()
return
}
if _, ok := api.Users[cfg.UserList[id.Row]]; !ok {
return
}
p.selected = id.Row
p.userdelBut.Enable()
}

func (p *MainPage) OnCellUnselect() {
p.selected = -1
p.userdelBut.Disable()
}

func (p *MainPage) OnUserAdd(w fyne.Window) {
var emailEdt = widget.NewEntry()
emailEdt.Validator = EmailValidator()
emailEdt.PlaceHolder = "[email protected]"
var items = []*widget.FormItem{
{Text: "Email", Widget: emailEdt, HintText: "Email of registered user"},
}
var dlg = dialog.NewForm("Registered email", "Add", "Cancel", items, func(b bool) {
var err error
var user api.User
if !b {
return
}
if user, _, err = api.ReqSignIs(emailEdt.Text); err != nil {
log.Printf("can not detect user '%s'", emailEdt.Text)
return
}
cfg.UserList = append(cfg.UserList, emailEdt.Text)
api.Users[emailEdt.Text] = &user
p.userTable.Refresh()
cfg.SaveUserList()
}, w)
dlg.Resize(fyne.Size{Width: 400})
dlg.Show()
}

func (p *MainPage) OnUserRemove(w fyne.Window) {
var email = cfg.UserList[p.selected]
var dlg = dialog.NewConfirm(
"Confirm to remove",
fmt.Sprintf("Confirm to remove user with email '%s' from the list. It will be removed from the list only and remains in the database.", email),
func(confirm bool) {
if !confirm {
return
}
cfg.UserList = append(cfg.UserList[:p.selected], cfg.UserList[p.selected+1:]...)
delete(api.Users, email)
p.userTable.Refresh()
cfg.SaveUserList()
}, w)
dlg.SetDismissText("Cancel")
dlg.SetConfirmText("Remove")
dlg.Show()
}

// Refreshes visible content of users list. Fetches data from server
// if cached data has timeout is over.
func (p *MainPage) RefreshContent() {
Expand Down
12 changes: 5 additions & 7 deletions ui/startup.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ func (f *Frame) submitSignin() {
cfg.Credentials.Addr = f.host.Text
cfg.Credentials.Email = f.email.Text
cfg.Credentials.Secret = f.secret.Text
if err = cfg.SaveCredentials(); err != nil {
log.Printf("can not save credentials: %s", err.Error())
}
cfg.SaveCredentials()
}
}

Expand All @@ -155,15 +153,15 @@ func (f *Frame) submitSignin() {
}

func (f *Frame) CreateWindow(a fyne.App) {
f.MainPage.Create()
f.SigninPage.Create()

go WaitToken()

var w = a.NewWindow("Balance")
f.Window = w
f.MainPage.Create(w)
f.SigninPage.Create(w)

w.Resize(fyne.NewSize(540, 640))
w.SetContent(f.signinPage)
f.Window = w

f.SigninPage.form.OnSubmit = f.submitSignin
f.SigninPage.form.Refresh()
Expand Down
6 changes: 3 additions & 3 deletions ui/widgets.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ func (tl *ToolbarLabel) ToolbarObject() fyne.CanvasObject {
return tl
}

type CenterVBoxLayout struct {
}

// Layout that fits the images to whole space and cuts edges if it needs.
type ImageFitLayout struct {
}

// Declare conformity with Layout interface
var _ fyne.Layout = (*ImageFitLayout)(nil)

func NewImageFit(objects ...fyne.CanvasObject) *fyne.Container {
return container.New(ImageFitLayout{}, objects...)
}
Expand Down

0 comments on commit 9b50a97

Please sign in to comment.