~gioverse/chat

d85f2e81070557e8870f05f1482339bb018a0ce9 — Chris Waldon 2 months ago ff42a2f
example/kitchen: update to new Loader signature

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2 files changed, 32 insertions(+), 28 deletions(-)

M example/kitchen/row-tracker.go
M example/kitchen/ui.go
M example/kitchen/row-tracker.go => example/kitchen/row-tracker.go +6 -4
@@ 99,7 99,7 @@ func (r *RowTracker) NewRow() list.Element {
// Load simulates loading chat history from a database or API. It
// sleeps for a random number of milliseconds and then returns
// some messages.
func (r *RowTracker) Load(dir list.Direction, relativeTo list.Serial) (loaded []list.Element) {
func (r *RowTracker) Load(dir list.Direction, relativeTo list.Serial) (loaded []list.Element, more bool) {
	if r.SimulateLatency > 0 {
		duration := time.Millisecond * time.Duration(rand.Intn(r.SimulateLatency))
		log.Println("sleeping", duration)


@@ 117,13 117,15 @@ func (r *RowTracker) Load(dir list.Direction, relativeTo list.Serial) (loaded []
		// If loading relative to nothing, likely the chat interface is empty.
		// We should load the most recent messages first in this case, regardless
		// of the direction parameter.
		return r.Rows[numRows-min(r.MaxLoads, numRows):]
		return r.Rows[numRows-min(r.MaxLoads, numRows):], numRows > r.MaxLoads
	}
	idx := r.SerialToIndex[relativeTo]
	if dir == list.After {
		return r.Rows[idx+1 : min(numRows, idx+r.MaxLoads)]
		end := min(numRows, idx+r.MaxLoads)
		return r.Rows[idx+1 : end], end < len(r.Rows)-1
	}
	return r.Rows[maximum(0, idx-r.MaxLoads):idx]
	start := maximum(0, idx-r.MaxLoads)
	return r.Rows[start:idx], start > 0
}

// Delete removes the element with the provided serial from storage.

M example/kitchen/ui.go => example/kitchen/ui.go +26 -24
@@ 132,31 132,33 @@ func NewUI(w *app.Window) *UI {
		rt := NewExampleData(users, local, g, 100)
		rt.SimulateLatency = latency
		rt.MaxLoads = loadSize
		ui.Rooms.List = append(ui.Rooms.List, Room{
			Room:     r,
			Messages: rt,
			ListState: list.NewManager(bufferSize,
				list.Hooks{
					// Define an allocator function that can instaniate the appropriate
					// state type for each kind of row data in our list.
					Allocator: func(data list.Element) interface{} {
						switch data.(type) {
						case model.Message:
							return &chatwidget.Row{}
						default:
							return nil
						}
					},
					// Define a presenter that can transform each kind of row data
					// and state into a widget.
					Presenter: ui.presentChatRow,
					// NOTE(jfm): awkard coupling between message data and `list.Manager`.
					Loader:      rt.Load,
					Synthesizer: synth,
					Comparator:  rowLessThan,
					Invalidator: w.Invalidate,
		lm := list.NewManager(bufferSize,
			list.Hooks{
				// Define an allocator function that can instaniate the appropriate
				// state type for each kind of row data in our list.
				Allocator: func(data list.Element) interface{} {
					switch data.(type) {
					case model.Message:
						return &chatwidget.Row{}
					default:
						return nil
					}
				},
			),
				// Define a presenter that can transform each kind of row data
				// and state into a widget.
				Presenter: ui.presentChatRow,
				// NOTE(jfm): awkard coupling between message data and `list.Manager`.
				Loader:      rt.Load,
				Synthesizer: synth,
				Comparator:  rowLessThan,
				Invalidator: w.Invalidate,
			},
		)
		lm.Stickiness = list.After
		ui.Rooms.List = append(ui.Rooms.List, Room{
			Room:      r,
			Messages:  rt,
			ListState: lm,
		})
	}