summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/package/contents/ui/ConversationView.qml115
-rw-r--r--framework/domain/mailcontroller.cpp2
2 files changed, 111 insertions, 6 deletions
diff --git a/components/package/contents/ui/ConversationView.qml b/components/package/contents/ui/ConversationView.qml
index 3c76928f..6ecc59ae 100644
--- a/components/package/contents/ui/ConversationView.qml
+++ b/components/package/contents/ui/ConversationView.qml
@@ -31,11 +31,43 @@ Rectangle {
31 id: root 31 id: root
32 32
33 property variant mail; 33 property variant mail;
34 property int currentIndex: 0;
35 property bool scrollToEnd: true;
36 property variant currentMail: null;
37 onCurrentIndexChanged: {
38 markAsReadTimer.restart();
39 }
40 onMailChanged: {
41 scrollToEnd = true;
42 currentMail = null;
43 }
34 44
35 color: Kirigami.Theme.backgroundColor 45 color: Kirigami.Theme.backgroundColor
36 46
37 ListView { 47 ListView {
38 id: listView 48 id: listView
49 function setCurrentIndex()
50 {
51 /**
52 * This will detect the index at the "scrollbar-position" (visibleArea.yPosition).
53 * This ensures that the first and last entry can become the currentIndex,
54 * but in the middle of the list the item in the middle is set as the current item.
55 */
56 var yPos = 0.5;
57 if (listView.visibleArea.yPosition < 0.4) {
58 yPos = 0.2 + (0.2 * listView.visibleArea.yPosition);
59 }
60 if (listView.visibleArea.yPosition > 0.6) {
61 yPos = 0.6 + (0.2 * listView.visibleArea.yPosition)
62 }
63 var indexAtCenter = listView.indexAt(root.width / 2, contentY + root.height * yPos);
64 if (indexAtCenter >= 0) {
65 root.currentIndex = indexAtCenter;
66 } else {
67 root.currentIndex = count - 1;
68 }
69 }
70
39 anchors { 71 anchors {
40 top: parent.top 72 top: parent.top
41 left: parent.left 73 left: parent.left
@@ -64,13 +96,68 @@ Rectangle {
64 96
65 boundsBehavior: Flickable.StopAtBounds 97 boundsBehavior: Flickable.StopAtBounds
66 98
67 //Always scroll to the end of the conversation 99 //default is 1500, which is not usable with a mouse
68 highlightFollowsCurrentItem: true 100 flickDeceleration: 10000
69 //Scroll quickly 101
70 highlightMoveDuration: 1 102 //Optimize for view quality
103 pixelAligned: true
104
105 Timer {
106 id: scrollToEndTimer
107 interval: 10
108 running: false
109 repeat: false
110 onTriggered: {
111 //Only do this once per conversation
112 root.scrollToEnd = false;
113 root.currentIndex = listView.count - 1
114 //positionViewAtEnd/Index don't work
115 listView.contentY = listView.contentHeight - listView.height
116 }
117 }
118
71 onCountChanged: { 119 onCountChanged: {
72 //TODO: ideally we should only do this initially, not when new messages enter while you're reading. 120 if (root.scrollToEnd) {
73 currentIndex = count - 1; 121 scrollToEndTimer.restart()
122 }
123 }
124
125 onContentHeightChanged: {
126 //Initially it will resize a lot, so we keep waiting
127 if (root.scrollToEnd) {
128 scrollToEndTimer.restart()
129 }
130 }
131
132 onContentYChanged: {
133 //We have to track our current mail manually
134 setCurrentIndex();
135 }
136
137 //The cacheBuffer needs to be large enough to fit the whole thread.
138 //Otherwise the contentHeight will constantly increase and decrease,
139 //which will break lot's of things.
140 cacheBuffer: 100000
141
142 KubeFramework.MailController {
143 id: mailController
144 Binding on mail {
145 //!! checks for the availability of the type
146 when: !!root.currentMail
147 value: root.currentMail
148 }
149 }
150
151 Timer {
152 id: markAsReadTimer
153 interval: 2000
154 running: false
155 repeat: false
156 onTriggered: {
157 if (mailController.markAsReadAction.enabled) {
158 mailController.markAsReadAction.execute();
159 }
160 }
74 } 161 }
75 162
76 //Intercept all scroll events, 163 //Intercept all scroll events,
@@ -85,6 +172,13 @@ Rectangle {
85 id: mailDelegate 172 id: mailDelegate
86 173
87 Item { 174 Item {
175 id: wrapper
176 property bool isCurrent: root.currentIndex === index;
177 onIsCurrentChanged: {
178 if (isCurrent) {
179 root.currentMail = model.mail
180 }
181 }
88 182
89 height: sheet.height + Kirigami.Units.gridUnit 183 height: sheet.height + Kirigami.Units.gridUnit
90 width: parent.width 184 width: parent.width
@@ -95,6 +189,15 @@ Rectangle {
95 implicitHeight: header.height + attachments.height + body.height + footer.height + Kirigami.Units.largeSpacing 189 implicitHeight: header.height + attachments.height + body.height + footer.height + Kirigami.Units.largeSpacing
96 width: parent.width - Kirigami.Units.gridUnit * 2 190 width: parent.width - Kirigami.Units.gridUnit * 2
97 191
192 //Overlay for non-active mails
193 Rectangle {
194 anchors.fill: parent
195 visible: !wrapper.isCurrent
196 color: "lightGrey"
197 z: 1
198 opacity: 0.2
199 }
200
98 color: Kirigami.Theme.viewBackgroundColor 201 color: Kirigami.Theme.viewBackgroundColor
99 202
100 //BEGIN header 203 //BEGIN header
diff --git a/framework/domain/mailcontroller.cpp b/framework/domain/mailcontroller.cpp
index 962b785f..b912567a 100644
--- a/framework/domain/mailcontroller.cpp
+++ b/framework/domain/mailcontroller.cpp
@@ -61,6 +61,8 @@ void MailController::updateActions()
61 if (mail) { 61 if (mail) {
62 action_moveToTrash->setEnabled(!mail->getTrash()); 62 action_moveToTrash->setEnabled(!mail->getTrash());
63 action_restoreFromTrash->setEnabled(mail->getTrash()); 63 action_restoreFromTrash->setEnabled(mail->getTrash());
64 action_markAsRead->setEnabled(mail->getUnread());
65 action_markAsUnread->setEnabled(!mail->getUnread());
64 } 66 }
65} 67}
66 68