M cmd/tallyard/main.go => cmd/tallyard/main.go +9 -2
@@ 129,8 129,15 @@ func main() {
// vote if we need to (user may have voted in previous tallyard
// invocation)
if el.LocalVoter != nil && el.LocalVoter.Poly == nil {
- ballot := ui.VoteTUI(el.Candidates)
- el.LocalVoter.Poly = math.NewRandomPoly(uint(len(*el.FinalJoinIDs)-1), 1024, ballot)
+ ballot, err := ui.VoteTUI(el.Candidates)
+ if err != nil {
+ panic(err)
+ }
+ if ballot == nil {
+ // user likely hit C-c
+ return
+ }
+ el.LocalVoter.Poly = math.NewRandomPoly(uint(len(*el.FinalJoinIDs)-1), 1024, *ballot)
el.Save()
}
M ui/tui.go => ui/tui.go +17 -7
@@ 332,8 332,7 @@ func ElectionWaitTUI(client *mautrix.Client, el *election.Election, eventStore *
}
// displays a voting UI to the user and returns the encoded ballot
-func VoteTUI(candidates []election.Candidate) []byte {
- ranks := make([]int, len(candidates))
+func VoteTUI(candidates []election.Candidate) (ballot *[]byte, err error) {
app := newTallyardApplication()
form := tview.NewForm()
form.SetTitle("Vote").SetBorder(true)
@@ 348,31 347,42 @@ func VoteTUI(candidates []election.Candidate) []byte {
form.AddButton("Submit", func() {
app.Stop()
+ ranks := make([]int, len(candidates))
for i := 0; i < len(candidates); i++ {
text := form.GetFormItem(i).(*tview.InputField).GetText()
if text == "" {
ranks[i] = len(candidates)
continue
}
- rank, err := strconv.Atoi(text)
+ var rank int
+ rank, err = strconv.Atoi(text)
if err != nil {
- panic(err)
+ err = fmt.Errorf("couldn't parse ballot option %d: %s", i+1, err)
+ return
}
if rank > len(candidates) {
rank = len(candidates)
}
ranks[i] = rank
}
+ b := getBallotFromRankings(ranks)
+ ballot = &b
})
app.SetRoot(form, true)
- if err := app.Run(); err != nil {
- panic(err)
+ err2 := app.Run()
+ if err != nil {
+ return nil, err
+ }
+ if err2 != nil {
+ return nil, err2
}
- return getBallotFromRankings(ranks)
+ return ballot, nil
}
+// same as tview.Application but includes an "alive" bool that's use by update
+// goroutines
type tallyardApplication struct {
*tview.Application
alive bool