Merge lp:~aacid/unity8/listviewforreviews into lp:unity8

Proposed by Albert Astals Cid on 2015-11-13
Status: Merged
Approved by: Michael Zanetti on 2015-12-01
Approved revision: 2045
Merged at revision: 2084
Proposed branch: lp:~aacid/unity8/listviewforreviews
Merge into: lp:unity8
Diff against target: 293 lines (+179/-25)
8 files modified
qml/Dash/Previews/Preview.qml (+2/-0)
qml/Dash/Previews/PreviewRatingDisplay.qml (+72/-21)
qml/Dash/Previews/PreviewWidget.qml (+3/-0)
qml/Dash/Previews/PreviewWidgetFactory.qml (+4/-0)
tests/qmltests/CMakeLists.txt (+1/-0)
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml (+1/-3)
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplayCreationRanges.qml (+94/-0)
tests/utils/modules/Unity/Test/UnityTestCase.qml (+2/-1)
To merge this branch: bzr merge lp:~aacid/unity8/listviewforreviews
Reviewer Review Type Date Requested Status
Michael Zanetti (community) 2015-11-13 Approve on 2015-12-01
PS Jenkins bot continuous-integration Needs Fixing on 2015-11-27
Review via email: mp+277428@code.launchpad.net

Commit Message

Create ratings on demand instead of all at the same time

Description of the Change

 * Are there any related MPs required for this MP to build/function as expected?
No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2039
http://jenkins.qa.ubuntu.com/job/unity8-ci/6706/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5141/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/121/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1418/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/121
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1313
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1314
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/120
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/120
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5155
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5155/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/22/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/121
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/121/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25132

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6706/rebuild

review: Needs Fixing (continuous-integration)
Michael Zanetti (mzanetti) wrote :

Improves the issue a lot. Code looks reasonable.

Do you think it is worth writing some test for this? Shouldn't be too hard to open a fake preview with tons of entries, making sure only very few are created, flicking to the bottom and making sure all of them are created. Would at least check if noone breaks it by making it perform bad again, or by preventing things from being built up when required.

Michael Zanetti (mzanetti) :
review: Needs Information
lp:~aacid/unity8/listviewforreviews updated on 2015-11-26
2040. By Albert Astals Cid on 2015-11-26

Merge

2041. By Albert Astals Cid on 2015-11-26

Do not use 5 max iterations hardcoded in flickToYEnd, makes no sense

2042. By Albert Astals Cid on 2015-11-26

Rename parentList to parentFlickable

2043. By Albert Astals Cid on 2015-11-26

Add test for the creation ranges on rating display creation

Albert Astals Cid (aacid) wrote :

Test added

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2040
http://jenkins.qa.ubuntu.com/job/unity8-ci/6815/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5435
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/230/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1526
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/228
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1421
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1421
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/228/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/227/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4290
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5449
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5449/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25547
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/76/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/229
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/229/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25546

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6815/rebuild

review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/listviewforreviews updated on 2015-11-27
2044. By Albert Astals Cid on 2015-11-27

beware of scary eol

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2044
http://jenkins.qa.ubuntu.com/job/unity8-ci/6818/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5447
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/233/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1529
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/231/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1424
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1424
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/231
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/230
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4299
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5461
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5461/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25564
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/77/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/232
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/232/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25563

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6818/rebuild

review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/listviewforreviews updated on 2015-11-27
2045. By Albert Astals Cid on 2015-11-27

Make test pass again

There's no need to check the repeater.count (that doesn't exist anymore)
since we're checking the existance of "reviewItem" + index later in the loop anyway

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2045
http://jenkins.qa.ubuntu.com/job/unity8-ci/6820/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5449
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/235/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1531
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/233
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1426
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1426
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/233
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/232
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4301
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5463
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5463/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25572
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/79/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/234
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/234/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25571

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6820/rebuild

review: Needs Fixing (continuous-integration)
Michael Zanetti (mzanetti) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?

yes

 * Did CI run pass? If not, please explain why.

yes

 * Did you make sure that the branch does not contain spurious tags?

