]> git.giacomolli.uk - onechat/blobdiff - view.go
Order model and chat declarations
[onechat] / view.go
diff --git a/view.go b/view.go
index 233e08921f7a1ec2699244832177be784c3faae4..1b3ed6ae985b902811ca263d0047a8953800638a 100644 (file)
--- a/view.go
+++ b/view.go
@@ -23,42 +23,6 @@ const (
        viewPending = "(not summarized yet: zoom it)"
 )
 
-// newView returns an empty view with the limits high and low.
-func newView(high, low int) *View {
-       return &View{
-               high:  high,
-               low:   low,
-               nodes: make(map[NodeKey]Node),
-       }
-}
-
-// restoreView returns the view of state with the limits high and low. Each line
-// must continue the one before it, and each line above level 0 must be built.
-func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, error) {
-       v := newView(high, low)
-       v.merging = state.Merging
-       for _, pair := range state.Lines {
-               line := NodeKey{pair[0], pair[1]}
-               if line.level < 0 || line.level >= bits.UintSize-2 || line.index < 0 || line.index<<line.level != v.end {
-                       return nil, fmt.Errorf("view line (%d, %d) does not start at message %d", line.level, line.index, v.end)
-               }
-
-               built, err := v.load(tree, line)
-               if err != nil {
-                       return nil, err
-               }
-
-               if line.level > 0 && !built {
-                       return nil, fmt.Errorf("view line (%d, %d) is not built", line.level, line.index)
-               }
-
-               v.lines = append(v.lines, line)
-               v.end = nodeEnd(line.level, line.index)
-       }
-
-       return v, nil
-}
-
 // View is a list of tree nodes that covers messages 0 to end-1 without a gap,
 // oldest first. Each new message appends its leaf as a line. Once the size of
 // the view goes above high, one batch merges the most due sibling pairs until
@@ -83,6 +47,27 @@ type View struct {
        merging bool
 }
 
+// ViewState is the saved form of a View. The limits are not part of it.
+type ViewState struct {
+       Lines   [][2]int `json:"lines"`
+       Merging bool     `json:"merging"`
+}
+
+// ViewNodeReader gives the built nodes of a tree.
+type ViewNodeReader interface {
+       Built(level, index int) (bool, error)
+       Node(level, index int) (Node, bool, error)
+}
+
+// newView returns an empty view with the limits high and low.
+func newView(high, low int) *View {
+       return &View{
+               high:  high,
+               low:   low,
+               nodes: make(map[NodeKey]Node),
+       }
+}
+
 // State returns the saved form of the view.
 func (v *View) State() ViewState {
        state := ViewState{
@@ -197,7 +182,9 @@ func (v *View) LinesWithout(skip map[int]bool) []string {
                }
 
                var text strings.Builder
+
                v.renderLine(&text, line)
+
                lines = append(lines, text.String())
        }
 
@@ -209,7 +196,9 @@ func (v *View) LinesWithout(skip map[int]bool) []string {
 // sees a pending mark or a part of a message.
 func (v *View) Context(end int) string {
        var text strings.Builder
+
        text.WriteString("<chat>\n")
+
        for _, line := range v.lines {
                _, built := v.nodes[line]
                if !built || nodeEnd(line.level, line.index) > end {
@@ -261,6 +250,7 @@ func (v *View) fit(tree ViewNodeReader) (bool, error) {
                size += v.lineSize(parent) - v.lineSize(left) - v.lineSize(right)
                delete(v.nodes, left)
                delete(v.nodes, right)
+
                v.lines[best] = parent
                v.lines = append(v.lines[:best+1], v.lines[best+2:]...)
                merged = true
@@ -316,7 +306,7 @@ func (v *View) mostDue(tree ViewNodeReader) (int, error) {
 
                built, err := tree.Built(left.level+1, left.index/2)
                if err != nil {
-                       return -1, err
+                       return -1, fmt.Errorf("check parent node: %w", err)
                }
 
                if built {
@@ -338,14 +328,29 @@ func (v *View) lineSize(line NodeKey) int {
        return node.Size
 }
 
-// ViewState is the saved form of a View. The limits are not part of it.
-type ViewState struct {
-       Lines   [][2]int `json:"lines"`
-       Merging bool     `json:"merging"`
-}
+// restoreView returns the view of state with the limits high and low. Each line
+// must continue the one before it, and each line above level 0 must be built.
+func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, error) {
+       v := newView(high, low)
+       v.merging = state.Merging
+       for _, pair := range state.Lines {
+               line := NodeKey{pair[0], pair[1]}
+               if line.level < 0 || line.level >= bits.UintSize-2 || line.index < 0 || line.index<<line.level != v.end {
+                       return nil, fmt.Errorf("view line (%d, %d) does not start at message %d", line.level, line.index, v.end)
+               }
 
-// ViewNodeReader gives the built nodes of a tree.
-type ViewNodeReader interface {
-       Built(level, index int) (bool, error)
-       Node(level, index int) (Node, bool, error)
+               built, err := v.load(tree, line)
+               if err != nil {
+                       return nil, err
+               }
+
+               if line.level > 0 && !built {
+                       return nil, fmt.Errorf("view line (%d, %d) is not built", line.level, line.index)
+               }
+
+               v.lines = append(v.lines, line)
+               v.end = nodeEnd(line.level, line.index)
+       }
+
+       return v, nil
 }