forked from race604/react-native-viewpager
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ViewPagerDataSource.js
132 lines (108 loc) · 3.08 KB
/
ViewPagerDataSource.js
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
'use strict';
//var warning = require('warning');
function defaultGetPageData(
dataBlob: any,
pageID: number | string,
): any {
return dataBlob[pageID];
}
type differType = (data1: any, data2: any) => bool;
type ParamType = {
pageHasChanged: differType;
getPageData: ?typeof defaultGetPageData;
}
class ViewPagerDataSource {
constructor(params: ParamType) {
this._getPageData = params.getPageData || defaultGetPageData;
this._pageHasChanged = params.pageHasChanged;
this.pageIdentities = [];
}
cloneWithPages(
dataBlob: any,
pageIdentities: ?Array<string>,
): ViewPagerDataSource {
var newSource = new ViewPagerDataSource({
getPageData: this._getPageData,
pageHasChanged: this._pageHasChanged,
});
newSource._dataBlob = dataBlob;
if (pageIdentities) {
newSource.pageIdentities = pageIdentities;
} else {
newSource.pageIdentities = Object.keys(dataBlob);
}
newSource._cachedPageCount = newSource.pageIdentities.length;
newSource._calculateDirtyPages(
this._dataBlob,
this.pageIdentities
);
return newSource;
}
getPageCount(): number {
return this._cachedPageCount;
}
/**
* Returns if the row is dirtied and needs to be rerendered
*/
pageShouldUpdate(pageIndex: number): bool {
var needsUpdate = this._dirtyPages[pageIndex];
// warning(needsUpdate !== undefined,
// 'missing dirtyBit for section, page: ' + pageIndex);
return needsUpdate;
}
/**
* Gets the data required to render the page
*/
getPageData(pageIndex: number): any {
if (!this.getPageData) {
return null;
}
var pageID = this.pageIdentities[pageIndex];
// warning(pageID !== undefined,
// 'renderPage called on invalid section: ' + pageID);
return this._getPageData(this._dataBlob,pageID);
}
/**
* Private members and methods.
*/
_getPageData: typeof defaultGetPageData;
_pageHasChanged: differType;
_dataBlob: any;
_dirtyPages: Array<bool>;
_cachedRowCount: number;
pageIdentities: Array<string>;
_calculateDirtyPages(
prevDataBlob: any,
prevPageIDs: Array<string>,
): void {
// construct a hashmap of the existing (old) id arrays
var prevPagesHash = keyedDictionaryFromArray(prevPageIDs);
this._dirtyPages = [];
var dirty;
for (var sIndex = 0; sIndex < this.pageIdentities.length; sIndex++) {
var pageID = this.pageIdentities[sIndex];
dirty = !prevPagesHash[pageID];
var pageHasChanged = this._pageHasChanged
if (!dirty && pageHasChanged) {
dirty = pageHasChanged(
this._getPageData(prevDataBlob, pageID),
this._getPageData(this._dataBlob, pageID)
);
}
this._dirtyPages.push(!!dirty);
}
}
}
function keyedDictionaryFromArray(arr) {
if (arr.length === 0) {
return {};
}
var result = {};
for (var ii = 0; ii < arr.length; ii++) {
var key = arr[ii];
// warning(!result[key], 'Value appears more than once in array: ' + key);
result[key] = true;
}
return result;
}
module.exports = ViewPagerDataSource;