Skip to content

Commit

Permalink
table view for users.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwarzlichtbezirk committed Nov 15, 2024
1 parent 56c7e10 commit 532f80a
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 47 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.23'

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ go.work.sum

# env file
.env

# Visual Studio settings
.vs/

# Visual Studio Code settings
.vscode/
65 changes: 65 additions & 0 deletions core/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,34 @@ type (
XMLName xml.Name `json:"-" yaml:"-" xml:"ret"`
List []clubitem `json:"list" yaml:"list" xml:"list>club" form:"list"`
}
ArgClubInfo struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"arg"`
CID uint64 `json:"cid" yaml:"cid" xml:"cid,attr"`
}
RetClubInfo struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"ret"`
Name string `json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"`
Bank float64 `json:"bank" yaml:"bank" xml:"bank"` // users win/lost balance, in coins
Fund float64 `json:"fund" yaml:"fund" xml:"fund"` // jackpot fund, in coins
Lock float64 `json:"lock" yaml:"lock" xml:"lock"` // not changed deposit within games
Rate float64 `json:"rate" yaml:"rate" xml:"rate"` // jackpot rate for games with progressive jackpot
MRTP float64 `json:"mrtp" yaml:"mrtp" xml:"mrtp"` // master RTP
}
)

func ApiClubList() (ret RetClubList, err error) {
ret, _, err = HttpPost[any, RetClubList]("/club/list", admin.Access, nil)
return
}

func ApiClubInfo(cid uint64) (ret RetClubInfo, err error) {
var arg = ArgClubInfo{
CID: cid,
}
ret, _, err = HttpPost[ArgClubInfo, RetClubInfo]("/club/info", admin.Access, &arg)
return
}

type (
ArgPropGet struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"arg"`
Expand All @@ -97,6 +118,26 @@ type (
XMLName xml.Name `json:"-" yaml:"-" xml:"ret"`
Wallet float64 `json:"wallet" yaml:"wallet" xml:"wallet"`
}
ArgAccessGet struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"arg"`
CID uint64 `json:"cid" yaml:"cid" xml:"cid,attr"`
UID uint64 `json:"uid" yaml:"uid" xml:"uid,attr"`
All bool `json:"all" yaml:"all" xml:"all,attr"`
}
RetAccessGet struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"ret"`
Access AL `json:"access" yaml:"access" xml:"access"`
}
ArgRtpGet struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"arg"`
CID uint64 `json:"cid" yaml:"cid" xml:"cid,attr"`
UID uint64 `json:"uid" yaml:"uid" xml:"uid,attr"`
All bool `json:"all" yaml:"all" xml:"all,attr"`
}
RetRtpGet struct {
XMLName xml.Name `json:"-" yaml:"-" xml:"ret"`
MRTP float64 `json:"mrtp" yaml:"mrtp" xml:"mrtp"`
}
)