yes

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Dash/Previews/Preview.qml'
2--- qml/Dash/Previews/Preview.qml 2015-11-04 14:57:13 +0000
3+++ qml/Dash/Previews/Preview.qml 2015-11-27 10:34:17 +0000
4@@ -90,6 +90,8 @@
5 widgetData: model.properties
6 isCurrentPreview: root.isCurrent
7 scopeStyle: root.scopeStyle
8+ parentFlickable: column
9+
10 anchors {
11 left: parent.left
12 right: parent.right
13
14=== modified file 'qml/Dash/Previews/PreviewRatingDisplay.qml'
15--- qml/Dash/Previews/PreviewRatingDisplay.qml 2015-08-13 09:08:15 +0000
16+++ qml/Dash/Previews/PreviewRatingDisplay.qml 2015-11-27 10:34:17 +0000
17@@ -40,28 +40,79 @@
18 id: root
19 implicitHeight: childrenRect.height
20
21- Column {
22+ onIsCurrentPreviewChanged: ratingsList.updateRanges();
23+ onParentFlickableChanged: ratingsList.updateRanges();
24+
25+ Connections {
26+ target: parentFlickable
27+ onOriginYChanged: ratingsList.updateRanges();
28+ onContentYChanged: ratingsList.updateRanges();
29+ onHeightChanged: ratingsList.updateRanges();
30+ onContentHeightChanged: ratingsList.updateRanges();
31+ }
32+
33+ ListView {
34+ id: ratingsList
35 anchors { left: parent.left; right: parent.right; }
36- visible: reviewsRepeater.count > 0
37-
38- Repeater {
39- id: reviewsRepeater
40- objectName: "reviewsRepeater"
41- model: root.widgetData["reviews"]
42-
43- delegate: PreviewRatingSingleDisplay {
44- objectName: "reviewItem" + index
45-
46- anchors { left: parent.left; right: parent.right; }
47-
48- rating: modelData["rating"] || -1
49- author: modelData["author"] || ""
50- review: modelData["review"] || ""
51- urlIconEmpty: widgetData["rating-icon-empty"]
52- urlIconFull: widgetData["rating-icon-full"]
53- urlIconHalf: widgetData["rating-icon-half"]
54- labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
55- }
56+ height: contentHeight
57+ interactive: false
58+
59+ model: root.widgetData["reviews"]
60+
61+ delegate: PreviewRatingSingleDisplay {
62+ id: prsd
63+ objectName: "reviewItem" + index
64+
65+ anchors { left: parent.left; right: parent.right; }
66+
67+ rating: modelData["rating"] || -1
68+ author: modelData["author"] || ""
69+ review: modelData["review"] || ""
70+ urlIconEmpty: widgetData["rating-icon-empty"]
71+ urlIconFull: widgetData["rating-icon-full"]
72+ urlIconHalf: widgetData["rating-icon-half"]
73+ labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
74+ }
75+
76+ onContentHeightChanged: ratingsList.updateRanges();
77+
78+ function updateRanges() {
79+ var baseItem = root.parent;
80+ if (!parentFlickable || !baseItem) {
81+ ratingsList.displayMarginBeginning = 0;
82+ ratingsList.displayMarginEnd = 0;
83+ return;
84+ }
85+
86+ if (parentFlickable.moving) {
87+ // Do not update the range if we are overshooting up or down, since we'll come back
88+ // to the stable position and delete/create items without any reason
89+ if (parentFlickable.contentY < parentFlickable.originY) {
90+ return;
91+ } else if (parentFlickable.contentHeight - parentFlickable.originY > parentFlickable.height &&
92+ parentFlickable.contentY + parentFlickable.height > parentFlickable.contentHeight) {
93+ return;
94+ }
95+ }
96+
97+ // A item view creates its delegates synchronously from
98+ // -displayMarginBeginning
99+ // to
100+ // height + displayMarginEnd
101+ // Around that area it adds the cacheBuffer area where delegates are created async
102+ //
103+ // We adjust displayMarginEnd to be negative so that the range of created delegates matches
104+ // from the beginning of the list to the end of the viewport.
105+ // Ideally we would also use displayMarginBeginning
106+ // so that delegates at the beginning get destroyed but that causes issues with
107+ // listview and is not really necessary to provide the better experience we're after
108+ var itemYOnViewPort = baseItem.y - parentFlickable.contentY;
109+ var displayMarginEnd = -ratingsList.contentHeight + parentFlickable.height - itemYOnViewPort;
110+ displayMarginEnd = -Math.max(-displayMarginEnd, 0);
111+ displayMarginEnd = -Math.min(-displayMarginEnd, ratingsList.contentHeight);
112+ displayMarginEnd = Math.round(displayMarginEnd);
113+
114+ ratingsList.displayMarginEnd = displayMarginEnd;
115 }
116 }
117 }
118
119=== modified file 'qml/Dash/Previews/PreviewWidget.qml'
120--- qml/Dash/Previews/PreviewWidget.qml 2015-11-04 14:57:13 +0000
121+++ qml/Dash/Previews/PreviewWidget.qml 2015-11-27 10:34:17 +0000
122@@ -37,6 +37,9 @@
123 //! Set margins width.
124 property real widgetMargins: units.gu(1)
125
126+ /// The parent (vertical) flickable this widget is in (if any)
127+ property var parentFlickable: null
128+
129 /*! \brief This signal should be emitted when a preview action was triggered.
130 *
131 * \param widgetId, actionId Respective identifiers from widgetData.
132
133=== modified file 'qml/Dash/Previews/PreviewWidgetFactory.qml'
134--- qml/Dash/Previews/PreviewWidgetFactory.qml 2015-11-04 14:57:13 +0000
135+++ qml/Dash/Previews/PreviewWidgetFactory.qml 2015-11-27 10:34:17 +0000
136@@ -43,6 +43,9 @@
137 //! Set margins width.
138 property real widgetMargins: status === Loader.Ready ? item.widgetMargins : units.gu(1)
139
140+ /// The parent (vertical) flickable this widget is in (if any)
141+ property var parentFlickable: null
142+
143 //! Triggered signal forwarded from the widgets.
144 signal triggered(string widgetId, string actionId, var data)
145
146@@ -82,6 +85,7 @@
147 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
148 item.expanded = Qt.binding(function() { return root.expanded } )
149 item.scopeStyle = Qt.binding(function() { return root.scopeStyle } )
150+ item.parentFlickable = Qt.binding(function() { return root.parentFlickable } )
151 }
152
153 Connections {
154
155=== modified file 'tests/qmltests/CMakeLists.txt'
156--- tests/qmltests/CMakeLists.txt 2015-11-06 10:06:58 +0000
157+++ tests/qmltests/CMakeLists.txt 2015-11-27 10:34:17 +0000
158@@ -41,6 +41,7 @@
159 add_unity8_qmltest(Dash/Previews PreviewPayments)
160 add_unity8_qmltest(Dash/Previews PreviewProgress)
161 add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
162+add_unity8_qmltest(Dash/Previews PreviewRatingDisplayCreationRanges)
163 add_unity8_qmltest(Dash/Previews PreviewRatingEdit)
164 add_unity8_qmltest(Dash/Previews PreviewRatingInput)
165 add_unity8_qmltest(Dash/Previews PreviewSharing)
166
167=== modified file 'tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml'
168--- tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml 2015-07-15 15:07:19 +0000
169+++ tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml 2015-11-27 10:34:17 +0000
170@@ -70,9 +70,7 @@
171
172 function test_reviews(data) {
173 previewRatingDisplay.widgetData = data.reviewsModel;
174-
175- var reviewsRepeater = findChild(previewRatingDisplay, "reviewsRepeater");
176- compare(reviewsRepeater.count, data.reviewsModel["reviews"].length);
177+ waitForRendering(previewRatingDisplay);
178
179 for (var i = 0; i < data.reviewsModel["reviews"].length; ++i) {
180 var reviewItem = findChild(previewRatingDisplay, "reviewItem" + i);
181
182=== added file 'tests/qmltests/Dash/Previews/tst_PreviewRatingDisplayCreationRanges.qml'
183--- tests/qmltests/Dash/Previews/tst_PreviewRatingDisplayCreationRanges.qml 1970-01-01 00:00:00 +0000
184+++ tests/qmltests/Dash/Previews/tst_PreviewRatingDisplayCreationRanges.qml 2015-11-27 10:34:17 +0000
185@@ -0,0 +1,94 @@
186+/*
187+ * Copyright 2014,2015 Canonical Ltd.
188+ *
189+ * This program is free software; you can redistribute it and/or modify
190+ * it under the terms of the GNU General Public License as published by
191+ * the Free Software Foundation; version 3.
192+ *
193+ * This program is distributed in the hope that it will be useful,
194+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
195+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
196+ * GNU General Public License for more details.
197+ *
198+ * You should have received a copy of the GNU General Public License
199+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
200+ */
201+
202+import QtQuick 2.4
203+import QtTest 1.0
204+import Ubuntu.Components 1.3
205+import "../../../../qml/Dash/Previews"
206+import Unity.Test 0.1 as UT
207+
208+Flickable {
209+ id: root
210+ width: units.gu(40)
211+ height: units.gu(80)
212+ contentHeight: factory.implicitHeight
213+
214+ property var reviewsEmpty: {
215+ "reviews": [ ]
216+ }
217+
218+ Item {
219+ id: widgetData500
220+ property var reviews: []
221+ }
222+
223+ PreviewWidgetFactory {
224+ id: factory
225+ anchors.fill: parent
226+ widgetType: "reviews"
227+ parentFlickable: root
228+ }
229+
230+ Component.onCompleted: {
231+ for (var i = 0; i < 500; ++i) {
232+ widgetData500.reviews.push({ author: "Some dude", review: "Very cool app" + i });
233+ }
234+ factory.widgetData = widgetData500;
235+ }
236+
237+ UT.UnityTestCase {
238+ name: "PreviewRatingDisplayTest"
239+ when: windowShown
240+
241+ function test_creation_speed() {
242+ factory.parentFlickable = null;
243+ factory.widgetData = reviewsEmpty;
244+ waitForRendering(root);
245+
246+ var start = new Date().getTime();
247+ factory.widgetData = widgetData500;
248+ waitForRendering(root);
249+ var end = new Date().getTime();
250+ var time500 = end - start;
251+
252+ factory.widgetData = reviewsEmpty;
253+ waitForRendering(root);
254+
255+ factory.parentFlickable = root;
256+ start = new Date().getTime();
257+ factory.widgetData = widgetData500;
258+ waitForRendering(root);
259+ end = new Date().getTime();
260+ var timeRanges500 = end - start;
261+
262+ // Measurements show it's usually like 20 times faster
263+ // but we set the range at 8 times fast to make sure it's not an unstable test
264+ verify(timeRanges500 * 8 < time500);
265+ }
266+
267+ function test_check_indexes() {
268+ // Check that item 499 isn't there on startup but if we scroll down
269+ // it will be there
270+ var reviewItem499 = findChild(factory, "reviewItem499");
271+ verify(reviewItem499 === null);
272+
273+ flickToYEnd(root);
274+
275+ var reviewItem499 = findChild(factory, "reviewItem499");
276+ verify(reviewItem499 !== null);
277+ }
278+ }
279+}
280
281=== modified file 'tests/utils/modules/Unity/Test/UnityTestCase.qml'
282--- tests/utils/modules/Unity/Test/UnityTestCase.qml 2015-08-13 09:08:15 +0000
283+++ tests/utils/modules/Unity/Test/UnityTestCase.qml 2015-11-27 10:34:17 +0000
284@@ -239,7 +239,8 @@
285 var x = item.width / 2;
286 var y = item.height - units.gu(1);
287 var toY = units.gu(1);
288- while (i < 5 && !item.atYEnd) {
289+ var maxIterations = 5 + item.contentHeight / item.height;
290+ while (i < maxIterations && !item.atYEnd) {
291 touchFlick(item, x, y, x, toY);
292 tryCompare(item, "moving", false);
293 ++i;

Subscribers

People subscribed via source and target branches