]> git.giacomolli.uk - onechat/blobdiff - view.go
Show stored images to the user
[onechat] / view.go
diff --git a/view.go b/view.go
index e39236401ca08dde025c4f91efefb7f39b54eaed..235719877517ad1cbce460dfa18ccb3c07af5366 100644 (file)
--- a/view.go
+++ b/view.go
@@ -28,7 +28,7 @@ func newView(high, low int) *View {
        return &View{
                high:  high,
                low:   low,
        return &View{
                high:  high,
                low:   low,
-               nodes: make(map[nodeKey]Node),
+               nodes: make(map[NodeKey]Node),
        }
 }
 
        }
 }
 
@@ -38,7 +38,7 @@ func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, er
        v := newView(high, low)
        v.merging = state.Merging
        for _, pair := range state.Lines {
        v := newView(high, low)
        v.merging = state.Merging
        for _, pair := range state.Lines {
-               line := nodeKey{pair[0], pair[1]}
+               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)
                }
                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)
                }
@@ -77,8 +77,8 @@ func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, er
 type View struct {
        high    int
        low     int
 type View struct {
        high    int
        low     int
-       lines   []nodeKey
-       nodes   map[nodeKey]Node
+       lines   []NodeKey
+       nodes   map[NodeKey]Node
        end     int
        merging bool
 }
        end     int
        merging bool
 }
@@ -100,7 +100,7 @@ func (v *View) State() ViewState {
 // Append adds the leaf of the next message as a line and merges when the view
 // is too large. It tells if a merge changed the view.
 func (v *View) Append(tree ViewNodeReader) (bool, error) {
 // Append adds the leaf of the next message as a line and merges when the view
 // is too large. It tells if a merge changed the view.
 func (v *View) Append(tree ViewNodeReader) (bool, error) {
-       line := nodeKey{0, v.end}
+       line := NodeKey{0, v.end}
        _, err := v.load(tree, line)
        if err != nil {
                return false, err
        _, err := v.load(tree, line)
        if err != nil {
                return false, err
@@ -118,8 +118,8 @@ func (v *View) Append(tree ViewNodeReader) (bool, error) {
 // either nest or do not overlap, so the result covers the messages without a
 // gap.
 func (v *View) Coarsen(other *View, tree ViewNodeReader) error {
 // either nest or do not overlap, so the result covers the messages without a
 // gap.
 func (v *View) Coarsen(other *View, tree ViewNodeReader) error {
-       lines := make([]nodeKey, 0, len(v.lines))
-       nodes := make(map[nodeKey]Node, len(v.nodes))
+       lines := make([]NodeKey, 0, len(v.lines))
+       nodes := make(map[NodeKey]Node, len(v.nodes))
        mine, theirs := 0, 0
        for start := 0; start < v.end; {
                line := v.lines[mine]
        mine, theirs := 0, 0
        for start := 0; start < v.end; {
                line := v.lines[mine]
@@ -154,7 +154,7 @@ func (v *View) Coarsen(other *View, tree ViewNodeReader) error {
 
 // Refresh keeps node when it is the node of a pending line.
 func (v *View) Refresh(node Node) {
 
 // Refresh keeps node when it is the node of a pending line.
 func (v *View) Refresh(node Node) {
-       key := nodeKey{node.Level, node.Index}
+       key := NodeKey{node.Level, node.Index}
        for n := len(v.lines) - 1; n >= 0; n-- {
                line := v.lines[n]
                if line == key {
        for n := len(v.lines) - 1; n >= 0; n-- {
                line := v.lines[n]
                if line == key {
@@ -168,6 +168,18 @@ func (v *View) Refresh(node Node) {
        }
 }
 
        }
 }
 
+// Pending tells if a line of the view is not built yet.
+func (v *View) Pending() bool {
+       for _, line := range v.lines {
+               _, built := v.nodes[line]
+               if !built {
+                       return true
+               }
+       }
+
+       return false
+}
+
 // Render returns the view as the model reads it: one line "id+n|text" for each
 // node inside <chat> tags, with the newlines of the text as spaces.
 func (v *View) Render() string {
 // Render returns the view as the model reads it: one line "id+n|text" for each
 // node inside <chat> tags, with the newlines of the text as spaces.
 func (v *View) Render() string {
@@ -185,7 +197,9 @@ func (v *View) LinesWithout(skip map[int]bool) []string {
                }
 
                var text strings.Builder
                }
 
                var text strings.Builder
+
                v.renderLine(&text, line)
                v.renderLine(&text, line)
+
                lines = append(lines, text.String())
        }
 
                lines = append(lines, text.String())
        }
 
@@ -197,7 +211,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
 // 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")
        text.WriteString("<chat>\n")
+
        for _, line := range v.lines {
                _, built := v.nodes[line]
                if !built || nodeEnd(line.level, line.index) > end {
        for _, line := range v.lines {
                _, built := v.nodes[line]
                if !built || nodeEnd(line.level, line.index) > end {
@@ -213,7 +229,7 @@ func (v *View) Context(end int) string {
 }
 
 // load keeps the node of line when it is built, and tells if it is.
 }
 
 // load keeps the node of line when it is built, and tells if it is.
-func (v *View) load(tree ViewNodeReader, line nodeKey) (bool, error) {
+func (v *View) load(tree ViewNodeReader, line NodeKey) (bool, error) {
        node, built, err := tree.Node(line.level, line.index)
        if err != nil || !built {
                return false, err
        node, built, err := tree.Node(line.level, line.index)
        if err != nil || !built {
                return false, err
@@ -240,7 +256,7 @@ func (v *View) fit(tree ViewNodeReader) (bool, error) {
                }
 
                left, right := v.lines[best], v.lines[best+1]
                }
 
                left, right := v.lines[best], v.lines[best+1]
-               parent := nodeKey{left.level + 1, left.index / 2}
+               parent := NodeKey{left.level + 1, left.index / 2}
                _, err = v.load(tree, parent)
                if err != nil {
                        return merged, err
                _, err = v.load(tree, parent)
                if err != nil {
                        return merged, err
@@ -249,6 +265,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)
                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
                v.lines[best] = parent
                v.lines = append(v.lines[:best+1], v.lines[best+2:]...)
                merged = true
@@ -260,7 +277,7 @@ func (v *View) fit(tree ViewNodeReader) (bool, error) {
 }
 
 // renderLine writes one view line, "id+n|text", and a newline.
 }
 
 // renderLine writes one view line, "id+n|text", and a newline.
-func (v *View) renderLine(text *strings.Builder, line nodeKey) {
+func (v *View) renderLine(text *strings.Builder, line NodeKey) {
        body := viewPending
        node, built := v.nodes[line]
        if built {
        body := viewPending
        node, built := v.nodes[line]
        if built {
@@ -304,7 +321,7 @@ func (v *View) mostDue(tree ViewNodeReader) (int, error) {
 
                built, err := tree.Built(left.level+1, left.index/2)
                if err != nil {
 
                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 {
                }
 
                if built {
@@ -317,7 +334,7 @@ func (v *View) mostDue(tree ViewNodeReader) (int, error) {
 }
 
 // lineSize returns the size of a view line.
 }
 
 // lineSize returns the size of a view line.
-func (v *View) lineSize(line nodeKey) int {
+func (v *View) lineSize(line NodeKey) int {
        node, built := v.nodes[line]
        if !built {
                return len(viewPending)
        node, built := v.nodes[line]
        if !built {
                return len(viewPending)