func ApiPropGet(cid, uid uint64) (p Props, err error) {
Expand Down Expand Up @@ -125,3 +166,27 @@ func ApiWalletGet(cid, uid uint64) (sum float64, err error) {
sum = ret.Wallet
return
}

func ApiAccessGet(cid, uid uint64, all bool) (al AL, err error) {
var arg = ArgAccessGet{
CID: cid,
UID: uid,
All: all,
}
var ret RetAccessGet
ret, _, err = HttpPost[ArgAccessGet, RetAccessGet]("/prop/al/get", admin.Access, &arg)
al = ret.Access
return
}

func ApiRtpGet(cid, uid uint64, all bool) (mrtp float64, err error) {
var arg = ArgRtpGet{
CID: cid,
UID: uid,
All: all,
}
var ret RetRtpGet
ret, _, err = HttpPost[ArgRtpGet, RetRtpGet]("/prop/rtp/get", admin.Access, &arg)
mrtp = ret.MRTP
return
}
21 changes: 21 additions & 0 deletions core/logic.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"strings"
"time"

cfg "github.com/slotopol/balance/config"
Expand Down Expand Up @@ -52,3 +53,23 @@ func GetProp(cid uint64, user *User) (p Props, err error) {
user.props[curcid] = p
return
}

func FormatAL(al AL) string {
var items = make([]string, 0, 5)
if al&ALmem != 0 {
items = append(items, "member")
}
if al&ALgame != 0 {
items = append(items, "game")
}
if al&ALuser != 0 {
items = append(items, "user")
}
if al&ALclub != 0 {
items = append(items, "club")
}
if al&ALadmin != 0 {
items = append(items, "admin")
}
return strings.Join(items, ", ")
}
138 changes: 110 additions & 28 deletions core/startup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package core
import (
"fmt"
"log"
"strconv"
"time"

"fyne.io/fyne/v2"
Expand All @@ -12,13 +13,37 @@ import (
cfg "github.com/slotopol/balance/config"
)

var Foreground bool

var (
admwnd = widget.NewLabel("not logined yet")
clubtabs = &container.AppTabs{}
userlist *widget.List
userlist *widget.Table
curcid uint64
cural AL
)

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

func RefreshContent() {
var err error

userlist.Refresh()

var label = clubtabs.Selected().Content.(*widget.Label)
var bank, fund, deposit = "N/A", "N/A", "N/A"
if cural&ALclub != 0 {
var info RetClubInfo
if info, err = ApiClubInfo(curcid); err != nil {
return
}
bank, fund, deposit = fmt.Sprintf("%.2f", info.Bank), fmt.Sprintf("%.2f", info.Fund), fmt.Sprintf("%.2f", info.Lock)
}
label.SetText(fmt.Sprintf("bank: %s, jackpot fund: %s, deposit: %s", bank, fund, deposit))
}

func MakeSignIn() (err error) {
if err = cfg.ReadCredentials(); err != nil {
log.Printf("failure on reading credentials, using default: %s\n", err.Error())
Expand All @@ -43,19 +68,25 @@ func MakeClubList() (err error) {
var tabs = make([]*container.TabItem, len(cl.List))
for i, item := range cl.List {
Clubs[item.Name] = item.CID
tabs[i] = container.NewTabItem(item.Name, widget.NewLabel("Content of tab "+item.Name))
tabs[i] = container.NewTabItem(item.Name, widget.NewLabel(""))
}
clubtabs.SetItems(tabs)
curcid = Clubs[clubtabs.Selected().Text]

clubtabs.OnSelected = func(tab *container.TabItem) {
var uid, ok = Clubs[tab.Text]
if !ok {
var err error

var ok bool
if curcid, ok = Clubs[tab.Text]; !ok {
return
}
if cural, err = ApiAccessGet(curcid, admin.UID, true); err != nil {
return
}
curcid = uid
userlist.Refresh()

RefreshContent()
}
clubtabs.OnSelected(clubtabs.Selected())

log.Printf("clubs list ready, %d clubs", len(Clubs))
return
}
Expand All @@ -72,7 +103,7 @@ func MakeUserList() (err error) {
}
if user.UID == 0 {
cfg.UserList = append(cfg.UserList[:i], cfg.UserList[i+1:]...)
log.Printf("user with email '%s' presents in yaml list but absent in server database, skipped")
log.Printf("user with email '%s' presents in yaml list but absent in server database, skipped", email)
continue
}
user.props = map[uint64]Props{} // make new empty map
Expand All @@ -81,7 +112,9 @@ func MakeUserList() (err error) {
go func() {
var c = time.Tick(Cfg.PropUpdateTick)
for range c {
userlist.Refresh()
if Foreground {
RefreshContent()
}
}
}()
log.Printf("users list ready, %d users", len(Users))
Expand Down Expand Up @@ -116,39 +149,88 @@ func StartupChain() {
}
}

func Lifecycle(a fyne.App) {
var l = a.Lifecycle()
l.SetOnStarted(func() {
log.Println("lifecycle: started")
})
l.SetOnStopped(func() {
log.Println("lifecycle: stopped")
})
l.SetOnEnteredForeground(func() {
Foreground = true
log.Println("lifecycle: entered foreground")
})
l.SetOnExitedForeground(func() {
Foreground = false
log.Println("lifecycle: exited foreground")
})
}

func CreateMainWindow(a fyne.App) fyne.Window {
var w = a.NewWindow("Balance")

userlist = widget.NewList(
func() int {
return len(cfg.UserList)
},
userlist = widget.NewTableWithHeaders(
func() (int, int) { return len(cfg.UserList), 4 },
func() fyne.CanvasObject {
return container.NewHBox(widget.NewLabel("email"), widget.NewLabelWithStyle("wallet", fyne.TextAlignLeading, fyne.TextStyle{
Bold: true,
Monospace: true,
}))
var label = widget.NewLabel("")
label.Truncation = fyne.TextTruncateClip
return label
},
func(id widget.ListItemID, item fyne.CanvasObject) {
func(id widget.TableCellID, cell fyne.CanvasObject) {
var err error

var mailwid = item.(*fyne.Container).Objects[0].(*widget.Label)
mailwid.SetText(cfg.UserList[id])

var wallwid = item.(*fyne.Container).Objects[1].(*widget.Label)
var user, ok = Users[cfg.UserList[id]]
var label = cell.(*widget.Label)
var user, ok = Users[cfg.UserList[id.Row]]
if !ok {
wallwid.SetText("error")
label.SetText("error")
return
}
if id.Col == 0 { // email
label.SetText(cfg.UserList[id.Row])
return
}
if cural&ALuser == 0 {
label.SetText("N/A")
return
}
var prop Props
if prop, err = GetProp(curcid, &user); err != nil {
wallwid.SetText("error")
label.SetText("error")
return
}
wallwid.SetText(fmt.Sprintf("%.2f", prop.Wallet))
},
)
switch id.Col {
case 1: // wallet
label.SetText(fmt.Sprintf("%.2f", prop.Wallet))
case 2: // mtrp
if prop.MRTP > 0 {
label.SetText(fmt.Sprintf("%g%%", prop.MRTP))
} else {
label.SetText("-")
}
case 3: // access
label.SetText(FormatAL(prop.Access))
}
})
userlist.SetColumnWidth(0, 180) // email
userlist.SetColumnWidth(1, 100) // wallet
userlist.SetColumnWidth(2, 50) // mtrp
userlist.SetColumnWidth(3, 150) // access
userlist.UpdateHeader = func(id widget.TableCellID, cell fyne.CanvasObject) {
var label = cell.(*widget.Label)
if id.Row < 0 {
label.SetText(colhdr[id.Col])
} else if id.Col < 0 {
var user, ok = Users[cfg.UserList[id.Row]]
if !ok {
label.SetText("error")
return
}
label.SetText(strconv.Itoa(int(user.UID)))
} else {
label.SetText("")
}
}

var frame = container.NewBorder(
container.NewVBox(admwnd, clubtabs),
Expand Down
Loading

0 comments on commit 532f80a

Please sign in to comment.