~f4814n/frost

c4497e80e6fb1e0cd673c184438c866c749f6ea3 — Fabian Geiselhart 3 months ago 1870b0c
fix: Invalidate when roomlist updates
2 files changed, 41 insertions(+), 68 deletions(-)

M cmd/frost/app.go
M view/roomlist/roomlist.go
M cmd/frost/app.go => cmd/frost/app.go +3 -3
@@ 1,7 1,6 @@
package main

import (
	"fmt"
	"net/http"

	"golang.org/x/exp/shiny/materialdesign/icons"


@@ 137,7 136,7 @@ func (a *App) run() error {
			id:   id,
			View: roomlist.New(a.cli, a.modalLayer, a.theme, a.logger.Named("roomlist")),
		}
		a.views[0].Run(rx, tx)
		go a.views[0].Run(rx, tx)
	} else {
		id, rx, tx := a.mux.Register()
		a.views[0] = registeredView{id: id, View: login.New(a.theme, a.logger.Named("login"))}


@@ 171,7 170,6 @@ func (a *App) handleEvents() error {
			e.Frame(gtx.Ops)
		}
	case e := <-a.rx:
		fmt.Printf("%#v\n", e)
		switch e := e.(type) {
		case roomhistory.Show:
			a.currentRoom = e.Room


@@ 206,6 204,8 @@ func (a *App) handleEvents() error {
			}, nil)

			go a.views[1].Run(rx, tx)
		case frost.InvalidationEvent:
			a.window.Invalidate()
		}
	}


M view/roomlist/roomlist.go => view/roomlist/roomlist.go +38 -65
@@ 30,23 30,22 @@ type (
type view struct {
	rx, tx chan frost.Event

	matrixEvents chan matrix.Event

	cli      *matrix.Client
	roomList *RoomList
	cli *matrix.Client

	theme *material.Theme

	logger *zap.Logger

	list  *layout.List
	rooms []roomListElement
}

func New(cli *matrix.Client, modalLayer *materials.ModalLayer, theme *material.Theme, logger *zap.Logger) frost.View {
	return &view{
		cli:          cli,
		matrixEvents: make(chan matrix.Event, 100),
		roomList:     NewRoomList(logger, theme),
		theme:        theme,
		logger:       logger,
		cli:    cli,
		theme:  theme,
		logger: logger,
		list:   &layout.List{Axis: layout.Vertical},
	}
}



@@ 54,60 53,21 @@ func (l *view) Run(rx, tx chan frost.Event) {
	l.logger.Info("Starting")

	l.rx, l.tx = rx, tx
	l.cli.Notify(l.matrixEvents)
}

func (l *view) Layout(gtx layout.Context) layout.Dimensions {
	l.update(gtx)

	return l.roomList.Layout(gtx)
}

func (l *view) update(gtx g) {
	for _, room := range l.roomList.rooms {
		for _, e := range room.click.Events(gtx) {
			if e.Type == gesture.TypeClick {
				l.tx <- roomhistory.Show{
					Room: room.room,
				}
			}
		}
	}
	matrixEvents := make(chan matrix.Event, 100)
	l.cli.Notify(matrixEvents)

	for {
		select {
		case <-l.rx:
		case event := <-l.matrixEvents:
			l.roomList.NewEvent(event)
		case event := <-matrixEvents:
			l.handleMatrixEvent(event)
		default:
			return
			continue
		}
	}
}

func (l *view) Stop() {
}

// RoomList is a widget that displays a list of rooms
type RoomList struct {
	list   *layout.List
	logger *zap.Logger
	theme  *material.Theme
	rooms  []roomListElement
}

func NewRoomList(logger *zap.Logger, theme *material.Theme) *RoomList {
	return &RoomList{
		logger: logger,
		theme:  theme,
		list: &layout.List{
			Axis: layout.Vertical,
		},
	}
}

// NewEvent updates the room list when a new event arrives
func (w *RoomList) NewEvent(event matrix.Event) {
func (l *view) handleMatrixEvent(event matrix.Event) {
	var room matrix.Room

	switch event := event.(type) {


@@ 119,25 79,38 @@ func (w *RoomList) NewEvent(event matrix.Event) {
		return
	}

	for i, elem := range w.rooms {
	for _, elem := range l.rooms {
		if elem.room == room {
			w.logger.Debug("Adding room",
				zap.String("room", room.Displayname()),
			)
			w.rooms = append(w.rooms[:i], w.rooms[i+1:]...)
			break
			return
		}
	}
	w.rooms = append([]roomListElement{NewRoomListElement(room, event, w.theme)}, w.rooms...)
	l.rooms = append([]roomListElement{NewRoomListElement(room, event, l.theme)}, l.rooms...)
	l.tx <- frost.InvalidationEvent{}
}

// Layout implements the layout.Widget interface
func (w *RoomList) Layout(gtx g) d {
	return w.list.Layout(gtx, len(w.rooms), func(gtx g, index int) d {
		return w.rooms[index].Layout(gtx)
func (l *view) Layout(gtx layout.Context) layout.Dimensions {
	l.update(gtx)

	return l.list.Layout(gtx, len(l.rooms), func(gtx g, index int) d {
		return l.rooms[index].Layout(gtx)
	})
}

func (l *view) update(gtx g) {
	for _, room := range l.rooms {
		for _, e := range room.click.Events(gtx) {
			if e.Type == gesture.TypeClick {
				l.tx <- roomhistory.Show{
					Room: room.room,
				}
			}
		}
	}
}

func (l *view) Stop() {
}

// roomListElement is a element in the room list
type roomListElement struct {
	theme     *material.Theme