1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
diff --git a/app/dirtree.go b/app/dirtree.go
index 24e776d8a4eddbcfc1d7271ee66848a2d32ddd7e..50f5797f21954f6fd249ee2138d8eb9d31e941aa 100644
--- a/app/dirtree.go
+++ b/app/dirtree.go
@@ -167,7 +167,11 @@ if visible == y+dt.Scroll()+1 {
if path := dt.getDirectory(node); path != "" {
return path, true
}
- node.Hidden = !node.Hidden
+ if node.Hidden == 0 {
+ node.Hidden = 1
+ } else {
+ node.Hidden = 0
+ }
dt.Invalidate()
return "", false
}
@@ -251,8 +255,8 @@
func (dt *DirectoryTree) CollapseFolder() {
if dt.listIdx >= 0 && dt.listIdx < len(dt.list) {
if node := dt.list[dt.listIdx]; node != nil {
- if node.Parent != nil && (node.Hidden || node.FirstChild == nil) {
- node.Parent.Hidden = true
+ if node.Parent != nil && (node.Hidden != 0 || node.FirstChild == nil) {
+ node.Parent.Hidden = 1
// highlight parent node and select it
for i, t := range dt.list {
if t == node.Parent {
@@ -263,7 +267,7 @@ }
}
}
} else {
- node.Hidden = true
+ node.Hidden = 1
}
dt.Invalidate()
}
@@ -272,7 +276,7 @@ }
func (dt *DirectoryTree) ExpandFolder() {
if dt.listIdx >= 0 && dt.listIdx < len(dt.list) {
- dt.list[dt.listIdx].Hidden = false
+ dt.list[dt.listIdx].Hidden = 0
dt.Invalidate()
}
}
@@ -313,7 +317,7 @@
func (dt *DirectoryTree) hiddenDirectories() map[string]bool {
hidden := make(map[string]bool, 0)
for _, node := range dt.list {
- if node.Hidden && node.FirstChild != nil {
+ if node.Hidden != 0 && node.FirstChild != nil {
elems := strings.Split(dt.treeDirs[getAnyUid(node)], dt.DirectoryList.worker.PathSeparator())
if levels := countLevels(node); levels < len(elems) {
if node.FirstChild != nil && (levels+1) < len(elems) {
@@ -337,7 +341,7 @@ levels += 1
}
strDir := strings.Join(elems[:levels], dt.DirectoryList.worker.PathSeparator())
if hidden, ok := hiddenDirs[strDir]; hidden && ok {
- node.Hidden = true
+ node.Hidden = 1
}
}
}
@@ -438,7 +442,11 @@ }
nextNode := &types.Thread{Uid: uid}
node.AddChild(nextNode)
if dt.UiConfig(path).DirListCollapse != 0 {
- node.Hidden = depth > dt.UiConfig(path).DirListCollapse
+ if depth > dt.UiConfig(path).DirListCollapse {
+ node.Hidden = 1
+ } else {
+ node.Hidden = 0
+ }
}
dt.buildTreeNode(nextNode, next, defaultUid, depth+1)
}
@@ -449,14 +457,14 @@ if node == nil {
return
}
for iter := node.Parent; iter != nil; iter = iter.Parent {
- iter.Hidden = false
+ iter.Hidden = 0
}
}
func isVisible(node *types.Thread) bool {
isVisible := true
for iter := node.Parent; iter != nil; iter = iter.Parent {
- if iter.Hidden {
+ if iter.Hidden != 0 {
isVisible = false
break
}
@@ -488,7 +496,7 @@ func getFlag(node *types.Thread) string {
if node == nil && node.FirstChild == nil {
return ""
}
- if node.Hidden {
+ if node.Hidden != 0 {
return "+"
}
return ""
diff --git a/app/msglist.go b/app/msglist.go
index e57bfe9d86bd3db6cd67dc76ba713ed452a9d8c4..146d032d1668573a01d8b82ee172d196988bcef1 100644
--- a/app/msglist.go
+++ b/app/msglist.go
@@ -485,7 +485,7 @@ same = subject == t.prevSubj && sameParent(thread, t.prev) && !isParent(thread)
t.prev = thread
t.prevSubj = subject
count = countThreads(thread)
- folded = thread.FirstChild != nil && thread.FirstChild.Hidden
+ folded = thread.FirstChild != nil && thread.FirstChild.Hidden != 0
context = thread.Context
}
data.SetThreading(prefix, same, count, folded, context)
diff --git a/lib/msgstore.go b/lib/msgstore.go
index c68c2ed86b4c4987b63bd4957b8b0bc8d3b8f764..ca5f16d9c8dbd1063d3ca201f862c2624e09869b 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -517,14 +517,23 @@ func (store *MessageStore) Unfold(uid uint32) error {
return store.doThreadFolding(uid, false)
}
-func (store *MessageStore) doThreadFolding(uid uint32, hidden bool) error {
+func (store *MessageStore) doThreadFolding(uid uint32, hide bool) error {
thread, err := store.Thread(uid)
if err != nil {
return err
}
+ if hide && thread.FirstChild.Hidden > 0 {
+ return nil
+ }
err = thread.Walk(func(t *types.Thread, _ int, __ error) error {
if t.Uid != uid {
- t.Hidden = hidden
+ if hide {
+ t.Hidden++ //increase fold level
+ } else if t.Hidden > 1 {
+ t.Hidden--
+ } else {
+ t.Hidden = 0
+ }
}
return nil
})
diff --git a/lib/threadbuilder.go b/lib/threadbuilder.go
index 1f2d72c6243adc725edf911050343aacd22eb560..63ae80d36bce44285818e9a2b34a913a11f72f2f 100644
--- a/lib/threadbuilder.go
+++ b/lib/threadbuilder.go
@@ -205,7 +205,7 @@ t.Hidden = stored.Hidden
t.Deleted = stored.Deleted
}
builder.threadMap[t.Uid] = t
- if t.Deleted || t.Hidden {
+ if t.Deleted || t.Hidden != 0 {
return nil
}
threaduids = append(threaduids, t.Uid)
diff --git a/worker/notmuch/lib/database.go b/worker/notmuch/lib/database.go
index 015126c2bb6abbd16f422dc868882360e3e27128..b2a22227bda81b0d8e600e3d8fe490ec264edf70 100644
--- a/worker/notmuch/lib/database.go
+++ b/worker/notmuch/lib/database.go
@@ -336,7 +336,11 @@ switch threadContext {
case true:
node.Context = !match
default:
- node.Hidden = !match
+ if match {
+ node.Hidden = 0
+ } else {
+ node.Hidden = 1
+ }
}
if parent != nil && parent.FirstChild == nil {
parent.FirstChild = node
diff --git a/worker/types/thread.go b/worker/types/thread.go
index 75651280a7fbc6bb9f0e5a9b83e6d635ef867f75..b4f5ac5fcfa54fe5db33df93dc98cc198013271e 100644
--- a/worker/types/thread.go
+++ b/worker/types/thread.go
@@ -15,7 +15,7 @@ PrevSibling *Thread
NextSibling *Thread
FirstChild *Thread
- Hidden bool // if this flag is set the message isn't rendered in the UI
+ Hidden int // if this flag is not zero the message isn't rendered in the UI
Deleted bool // if this flag is set the message was deleted
// Context indicates the message doesn't match the mailbox / query but
|