diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-08-16 23:27:51 -0600 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-08-17 20:02:43 -0600 |
commit | de4be82bf141f1eb5f57189bf251123e57996f28 (patch) | |
tree | 28701506e5e77af0120b25f52aed02f252cb12ac /framework/qml/ConversationView.qml | |
parent | a855b61ace6572e19c305cdee7bd080c5f89eb51 (diff) | |
download | kube-de4be82bf141f1eb5f57189bf251123e57996f28.tar.gz kube-de4be82bf141f1eb5f57189bf251123e57996f28.zip |
Non listview based conversationview
The listview deals badly with non uniformly sized items.
We use the buffer hack to ensure all items are loaded so it works at
all, and setting the current index resulted in unpredictable scrolling.
With this new approach we manage everything ourselves in a Flickable,
and just always load all delegates (which we also did before, but with a
hack). As an optimization it should be possible to avoid loading some
delegates until they become visible.
Note that ConversationView is thightly coupled to ConversationListView
due to dependencies on some properties in the delegate. This could be
handled more elegantly with attached properties.
In any case, this seems to work much, much better.
Diffstat (limited to 'framework/qml/ConversationView.qml')
-rw-r--r-- | framework/qml/ConversationView.qml | 82 |
1 files changed, 16 insertions, 66 deletions
diff --git a/framework/qml/ConversationView.qml b/framework/qml/ConversationView.qml index 85707300..03ea3065 100644 --- a/framework/qml/ConversationView.qml +++ b/framework/qml/ConversationView.qml | |||
@@ -36,7 +36,6 @@ FocusScope { | |||
36 | filter: Kube.Messages.mailSelection | 36 | filter: Kube.Messages.mailSelection |
37 | onMessageReceived: { | 37 | onMessageReceived: { |
38 | root.mail = message.mail | 38 | root.mail = message.mail |
39 | listView.forceLayout() | ||
40 | } | 39 | } |
41 | } | 40 | } |
42 | 41 | ||
@@ -52,10 +51,9 @@ FocusScope { | |||
52 | anchors.fill: parent | 51 | anchors.fill: parent |
53 | color: Kube.Colors.backgroundColor | 52 | color: Kube.Colors.backgroundColor |
54 | 53 | ||
55 | Kube.ListView { | 54 | Kube.ConversationListView { |
56 | id: listView | 55 | id: listView |
57 | focus: true | 56 | focus: true |
58 | currentIndex: -1 | ||
59 | 57 | ||
60 | anchors { | 58 | anchors { |
61 | top: parent.top | 59 | top: parent.top |
@@ -65,69 +63,33 @@ FocusScope { | |||
65 | //Shrink the listview if the content doesn't fill the full height, so the email appears on top instead of on the bottom. | 63 | //Shrink the listview if the content doesn't fill the full height, so the email appears on top instead of on the bottom. |
66 | height: Math.min(contentHeight, parent.height) | 64 | height: Math.min(contentHeight, parent.height) |
67 | 65 | ||
68 | verticalLayoutDirection: ListView.BottomToTop | ||
69 | |||
70 | onActiveFocusChanged: { | ||
71 | if (activeFocus) { | ||
72 | if (currentIndex < 0) { | ||
73 | currentIndex = 0 | ||
74 | } | ||
75 | } else { | ||
76 | currentIndex = -1 | ||
77 | } | ||
78 | } | ||
79 | |||
80 | //Position view so the last email begins on top of the view | ||
81 | onContentHeightChanged: { | ||
82 | //FIXME This doesn't work quite correctly when we have headers and footers in the listview and the mail loads to slowly and only one item to show. | ||
83 | listView.positionViewAtIndex(currentIndex, ListView.End) | ||
84 | } | ||
85 | |||
86 | Keys.onDownPressed: { | ||
87 | decrementCurrentIndex() | ||
88 | positionViewAtIndex(listView.currentIndex, ListView.End) | ||
89 | } | ||
90 | |||
91 | Keys.onUpPressed: { | ||
92 | incrementCurrentIndex() | ||
93 | positionViewAtIndex(listView.currentIndex, ListView.End) | ||
94 | } | ||
95 | |||
96 | onCurrentIndexChanged: { | ||
97 | markAsReadTimer.restart(); | ||
98 | } | ||
99 | |||
100 | model: Kube.MailListModel { | 66 | model: Kube.MailListModel { |
101 | mail: root.mail | 67 | mail: root.mail |
102 | } | 68 | } |
103 | 69 | ||
104 | header: Item { | ||
105 | height: Kube.Units.gridUnit * 0.5 | ||
106 | width: parent.width | ||
107 | } | ||
108 | |||
109 | footer: Item { | ||
110 | height: Kube.Units.gridUnit | ||
111 | width: parent.width | ||
112 | } | ||
113 | |||
114 | delegate: FocusScope { | 70 | delegate: FocusScope { |
115 | id: delegateRoot | 71 | id: delegateRoot |
116 | 72 | ||
117 | property var currentData: model | 73 | property var currentData: model |
74 | property bool isCurrentItem: false | ||
75 | property int index: -1 | ||
118 | 76 | ||
119 | focus: false | 77 | focus: false |
120 | activeFocusOnTab: false | 78 | activeFocusOnTab: false |
121 | 79 | ||
122 | height: sheet.height + Kube.Units.gridUnit | 80 | height: sheet.height + Kube.Units.gridUnit |
123 | width: parent.width | 81 | width: listView.width |
124 | visible: !((root.hideTrash && model.trash) || (root.hideNonTrash && !model.trash)) | 82 | visible: !((root.hideTrash && model.trash) || (root.hideNonTrash && !model.trash)) |
125 | 83 | ||
126 | MouseArea { | 84 | MouseArea { |
127 | anchors.fill: parent | 85 | anchors.fill: parent |
128 | hoverEnabled: true | 86 | hoverEnabled: true |
129 | onEntered: delegateRoot.ListView.view.currentIndex = index | 87 | onEntered: listView.currentIndex = delegateRoot.index |
130 | onClicked: delegateRoot.ListView.view.currentIndex = index | 88 | onClicked: { |
89 | listView.currentIndex = delegateRoot.index | ||
90 | listView.forceActiveFocus(Qt.MouseFocusReason) | ||
91 | } | ||
92 | z: 1.0 | ||
131 | } | 93 | } |
132 | 94 | ||
133 | MailViewer { | 95 | MailViewer { |
@@ -147,19 +109,15 @@ FocusScope { | |||
147 | draft: model.draft | 109 | draft: model.draft |
148 | sent: model.sent | 110 | sent: model.sent |
149 | incomplete: model.incomplete | 111 | incomplete: model.incomplete |
150 | current: delegateRoot.ListView.isCurrentItem | 112 | current: delegateRoot.isCurrentItem |
151 | } | 113 | } |
152 | } | 114 | } |
153 | 115 | ||
154 | 116 | onCurrentItemChanged: { | |
155 | //Optimize for view quality | 117 | if (currentItem) { |
156 | pixelAligned: true | 118 | markAsReadTimer.restart() |
157 | 119 | } | |
158 | 120 | } | |
159 | //The cacheBuffer needs to be large enough to fit the whole thread. | ||
160 | //Otherwise the contentHeight will constantly increase and decrease, | ||
161 | //which will break lot's of things. | ||
162 | cacheBuffer: 100000 | ||
163 | 121 | ||
164 | Timer { | 122 | Timer { |
165 | id: markAsReadTimer | 123 | id: markAsReadTimer |
@@ -172,14 +130,6 @@ FocusScope { | |||
172 | } | 130 | } |
173 | } | 131 | } |
174 | } | 132 | } |
175 | |||
176 | //Intercept all scroll events, | ||
177 | //necessary due to the webengineview | ||
178 | Kube.MouseProxy { | ||
179 | anchors.fill: parent | ||
180 | target: listView.mouseProxy | ||
181 | forwardWheelEvents: true | ||
182 | } | ||
183 | } | 133 | } |
184 | } | 134 | } |
185 | } | 135 | } |