~edwargix/tallyard

e2b87a41f878d37d5e9063204ccd27fcabc5abc4 — David Florness 4 years ago d15efee
Properly sort elections by room in TUI
2 files changed, 32 insertions(+), 21 deletions(-)

M election/map.go
M ui/tui.go
M election/map.go => election/map.go +18 -16
@@ 7,6 7,7 @@ import (
	"os"
	"sort"
	"sync"
	"time"

	log "github.com/sirupsen/logrus"



@@ 16,8 17,12 @@ import (

type ElectionsMap struct {
	sync.RWMutex
	M     map[id.EventID]*Election
	L     []*Election // sorted list of elections by CreationTimestamp (newest to oldest)
	M map[id.EventID]*Election

	// by room, sorted list of elections by CreationTimestamp (newest to oldest)
	L     map[id.RoomID][]*Election
	Ltime time.Time // last time list was update

	Joins map[id.EventID]*Voter
	Save  func()
}


@@ 43,7 48,8 @@ func GetElections() (elections *ElectionsMap, err error) {
func NewElectionsMap() *ElectionsMap {
	em := &ElectionsMap{
		M:     make(map[id.EventID]*Election),
		L:     make([]*Election, 0),
		L:     make(map[id.RoomID][]*Election, 0),
		Ltime: time.Now(),
		Joins: make(map[id.EventID]*Voter),
	}
	em.Save = func() {


@@ 73,7 79,7 @@ func (em *ElectionsMap) UnmarshalJSON(b []byte) error {
	if err := json.Unmarshal(b, &em.M); err != nil {
		return err
	}
	em.L = make([]*Election, 0)
	em.L = make(map[id.RoomID][]*Election, 0)
	for createEventId, el := range em.M {
		em.insort(createEventId, el)
	}


@@ 100,12 106,6 @@ func (em *ElectionsMap) GetOk(createEventID id.EventID) (*Election, bool) {
	return el, ok
}

func (em *ElectionsMap) GetI(i int) *Election {
	em.RLock()
	defer em.RUnlock()
	return em.L[i]
}

func (em *ElectionsMap) SetIfNotExists(createEventID id.EventID, el *Election) {
	em.Lock()
	defer em.Save()


@@ 126,12 126,14 @@ func (em *ElectionsMap) set(createEventID id.EventID, el *Election) {
}

func (em *ElectionsMap) insort(createEventID id.EventID, el *Election) {
	i := sort.Search(len(em.L), func(i int) bool {
		return em.L[i].CreationTimestamp < el.CreationTimestamp
	list := em.L[el.RoomID]
	i := sort.Search(len(list), func(i int) bool {
		return list[i].CreationTimestamp < el.CreationTimestamp
	})
	newList := make([]*Election, len(em.L)+1)
	copy(newList[:i], em.L[:i])
	newList := make([]*Election, len(list)+1)
	copy(newList[:i], list[:i])
	newList[i] = el
	copy(newList[i+1:], em.L[i:])
	em.L = newList
	copy(newList[i+1:], list[i:])
	em.L[el.RoomID] = newList
	em.Ltime = time.Now()
}

M ui/tui.go => ui/tui.go +14 -5
@@ 70,15 70,17 @@ func RoomTUI(client *mautrix.Client, roomID id.RoomID, elections *election.Elect
	app := tview.NewApplication()
	list := tview.NewList().
		AddItem("Create Election", "start a new election in this room", '+', nil)
	n := 0
	var L     []*election.Election
	var Ltime time.Time = elections.Ltime.Add(-1 * time.Millisecond)
	update := func() {
		elections.RLock()
		defer elections.RUnlock()
		if n == len(elections.L) {
		if !Ltime.Before(elections.Ltime) {
			return
		}
		n = len(elections.L)
		for i, el := range elections.L {
		L = elections.L[roomID]
		Ltime = elections.Ltime
		for i, el := range L {
			title := el.Title
			if title == "" {
				title = "<no name>"


@@ 104,11 106,18 @@ func RoomTUI(client *mautrix.Client, roomID id.RoomID, elections *election.Elect
	list.SetSelectedFunc(func(i int, _ string, _ string, _ rune) {
		alive = false
		app.Stop()
		elections.RLock()
		// don't do anything if the election under the cursor has
		// changed
		if Ltime.Before(elections.Ltime) && L[i] != elections.L[roomID][i] {
			return
		}
		elections.RUnlock()

		if i > 0 {
			// user wants to join election

			el = elections.GetI(i - 1)
			el = L[i - 1]
			// don't need to lock because this goroutine controls LocalVoter
			if el.LocalVoter != nil {
				if el.LocalVoter.Ballot == nil {