@@ -30,6 +30,7 @@ public class FirestoreInfiniteArray<T> extends ObservableSnapshotArray<T> {
30
30
31
31
private List <Page > mPages = new ArrayList <>();
32
32
33
+ // TODO: I am not using reverse query at all
33
34
public FirestoreInfiniteArray (Query forwardQuery , Query reverseQuery , SnapshotParser <T > parser ) {
34
35
super (parser );
35
36
@@ -59,13 +60,20 @@ public int getPagesLoaded() {
59
60
return count ;
60
61
}
61
62
62
- public void unloadPage () {
63
+ public void unloadTopPage () {
63
64
// Find first loaded page
64
65
int firstLoaded = findFirstOfState (PageState .LOADED );
65
66
if (firstLoaded != -1 ) {
66
67
mPages .get (firstLoaded ).unload ();
67
- Log .d (TAG , "unloadPage: unloading page " + firstLoaded );
68
- Log .d (TAG , "unloadPage: new size = " + size ());
68
+ Log .d (TAG , "UNLOADING " + firstLoaded );
69
+ }
70
+ }
71
+
72
+ public void unloadBottomPage () {
73
+ int lastLoaded = findLastOfState (PageState .LOADED );
74
+ if (lastLoaded != -1 ) {
75
+ mPages .get (lastLoaded ).unload ();
76
+ Log .d (TAG , "UNLOADING " + lastLoaded );
69
77
}
70
78
}
71
79
@@ -74,37 +82,54 @@ public void loadPrevPage() {
74
82
return ;
75
83
}
76
84
77
- // Find first unloaded page
78
- int lastUnloaded = findLastOfState (PageState .UNLOADED );
79
- if (lastUnloaded != -1 ) {
80
- Log .d (TAG , "loadPrevPage: loading " + lastUnloaded );
81
- mPages .get (lastUnloaded ).load ();
82
- }
85
+ // Load the last UNLOADED page before the middle "core" of LOADED pages
86
+ int firstLoaded = findFirstOfState (PageState .LOADED );
87
+ int lastUnloadedBefore = findLastOfState (PageState .UNLOADED , firstLoaded );
83
88
84
- // TODO: What if we have to change the starting position of the next page
89
+ if (lastUnloadedBefore != -1 ) {
90
+ Log .d (TAG , "RELOADING " + lastUnloadedBefore );
91
+ mPages .get (lastUnloadedBefore ).load ();
92
+ }
85
93
}
86
94
87
95
public void loadNextPage () {
88
96
if (countState (PageState .LOADING ) > 0 ) {
89
97
return ;
90
98
}
91
99
92
- Page lastPage = getLastPage ();
93
- DocumentSnapshot lastSnapshot = lastPage .getLast ();
100
+ // There are two cases here
101
+ // 1. Need to load a whole new page
102
+ // 2. Need to load an UNLOADED bottom page
94
103
95
- if (lastSnapshot == null ) {
96
- Log .w (TAG , "Skipping load because last snapshot is null!" );
97
- return ;
98
- }
104
+ int lastLoaded = findLastOfState (PageState .LOADED );
99
105
100
- Query nextQuery = queryAfter (lastSnapshot );
101
- Log .d (TAG , "loadNextPage: loading page " + mPages .size ());
106
+ if (lastLoaded == mPages .size () - 1 ) {
107
+ // Case 1: Load a new page at the bottom
108
+ Page lastPage = getLastPage ();
109
+ DocumentSnapshot lastSnapshot = lastPage .getLast ();
110
+
111
+ // Reached the end, no more items to show
112
+ if (lastSnapshot == null ) {
113
+ return ;
114
+ }
115
+
116
+ Query nextQuery = queryAfter (lastSnapshot );
117
+ Log .d (TAG , "LOADING " + mPages .size ());
118
+
119
+ // Add and start loading
120
+ int nextPageIndex = mPages .size ();
121
+ Page nextPage = new Page (nextPageIndex , nextQuery );
122
+ mPages .add (nextPage );
123
+ nextPage .load ();
124
+ } else {
125
+ // Case 2: Need to load a previously unloaded page
126
+ // Find the first UNLOADED page after the middle "core" of loaded pages
127
+ int firstUnloadedAfter = findFirstOfState (PageState .UNLOADED , lastLoaded );
128
+
129
+ Log .d (TAG , "RELOADING " + firstUnloadedAfter );
130
+ mPages .get (firstUnloadedAfter ).load ();
131
+ }
102
132
103
- // Add and start loading
104
- int nextPageIndex = mPages .size ();
105
- Page nextPage = new Page (nextPageIndex , nextQuery );
106
- mPages .add (nextPage );
107
- nextPage .load ();
108
133
}
109
134
110
135
private void onPageLoaded (int index , int size ) {
@@ -126,7 +151,11 @@ private void onPageUnloaded(int index, int size) {
126
151
}
127
152
128
153
private int findFirstOfState (PageState state ) {
129
- for (int i = 0 ; i < mPages .size (); i ++) {
154
+ return findFirstOfState (state , 0 );
155
+ }
156
+
157
+ private int findFirstOfState (PageState state , int startingAt ) {
158
+ for (int i = startingAt ; i < mPages .size (); i ++) {
130
159
Page page = mPages .get (i );
131
160
if (page .getState () == state ) {
132
161
return i ;
@@ -137,7 +166,11 @@ private int findFirstOfState(PageState state) {
137
166
}
138
167
139
168
private int findLastOfState (PageState state ) {
140
- for (int i = mPages .size () - 1 ; i >= 0 ; i --) {
169
+ return findLastOfState (state , mPages .size () - 1 );
170
+ }
171
+
172
+ private int findLastOfState (PageState state , int endingAt ) {
173
+ for (int i = endingAt ; i >= 0 ; i --) {
141
174
Page page = mPages .get (i );
142
175
if (page .getState () == state ) {
143
176
return i ;
@@ -178,9 +211,8 @@ public DocumentSnapshot getSnapshot(int index) {
178
211
remaining -= page .size ();
179
212
}
180
213
181
- // TODO
182
- Log .e (TAG , "Requested bad index: " + index );
183
- return null ;
214
+ throw new IllegalArgumentException (
215
+ "Requested non-existent index: " + index + ", size=" + size ());
184
216
}
185
217
186
218
@ NonNull
@@ -222,11 +254,10 @@ private enum PageState {
222
254
223
255
private class Page implements OnCompleteListener <QuerySnapshot > {
224
256
225
- // TODO: state
226
-
257
+ // TODO: Does the Page really need to track its own index?
227
258
private PageState mState ;
228
- public final int mIndex ;
229
- public final Query mQuery ;
259
+ private final int mIndex ;
260
+ private final Query mQuery ;
230
261
231
262
private DocumentSnapshot mFirstInPage ;
232
263
@@ -262,12 +293,11 @@ public void onComplete(@NonNull Task<QuerySnapshot> task) {
262
293
Log .w (TAG , "Failed to get page" , task .getException ());
263
294
}
264
295
265
- Log .d (TAG , "pageLoaded: " + mIndex );
296
+ Log .d (TAG , "LOADED " + mIndex );
266
297
267
298
// Add all snapshots
268
299
mSnapshots .addAll (task .getResult ().getDocuments ());
269
300
270
- // TODO
271
301
// Range insert
272
302
onPageLoaded (mIndex , mSnapshots .size ());
273
303
}
0 commit comments