Skip to content

Commit

Permalink
Add ability to send chat messages to chat window.
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmacdonald committed Mar 7, 2023
1 parent e838f99 commit d48e933
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 96 deletions.
20 changes: 15 additions & 5 deletions internal/detector/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ func (bd *BD) triggerMatch(ctx context.Context, ps *model.Player, match *rules.M
}
if bd.settings.GetPartyWarningsEnabled() && time.Since(ps.AnnouncedLast) >= model.DurationAnnounceMatchTimeout {
// Don't spam friends, but eventually remind them if they manage to forget long enough
if errLog := bd.partyLog(ctx, "Bot: (%d) [%s] %s ", ps.UserId, match.Origin, ps.Name); errLog != nil {
if errLog := bd.SendChat(ctx, model.ChatDestParty, "(%d) [%s] [%s] %s ", ps.UserId, match.Origin, strings.Join(match.Attributes, ","), ps.Name); errLog != nil {
log.Printf("Failed to send party log message: %s\n", errLog)
return
}
Expand Down Expand Up @@ -918,14 +918,24 @@ func (bd *BD) connectRcon(ctx context.Context) error {
bd.rconConnection = conn
return nil
}

func (bd *BD) partyLog(ctx context.Context, fmtStr string, args ...any) error {
func (bd *BD) SendChat(ctx context.Context, destination model.ChatDest, format string, args ...any) error {
if errConn := bd.connectRcon(ctx); errConn != nil {
return errConn
}
_, errExec := bd.rconConnection.Exec(fmt.Sprintf("say_party %s", fmt.Sprintf(fmtStr, args...)))
cmd := ""
switch destination {
case model.ChatDestAll:
cmd = fmt.Sprintf("say %s", fmt.Sprintf(format, args...))
case model.ChatDestTeam:
cmd = fmt.Sprintf("say_team %s", fmt.Sprintf(format, args...))
case model.ChatDestParty:
cmd = fmt.Sprintf("say_party %s", fmt.Sprintf(format, args...))
default:
return errors.Errorf("Invalid destination: %s", destination)
}
_, errExec := bd.rconConnection.Exec(cmd)
if errExec != nil {
return errors.Wrap(errExec, "Failed to send rcon say_party")
return errors.Wrap(errExec, "Failed to send rcon chat message")
}
return nil
}
Expand Down
10 changes: 10 additions & 0 deletions internal/model/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ const (

type KickFunc func(ctx context.Context, userId int64, reason KickReason) error

type ChatDest string

const (
ChatDestAll ChatDest = "all"
ChatDestTeam ChatDest = "team"
ChatDestParty ChatDest = "party"
)

type ChatFunc func(ctx context.Context, destination ChatDest, format string, args ...any) error

type LaunchFunc func()

type QueryNamesFunc func(ctx context.Context, sid64 steamid.SID64) (UserNameHistoryCollection, error)
Expand Down
11 changes: 10 additions & 1 deletion internal/model/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ type LinkConfig struct {
Deleted bool `yaml:"-"`
}
type LinkConfigCollection []*LinkConfig

func (list LinkConfigCollection) AsAny() []any {
bl := make([]any, len(list))
for i, r := range list {
bl[i] = r
}
return bl
}

type ListConfigCollection []*ListConfig

func (list ListConfigCollection) AsAny() []any {
Expand Down Expand Up @@ -273,7 +282,7 @@ func (s *Settings) AddList(config *ListConfig) error {
return nil
}

func (s *Settings) GetLinks() []*LinkConfig {
func (s *Settings) GetLinks() LinkConfigCollection {
s.RLock()
defer s.RUnlock()
return s.Links
Expand Down
2 changes: 1 addition & 1 deletion internal/translations/active.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ label_add:
one: "Add"

label_confirm_delete_list:
one: "Are you are you want to delete the list?: {{ .Name }}"
one: "Are you are you want to delete the list?"

label_settings_vote_kicker:
one: "Vote Kicker"
Expand Down
2 changes: 1 addition & 1 deletion internal/translations/ru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ label_add:
one: "Добавить"

label_confirm_delete_list:
one: "Вы уверены что хотите удалить этот список?: {{ .Name }}"
one: "Вы уверены что хотите удалить этот список?"

label_settings_vote_kicker:
one: "Vote Kicker"
Expand Down
38 changes: 37 additions & 1 deletion internal/ui/chat_game.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,42 @@ func newGameChatWindow(ctx context.Context, app fyne.App, cb callBacks, attrs bi
gcw.objectMu.Unlock()
}
gcw.list = widget.NewListWithData(gcw.boundList, createFunc, updateFunc)
selected := "all"
chatTypeEntry := widget.NewSelect([]string{
string(model.ChatDestAll),
string(model.ChatDestTeam),
string(model.ChatDestParty),
}, func(s string) {
selected = s
})
chatTypeEntry.PlaceHolder = "Message..."
chatTypeEntry.SetSelectedIndex(0)
chatTypeEntry.Refresh()
sz := chatTypeEntry.Size()
sz.Width = 150
chatTypeEntry.Resize(sz)
chatEntryData := binding.NewString()
messageEntry := widget.NewEntryWithData(chatEntryData)
messageEntry.OnSubmitted = func(s string) {
showUserError(gcw.cb.chatFunc(ctx, model.ChatDest(selected), s), gcw.window)
_ = chatEntryData.Set("")
}
bottomContainer := container.NewBorder(
nil,
nil,
nil,
container.NewHBox(
chatTypeEntry,
widget.NewButtonWithIcon("Send", theme.MailSendIcon(), func() {
msg, err := chatEntryData.Get()
if err != nil {
return
}
showUserError(gcw.cb.chatFunc(ctx, model.ChatDest(selected), msg), gcw.window)
_ = chatEntryData.Set("")
})),
messageEntry)

gcw.window.SetContent(container.NewBorder(
container.NewBorder(
nil,
Expand All @@ -118,7 +154,7 @@ func newGameChatWindow(ctx context.Context, app fyne.App, cb callBacks, attrs bi
widget.NewLabelWithData(binding.IntToStringWithFormat(gcw.messageCount, fmt.Sprintf("%s%%d", translations.One(translations.LabelMessageCount)))),
widget.NewLabel(""),
),
nil,
bottomContainer,
nil,
nil,
container.NewVScroll(gcw.list)))
Expand Down
100 changes: 68 additions & 32 deletions internal/ui/links.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ui

import (
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/data/binding"
Expand All @@ -9,6 +10,8 @@ import (
"fyne.io/fyne/v2/widget"
"github.com/leighmacdonald/bd/internal/model"
"github.com/leighmacdonald/bd/internal/translations"
"github.com/nicksnyder/go-i18n/v2/i18n"
"log"
"sync"
)

Expand All @@ -33,15 +36,15 @@ func newLinksDialog(parent fyne.Window, settings *model.Settings) *linksConfigDi
boundList: binding.NewUntypedList(),
selectOpts: []string{"steam64", "steam32", "steam3", "steam"},
}
var selectedId widget.ListItemID
_ = lcd.boundList.Set(links)
lcd.list = widget.NewListWithData(lcd.boundList, func() fyne.CanvasObject {
return container.NewBorder(
nil,
nil,
widget.NewCheck("", func(b bool) {}),
container.NewHBox(
widget.NewButtonWithIcon("Edit", theme.FolderNewIcon(), func() {}),
widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func() {})),
nil,
widget.NewButtonWithIcon("", theme.SettingsIcon(), func() {})),
widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{Bold: false}),
)
}, func(i binding.DataItem, object fyne.CanvasObject) {
Expand All @@ -53,18 +56,21 @@ func newLinksDialog(parent fyne.Window, settings *model.Settings) *linksConfigDi

rootContainer := object.(*fyne.Container)
labelName := rootContainer.Objects[0].(*widget.Label)
btnContainer := rootContainer.Objects[1].(*fyne.Container)
btnContainer := rootContainer.Objects[2].(*fyne.Container)
editButton := btnContainer.Objects[0].(*widget.Button)
// deleteButton := btnContainer.Objects[1].(*widget.Button)

enabledCheck := rootContainer.Objects[1].(*widget.Check)

enabledBinding := binding.BindBool(&linkConfig.Enabled)
enabledCheck.Bind(enabledBinding)

urlEntry := widget.NewEntryWithData(binding.BindString(&linkConfig.URL))

nameBinding := binding.BindString(&linkConfig.Name)
labelName.Bind(nameBinding)
nameEntry := widget.NewEntryWithData(nameBinding)
editButton.OnTapped = func() {

enabledEntry := widget.NewCheckWithData(translations.One(translations.LabelEnabled), binding.BindBool(&linkConfig.Enabled))
enabledEntry := widget.NewCheckWithData(translations.One(translations.LabelEnabled), enabledBinding)
formatEntry := widget.NewSelectEntry(lcd.selectOpts)
formatEntry.Bind(binding.BindString(&linkConfig.IdFormat))

Expand All @@ -83,32 +89,62 @@ func newLinksDialog(parent fyne.Window, settings *model.Settings) *linksConfigDi
}
editButton.Refresh()
})
count := 1
delButton := widget.NewButtonWithIcon(translations.One(translations.LabelDelete), theme.ContentRemoveIcon(), func() {})

lcd.list.OnSelected = func(id widget.ListItemID) {
selectedId = id
delButton.Enable()
}
lcd.list.OnUnselected = func(id widget.ListItemID) {
delButton.Disable()
selectedId = -1
}

addButton := widget.NewButtonWithIcon(translations.One(translations.LabelAdd), theme.ContentAddIcon(), func() {
lcd.boundListMu.Lock()
newLinks := settings.GetLinks()
newLinks = append(newLinks, &model.LinkConfig{
IdFormat: string(model.Steam64),
Enabled: true,
Name: fmt.Sprintf("New Link %d", count)})
settings.SetLinks(newLinks)
showUserError(lcd.boundList.Set(settings.GetLinks().AsAny()),
parent)
lcd.boundListMu.Unlock()
lcd.list.Refresh()
count++
})

lcd.Dialog = dialog.NewCustom("Edit Links", "Dismiss",
container.NewBorder(widget.NewToolbar(widget.NewToolbarAction(theme.ContentAddIcon(), func() {
showUserError(lcd.boundList.Append(&model.LinkConfig{IdFormat: string(model.Steam64), Enabled: true}), parent)
delButton.OnTapped = func() {
msg := translations.Tr(&i18n.Message{ID: string(translations.LabelConfirmDeleteList)},
1, map[string]interface{}{"Name": ""})
confirm := dialog.NewConfirm(translations.One(translations.TitleDeleteConfirm), msg, func(b bool) {
if !b {
return
}
var updatedLinks model.LinkConfigCollection
for idx, link := range settings.GetLinks() {
if idx == selectedId {
continue
}
updatedLinks = append(updatedLinks, link)
}
settings.SetLinks(updatedLinks)
lcd.boundListMu.Lock()
if errReload := lcd.boundList.Set(settings.GetLinks().AsAny()); errReload != nil {
log.Printf("Failed to reload: %v\n", errReload)
}
lcd.boundListMu.Unlock()
lcd.list.Refresh()
})), nil, nil, nil, lcd.list), parent)

// func(b bool) {
// if !b {
// return
// }
// utLinks, errGet := lcd.boundList.Get()
// if errGet != nil {
// showUserError(errGet, parent)
// return
// }
// var linkConfigs []*model.LinkConfig
// for _, ut := range utLinks {
// link := ut.(*model.LinkConfig)
// if !link.Deleted {
// linkConfigs = append(linkConfigs, link)
// }
// }
// lcd.newLinkConfigSuccess = true
// lcd.newLinkConfig = linkConfigs
// }
lcd.Resize(fyne.NewSize(800, 800))

}, parent)
confirm.Show()
}
delButton.Refresh()
lcd.Dialog = dialog.NewCustom("Edit Links", translations.One(translations.LabelClose),
container.NewBorder(container.NewHBox(addButton, delButton), nil, nil, nil, lcd.list), parent)

lcd.Resize(fyne.NewSize(defaultDialogueWidth, 500))
return &lcd
}
Loading

0 comments on commit d48e933

Please sign in to comment.