Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-native-largelist

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-largelist - npm Package Compare versions

Comparing version 0.0.6 to 1.0.0

954

largelist/LargeList.js

@@ -24,2 +24,3 @@ /*

import { LargeListSection } from "./LargeListSection";
import { TableView } from "../tableview";

@@ -42,4 +43,4 @@ interface Size {

interface Range {
top:number;
bottom:number;
top: number,
bottom: number
}

@@ -59,3 +60,3 @@

bounces: PropTypes.bool,
onTopRefresh: PropTypes.func,
onRefresh: PropTypes.func,

@@ -67,7 +68,14 @@ safeMargin: PropTypes.number,

scrollEventThrottle: PropTypes.number,
onScroll:PropTypes.func,
onScroll: PropTypes.func,
speedLevel1: PropTypes.number,
speedLevel2: PropTypes.number,
nativeOptimize: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
onIndexPathDidEnterSafeArea: PropTypes.func,
onIndexPathDidLeaveSafeArea: PropTypes.func,
onSectionDidHangOnTop: PropTypes.func
// onIndexPathDidAppear: PropTypes.func,

@@ -81,60 +89,79 @@ // onIndexPathDidDisappear: PropTypes.func,

numberOfRowsInSection: section => 0,
renderSection: () => <View style={{ flex: 1 }} />,
renderSection: () => null,
heightForSection: section => 0,
renderHeader: null,
renderFooter: null,
renderHeader: () => null,
renderFooter: () => null,
bounces: true,
onRefresh: () => {},
nativeOptimize: false,
safeMargin: 600,
dynamicMargin: 500,
scrollEventThrottle: Platform.OS==="ios"?16:32
scrollEventThrottle: Platform.OS === "ios" ? 16 : 32,
speedLevel1: Platform.OS === "ios" ? 4 : 4,
speedLevel2: Platform.OS === "ios" ? 10 : 10,
showsVerticalScrollIndicator: true,
onSectionDidHangOnTop: () => {}
};
sections: Element[]=[];
workSectionRefs: LargeListSection[]=[];
freeSectionRefs: LargeListSection[]=[];
sections: Element[] = [];
workSectionRefs: LargeListSection[] = [];
freeSectionRefs: LargeListSection[] = [];
cells: Element[]=[]; //所有的Cell 的元素
cells: Element[] = []; //所有的Cell 的元素
workRefs: LargeListCell[] = []; //正在显示的Cell的引用
freeRefs: LargeListCell[] = []; //空闲的Cell的引用
workRefs: LargeListCell[]=[]; //正在显示的Cell的引用
freeRefs: LargeListCell[]=[]; //空闲的Cell的引用
size: Size = null; //LargeList宽高
contentOffset: Offset = { x: 0, y: 0 }; //LargeList偏移
size: Size; //LargeList宽高
contentOffset: Offset={ x: 0, y: 0 }; //LargeList偏移
safeArea: Range = { top: 0, bottom: 0 }; //safe area range
topIndexPath: IndexPath = { section: 0, row: 0 }; //safe area中最顶部的IndexPath
bottomIndexPath: IndexPath = { section: 0, row: 0 }; //safe area中最底部的IndexPath
contentSize: Size = { width: 0, height: 0 };
lastScrollTime: number = 0;
safeArea: Range={top:0, bottom:0}; //safe area range
topIndexPath: IndexPath={section:0, row:0}; //safe area中最顶部的IndexPath
bottomIndexPath: IndexPath={section:0, row:0}; //safe area中最底部的IndexPath
contentSize:Size={width:0,height:0};
lastScrollTime:number=0;
currentSection:number=0;
currentSection: number = 0;
currentSectionRef: LargeListSection;
nextSection: number=0;
headerHeight: number;
footerHeight: number;
sizeConfirmed: boolean=false;
forceTimer: number=0;
created: boolean=false;
keyForCreating: number=0;
headerHeight: number = null;
footerHeight: number = null;
sizeConfirmed: boolean = false;
keyForCreating: number = 0;
minCellHeight: number = 40;
minSectionHeight: number = 40;
scrollViewRef: ScrollView;
scrollViewRef: ScrollView | TableView;
native: boolean = false;
constructor(props) {
super(props);
for (let i=0;i<this.props.numberOfSections;++i) {
if (this.minSectionHeight > this.props.heightForSection(i)) {
this.initVar();
}
initVar() {
this.safeArea = { top: 0, bottom: 0 };
this.topIndexPath = { section: 0, row: -2 };
this.bottomIndexPath = { section: 0, row: -2 };
this.contentSize = { width: 0, height: 0 };
this.lastScrollTime = 0;
this.currentSection = 0;
this.keyForCreating = 0;
this.minCellHeight = 40;
this.minSectionHeight = 40;
this.native = Platform.OS === "ios" && this.props.nativeOptimize && TableView;
for (let i = 0; i < this.props.numberOfSections; ++i) {
if (
this.minSectionHeight > this.props.heightForSection(i) &&
this.props.heightForSection(i) > 10
) {
this.minSectionHeight = this.props.heightForSection(i);
}
this.contentSize.height += this.props.heightForSection(i);
for (let j=0;j<this.props.numberOfRowsInSection(i);++j){
if (this.minCellHeight > this.props.heightForCell(i,j)) {
this.minCellHeight = this.props.heightForCell(i,j);
for (let j = 0; j < this.props.numberOfRowsInSection(i); ++j) {
if (
this.minCellHeight > this.props.heightForCell(i, j) &&
this.props.heightForCell(i, j) > 10
) {
this.minCellHeight = this.props.heightForCell(i, j);
}
this.contentSize.height += this.props.heightForCell(i,j);
this.contentSize.height += this.props.heightForCell(i, j);
}

@@ -145,40 +172,58 @@ }

initCells() {
this.contentSize.height+=this.headerHeight;
this.contentSize.height+=this.footerHeight;
this.contentSize.height += this.headerHeight;
this.contentSize.height += this.footerHeight;
let sumHeight: number = this.headerHeight;
let section;
let row=0;
for (section=0; section<this.props.numberOfSections && sumHeight < this.size.height + this.props.safeMargin; ++section) {
if (row==0) {
this.sections.push(this._createSection(section, sumHeight, this.workSectionRefs));
let row = 0;
for (
section = 0;
section < this.props.numberOfSections &&
sumHeight < this.size.height + this.props.safeMargin;
++section
) {
if (row === 0) {
this.sections.push(
this._createSection(section, sumHeight, this.workSectionRefs)
);
sumHeight += this.props.heightForSection(section);
}
if (this.props.numberOfRowsInSection(section) == 0) {
if (this.props.numberOfRowsInSection(section) === 0) {
this.safeArea.bottom = sumHeight;
this.bottomIndexPath = {section:section,row:row};
this.bottomIndexPath = { section: section, row: row };
continue;
}
for (row=0;
row < this.props.numberOfRowsInSection(section);
++row
) {
for (row = 0; row < this.props.numberOfRowsInSection(section); ++row) {
if (sumHeight < this.size.height + this.props.safeMargin) {
this.cells.push(this._createCell(section, row, sumHeight, this.workRefs));
this.cells.push(
this._createCell(section, row, sumHeight, this.workRefs)
);
sumHeight += this.props.heightForCell(section, row);
this.safeArea.bottom = sumHeight;
this.bottomIndexPath = {section:section,row:row};
this.bottomIndexPath = { section: section, row: row };
}
}
row=0;
row = 0;
}
if (sumHeight<this.size.height+this.props.safeMargin) {
if (sumHeight < this.size.height + this.props.safeMargin) {
this.safeArea.bottom = sumHeight;
this.bottomIndexPath = {section:section,row:row};
this.bottomIndexPath = { section: section, row: row };
return;
}
for (let i = 0; i < Math.floor(this.props.safeMargin/this.minSectionHeight)+2; i++) {
this.sections.push(this._createSection(section + i + 1, -10000, this.freeSectionRefs));
for (
let i = 0;
i < Math.floor(this.props.safeMargin / this.minSectionHeight) + 2;
i++
) {
this.sections.push(
this._createSection(section + i + 1, -10000, this.freeSectionRefs)
);
}
for (let i = 0; i < Math.floor(this.props.safeMargin/this.minCellHeight)+2; i++) {
this.cells.push(this._createCell(section, row + i, -10000, this.freeRefs));
for (
let i = 0;
i < Math.floor(this.props.safeMargin / this.minCellHeight) + 2;
i++
) {
this.cells.push(
this._createCell(section, row + i, -10000, this.freeRefs)
);
}

@@ -188,60 +233,112 @@ }

render() {
if (this.native)
return (
<TableView ref={ref => (this.scrollViewRef = ref)} {...this.props} />
);
return (
<View {...this.props}>
<ScrollView
ref = {ref=>this.scrollViewRef=ref}
bounces={this.props.bounces}
refreshControl={this.props.refreshing!==undefined && <RefreshControl refreshing={this.props.refreshing} onRefresh={this.props.onRefresh}/>}
contentContainerStyle={{ alignSelf: "stretch", height: this.contentSize.height }}
onLayout={this._onLayout.bind(this)}
style={{flex:1}}
scrollEventThrottle={this.props.scrollEventThrottle}
onScroll={this._onScroll.bind(this)}
onMomentumScrollEnd={this._onMomentumScrollEnd.bind(this)}
style={{ flex: 1 }}
bounces={false}
contentContainerStyle={{ flex: 1 }}
>
<View style={{position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed?0:-10000}} onLayout={this._onHeaderLayout.bind(this)}>
{this.props.renderHeader()}
</View>
{this.sections.map(item=>item)}
{this.cells.map(item => item)}
<View style={{position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed?this.contentSize.height-this.footerHeight:-10000}} onLayout={this._onFooterLayout.bind(this)}>
{this.props.renderFooter()}
</View>
<ScrollView
ref={ref => (this.scrollViewRef = ref)}
bounces={this.props.bounces}
refreshControl={
this.props.onRefresh !== undefined
? <RefreshControl
refreshing={this.props.refreshing}
onRefresh={this.props.onRefresh}
/>
: null
}
contentContainerStyle={{
alignSelf: "stretch",
height: this.contentSize.height
}}
onLayout={this._onLayout.bind(this)}
style={{ flex: 1 }}
scrollEventThrottle={this.props.scrollEventThrottle}
onScroll={this._onScroll.bind(this)}
onMomentumScrollEnd={this._onMomentumScrollEnd.bind(this)}
showsVerticalScrollIndicator={
this.props.showsVerticalScrollIndicator
}
>
<View
style={{
position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed ? 0 : -10000
}}
onLayout={this._onHeaderLayout.bind(this)}
>
{this.props.renderHeader()}
</View>
{this.sections.map(item => item)}
{this.cells.map(item => item)}
<View
style={{
position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed
? this.contentSize.height - this.footerHeight
: -10000
}}
onLayout={this._onFooterLayout.bind(this)}
>
{this.props.renderFooter()}
</View>
</ScrollView>
<LargeListSection
style={{
position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed ? 0 : -10000,
height: this.props.heightForSection(0)
}}
section={0}
renderSection={this.props.renderSection}
ref={reference => (this.currentSectionRef = reference)}
numberOfSections={this.props.numberOfSections}
/>
</ScrollView>
<LargeListSection style={{
</View>
);
}
_createSection(section: number, top: number, refs: LargeListSection[]) {
return (
<LargeListSection
ref={reference => reference && refs.push(reference)}
key={this.keyForCreating++}
style={{
position: "absolute",
left: 0,
right: 0,
top: this.sizeConfirmed?0:-10000,
height: this.props.heightForSection(0),
zIndex:99999999
}} section={0} renderSection={this.props.renderSection} ref={reference=>this.currentSectionRef=reference}/>
</View>
top: top,
height:
refs == this.workSectionRefs
? this.props.heightForSection(section)
: 0
}}
numberOfSections={this.props.numberOfSections}
section={section}
renderSection={this.props.renderSection}
/>
);
}
_createSection(section: number, top:number, refs) {
return <LargeListSection
ref={reference=>reference&&refs.push(reference)}
key={this.keyForCreating++}
style={{
position: "absolute",
left: 0,
right: 0,
top: top,
height: this.props.heightForSection(section)
}}
section={section}
renderSection={this.props.renderSection}
/>
}
_createCell(section: number, row: number, top:number, refs) {
let height = this.props.heightForCell(section, row);
_createCell(
section: number,
row: number,
top: number,
refs: LargeListCell[]
) {
let height =
refs === this.workRefs ? this.props.heightForCell(section, row) : 0;
return (

@@ -259,3 +356,5 @@ <LargeListCell

renderCell={this.props.renderCell}
indexPath={{section:section,row:row}}
indexPath={{ section: section, row: row }}
numberOfSections={this.props.numberOfSections}
numberOfRowsInSection={this.props.numberOfRowsInSection}
/>

@@ -265,3 +364,3 @@ );

_onMomentumScrollEnd(){
_onMomentumScrollEnd() {
this.lastScrollTime = 0;

@@ -273,199 +372,365 @@ this._forceUpdate();

let offset: Offset = e.nativeEvent.contentOffset;
let now:number = new Date().getTime();
let speed:number = 0;
let topMargin:number=this.props.safeMargin;
let bottomMargin:number=this.props.safeMargin;
let distance = Math.abs(offset.y - this.contentOffset.y);
// if (distance < this.minCellHeight) {
// this._exchangeSection(offset);
// return;
// }
let now: number = new Date().getTime();
let speed: number = 0;
let topMargin: number = this.props.safeMargin;
let bottomMargin: number = this.props.safeMargin;
if (this.lastScrollTime > 0) {
speed = Math.abs(offset.y-this.contentOffset.y)/(now-this.lastScrollTime);
} else if (Math.abs(offset.y-this.contentOffset.y)>this.props.safeMargin) {
speed = distance / (now - this.lastScrollTime);
} else if (distance > this.props.safeMargin) {
speed = 5;
}
this.lastScrollTime = now;
let forceReload = offset.y<topMargin
|| offset.y+this.size.height+bottomMargin>this.contentSize.height
|| speed<4;
let reloadType: number = 0;
if (
offset.y < topMargin ||
offset.y + this.size.height + bottomMargin > this.contentSize.height ||
speed < this.props.speedLevel1
) {
reloadType = 0;
} else {
reloadType = 1;
}
if (offset.y > this.contentOffset.y) {
if (speed>=4) {
topMargin = this.props.safeMargin-this.props.dynamicMargin;
if (offset.y >= this.contentOffset.y) {
if (reloadType === 1) {
topMargin = this.props.safeMargin - this.props.dynamicMargin;
bottomMargin = this.props.safeMargin + this.props.dynamicMargin;
}
this.workSectionRefs.forEach(section=>{
if (section.top+section.height < offset.y - topMargin) {
this.freeSectionRefs.push(section);
if (this.safeArea.top<section.top+section.height) {
this.safeArea.top = section.top+section.height;
}
//下滑 处理上边
while (
this.safeArea.top < offset.y - topMargin &&
this.safeArea.top > this.headerHeight
) {
let lastIndexPath = this.topIndexPath;
this.topIndexPath = this._nextIndexPathWithIndexPath(this.topIndexPath);
if (lastIndexPath.row === -1) {
this.safeArea.top += this.props.heightForSection(
lastIndexPath.section
);
//Section离开事件
} else {
this.safeArea.top += this.props.heightForCell(
lastIndexPath.section,
lastIndexPath.row
);
this.props.onIndexPathDidLeaveSafeArea &&
this.props.onIndexPathDidLeaveSafeArea({
section: lastIndexPath.section,
row: lastIndexPath.row
});
}
}
//下滑 移动无用Section和Cell
this.workSectionRefs.forEach(item => {
if (item.section < this.topIndexPath.section) {
this.freeSectionRefs.splice(0, 0, item);
}
});
this.freeSectionRefs.forEach(section=>{
this.freeSectionRefs.forEach(section => {
let index = this.workSectionRefs.indexOf(section);
this.workSectionRefs.splice(index,index>-1?1:0);
this.workSectionRefs.splice(index, index > -1 ? 1 : 0);
});
this.workRefs.forEach(cell=>{
if (cell.top+cell.height < offset.y - topMargin) {
this.freeRefs.push(cell);
this.props.onIndexPathDidLeaveSafeArea && this.props.onIndexPathDidLeaveSafeArea({section:cell.indexPath.section,row:cell.indexPath.row});
if (this._compareIndexPath(this.topIndexPath, cell.indexPath) <= 0){
this.topIndexPath = this._nextIndexPathWithIndexPath(cell.indexPath);
}
if (this.safeArea.top<cell.top+cell.height) {
this.safeArea.top = cell.top+cell.height;
}
this.workRefs.forEach(item => {
if (this._compareIndexPath(item.indexPath, this.topIndexPath) < 0) {
this.freeRefs.splice(0, 0, item);
}
});
this.freeRefs.forEach(cell=>{
this.freeRefs.forEach(cell => {
let index = this.workRefs.indexOf(cell);
this.workRefs.splice(index,index>-1?1:0);
this.workRefs.splice(index, index > -1 ? 1 : 0);
});
while (this.safeArea.bottom < this.contentSize.height-this.footerHeight && this.safeArea.bottom<offset.y+this.size.height+bottomMargin) {
this.bottomIndexPath.row++;
if (this.bottomIndexPath.row>=this.props.numberOfRowsInSection(this.bottomIndexPath.section)) {
this.bottomIndexPath.section++;
this.bottomIndexPath.row=-1;
//下滑 处理下边
while (
this.safeArea.bottom < offset.y + this.size.height + bottomMargin &&
this.safeArea.bottom < this.contentSize.height - this.footerHeight
) {
let nextIndexPath = this._nextIndexPathWithIndexPath(
this.bottomIndexPath
);
if (nextIndexPath.section >= this.props.numberOfSections) {
break;
}
this.bottomIndexPath = nextIndexPath;
if (this.bottomIndexPath.row === -1) {
let reference = this.freeSectionRefs.pop();
if (!reference){
this.created = true;
this.sections.push(this._createSection(this.bottomIndexPath.section,this.safeArea.bottom,this.workSectionRefs));
if (!reference) {
this.sections.push(
this._createSection(
this.bottomIndexPath.section,
this.safeArea.bottom,
this.workSectionRefs
)
);
} else {
reference.updateToSection(this.bottomIndexPath.section,this.safeArea.bottom,this.props.heightForSection(this.bottomIndexPath.section),true);
reference.updateToSection(
this.bottomIndexPath.section,
this.safeArea.bottom,
this.props.heightForSection(this.bottomIndexPath.section),
true
);
this.workSectionRefs.push(reference);
}
this.safeArea.bottom += this.props.heightForSection(this.bottomIndexPath.section);
continue;
}
let reference = this.freeRefs.pop();
if (!reference) {
this.cells.push(this._createCell(this.bottomIndexPath.section, this.bottomIndexPath.row, this.safeArea.bottom,this.workRefs));
this.created = true;
this.safeArea.bottom += this.props.heightForSection(
this.bottomIndexPath.section
);
} else {
reference.updateToIndexPath(this.bottomIndexPath, this.safeArea.bottom,this.props.heightForCell(this.bottomIndexPath.section,this.bottomIndexPath.row),false);
this.workRefs.push(reference);
let reference = this.freeRefs.pop();
if (!reference) {
reference = this._topCellRef();
this.topIndexPath = this._nextIndexPathWithIndexPath(
reference.indexPath
);
this.safeArea.top = reference.top + reference.height;
} else {
this.workRefs.push(reference);
}
let nextHeight = this.props.heightForCell(
this.bottomIndexPath.section,
this.bottomIndexPath.row
);
reference.updateToIndexPath(
this.bottomIndexPath,
this.safeArea.bottom,
nextHeight
);
this.props.onIndexPathDidEnterSafeArea &&
this.props.onIndexPathDidEnterSafeArea({
section: this.bottomIndexPath.section,
row: this.bottomIndexPath.row
});
this.safeArea.bottom += nextHeight;
}
this.props.onIndexPathDidEnterSafeArea && this.props.onIndexPathDidEnterSafeArea({section:this.bottomIndexPath.section,row:this.bottomIndexPath.row});
this.safeArea.bottom += this.props.heightForCell(this.bottomIndexPath.section,this.bottomIndexPath.row);
}
} else {
if (speed>=4) {
topMargin = this.props.safeMargin+this.props.dynamicMargin;
if (reloadType === 1) {
topMargin = this.props.safeMargin + this.props.dynamicMargin;
bottomMargin = this.props.safeMargin - this.props.dynamicMargin;
}
this.workSectionRefs.forEach(section=>{
if (section.top > offset.y + this.size.height + bottomMargin) {
this.freeSectionRefs.push(section);
if (this.safeArea.bottom>section.top) {
this.safeArea.bottom = section.top;
}
//上滑,处理下边
while (
this.safeArea.bottom >
offset.y + this.size.height + bottomMargin
) {
let lastIndexPath = this.bottomIndexPath;
this.bottomIndexPath = this._previousIndexPathWithIndexPath(
this.bottomIndexPath
);
if (lastIndexPath.row === -1) {
this.safeArea.bottom -= this.props.heightForSection(
lastIndexPath.section
);
//Section离开事件
} else {
this.safeArea.bottom -= this.props.heightForCell(
lastIndexPath.section,
lastIndexPath.row
);
this.props.onIndexPathDidLeaveSafeArea &&
this.props.onIndexPathDidLeaveSafeArea({
section: lastIndexPath.section,
row: lastIndexPath.row
});
}
}
//移动Cell
this.workSectionRefs.forEach(item => {
if (item.section > this.bottomIndexPath.section) {
this.freeSectionRefs.splice(0, 0, item);
}
});
this.freeSectionRefs.forEach(section=>{
this.freeSectionRefs.forEach(section => {
let index = this.workSectionRefs.indexOf(section);
this.workSectionRefs.splice(index,index>-1?1:0);
this.workSectionRefs.splice(index, index > -1 ? 1 : 0);
});
this.workRefs.forEach(cell=>{
if (cell.top> offset.y+this.size.height + bottomMargin) {
this.freeRefs.push(cell);
this.props.onIndexPathDidLeaveSafeArea && this.props.onIndexPathDidLeaveSafeArea({section:cell.indexPath.section,row:cell.indexPath.row});
if (this._compareIndexPath(this.bottomIndexPath,cell.indexPath)>=0) {
this.bottomIndexPath = this._previousIndexPathWithIndexPath(cell.indexPath);
}
if (this.safeArea.bottom>cell.top) {
this.safeArea.bottom = cell.top;
}
this.workRefs.forEach(item => {
if (this._compareIndexPath(item.indexPath, this.bottomIndexPath) > 0) {
this.freeRefs.splice(0, 0, item);
}
});
this.freeRefs.forEach(cell=>{
this.freeRefs.forEach(cell => {
let index = this.workRefs.indexOf(cell);
this.workRefs.splice(index,index>-1?1:0);
this.workRefs.splice(index, index > -1 ? 1 : 0);
});
while (this.safeArea.top>this.headerHeight && this.safeArea.top>offset.y-topMargin) {
this.topIndexPath.row--;
if (this.topIndexPath.row==-1) {
//上滑,处理上边
while (
this.safeArea.top > offset.y - topMargin &&
this.safeArea.top > this.headerHeight
) {
let nextIndexPath = this._previousIndexPathWithIndexPath(
this.topIndexPath
);
if (nextIndexPath.section < 0) {
break;
}
this.topIndexPath = nextIndexPath;
if (this.topIndexPath.row === -1) {
this.safeArea.top -= this.props.heightForSection(
this.topIndexPath.section
);
let reference = this.freeSectionRefs.pop();
if (!reference){
this.created = true;
this.sections.push(this._createSection(this.topIndexPath.section,this.safeArea.top-this.props.heightForSection(this.topIndexPath.section),this.workSectionRefs));
if (!reference) {
this.sections.push(
this._createSection(
this.topIndexPath.section,
this.safeArea.top,
this.workSectionRefs
)
);
} else {
reference.updateToSection(this.topIndexPath.section,this.safeArea.top-this.props.heightForSection(this.topIndexPath.section),this.props.heightForSection(this.topIndexPath.section),true);
reference.updateToSection(
this.topIndexPath.section,
this.safeArea.top,
this.props.heightForSection(this.topIndexPath.section),
true
);
this.workSectionRefs.push(reference);
}
this.safeArea.top -= this.props.heightForSection(this.topIndexPath.section);
continue;
}
if (this.topIndexPath.row==-2) {
this.topIndexPath.section--;
this.topIndexPath.row = this.props.numberOfRowsInSection(this.topIndexPath.section);
continue;
}
let reference = this.freeRefs.pop();
if (!reference) {
this.created = true;
this.cells.push(this._createCell(this.topIndexPath.section, this.topIndexPath.row, this.safeArea.top-this.props.heightForCell(this.topIndexPath.section,this.topIndexPath.row),this.workRefs));
} else {
reference.updateToIndexPath(this.topIndexPath, this.safeArea.top-this.props.heightForCell(this.topIndexPath.section,this.topIndexPath.row),this.props.heightForCell(this.topIndexPath.section,this.topIndexPath.row),false);
this.workRefs.push(reference);
this.safeArea.top -= this.props.heightForCell(
this.topIndexPath.section,
this.topIndexPath.row
);
let reference = this.freeRefs.pop();
if (!reference) {
reference = this._bottomCellRef();
this.bottomIndexPath = this._previousIndexPathWithIndexPath(
reference.indexPath
);
this.safeArea.bottom = reference.top;
} else {
this.workRefs.push(reference);
}
let nextHeight = this.props.heightForCell(
this.topIndexPath.section,
this.topIndexPath.row
);
reference.updateToIndexPath(
this.topIndexPath,
this.safeArea.top,
nextHeight
);
this.props.onIndexPathDidEnterSafeArea &&
this.props.onIndexPathDidEnterSafeArea({
section: this.topIndexPath.section,
row: this.topIndexPath.row
});
}
this.props.onIndexPathDidEnterSafeArea && this.props.onIndexPathDidEnterSafeArea({section:this.topIndexPath.section,row:this.topIndexPath.row});
this.safeArea.top -= this.props.heightForCell(this.topIndexPath.section,this.topIndexPath.row);
}
}
this._exchangeSection(offset);
this.freeRefs.forEach(cell => {
if (cell.top !== -10000)
cell.updateToIndexPath(cell.indexPath, -10000, cell.height);
});
this.freeSectionRefs.forEach(section => {
if (section.top !== -10000)
section.updateToSection(section.section, -10000, section.height, false);
});
switch (reloadType) {
case 0:
this._forceUpdate();
break;
default:
this._positionUpdate();
break;
}
this.contentOffset = offset;
this.props.onScroll && this.props.onScroll(e);
}
_exchangeSection(offset: Offset) {
let exchanging = false;
this.workSectionRefs.forEach(item=>{
if (this.currentSection == item.section-1 && offset.y<item.top && item.top < this.currentSectionRef.height+offset.y) {
// this.nextSection=item.section;
exchanging=true;
this.currentSectionRef.updateToSection(this.currentSection,item.top-offset.y-this.currentSectionRef.height,this.currentSectionRef.height,false);
this.workSectionRefs.forEach(item => {
if (
this.currentSection === item.section - 1 &&
offset.y <= item.top &&
item.top <= this.currentSectionRef.height + offset.y
) {
exchanging = true;
this.currentSectionRef.updateToSection(
this.currentSection,
item.top - offset.y - this.currentSectionRef.height,
this.currentSectionRef.height,
false
);
}
});
if (!exchanging) {
this.workSectionRefs.forEach(item=>{
if (this.currentSection!=item.section && item.top<=offset.y && item.top+item.height>offset.y) {
this.workSectionRefs.forEach(item => {
if (
this.currentSection != item.section &&
item.top <= offset.y &&
item.top + item.height >= offset.y
) {
this.currentSection = item.section;
this.currentSectionRef.updateToSection(this.currentSection,0,this.props.heightForSection(this.currentSection),false);
this.currentSectionRef.updateToSection(
this.currentSection,
0,
this.props.heightForSection(this.currentSection),
true
);
this.props.onSectionDidHangOnTop(item.section);
}
})
this.workRefs.forEach(item=>{
if (this.currentSection!=item.indexPath.section && item.top<=offset.y && item.top+item.height>offset.y) {
});
this.workRefs.forEach(item => {
if (
this.currentSection != item.indexPath.section &&
item.top <= offset.y &&
item.top + item.height >= offset.y
) {
this.currentSection = item.indexPath.section;
this.currentSectionRef.updateToSection(this.currentSection,0,this.props.heightForSection(this.currentSection),false);
this.currentSectionRef.updateToSection(
this.currentSection,
0,
this.props.heightForSection(this.currentSection),
true
);
this.props.onSectionDidHangOnTop(item.indexPath.section);
}
})
});
if (this.currentSectionRef.top !== 0) {
this.currentSectionRef.updateToSection(
this.currentSection,
0,
this.props.heightForSection(this.currentSection),
false
);
}
}
if (offset.y<this.headerHeight) {
this.currentSectionRef.updateToSection(this.currentSection,-10000,this.props.heightForSection(this.currentSection),false);
} else if (this.currentSectionRef.top===-10000) {
this.currentSectionRef.updateToSection(this.currentSection,0,this.props.heightForSection(this.currentSection),false);
if (offset.y < this.headerHeight || offset.y > this.contentSize.height-this.footerHeight) {
this.currentSectionRef.updateToSection(
this.currentSection,
-10000,
this.props.heightForSection(this.currentSection),
false
);
} else if (this.currentSectionRef.top === -10000) {
this.currentSectionRef.updateToSection(
this.currentSection,
0,
this.props.heightForSection(this.currentSection),
false
);
}
// if (this.forceTimer>0) {
// clearTimeout(this.forceTimer);
// this.forceTimer=0;
// }
if (forceReload) {
// if (this.created) {
// this.created = false;
// this.setState({});
// } else {
this._forceUpdate();
// }
} else {
// this.forceTimer = setTimeout(()=>{
// this.forceTimer = 0;
// this._forceUpdate();
// },50);
}
this.props.onScroll && this.props.onScroll(e);
}
_forceUpdate(){
this.workRefs.forEach(item=>{
if (item.waitForRender)
item.forceUpdate();
_forceUpdate() {
this.workRefs.forEach(item => {
if (item.waitForRender) item.forceUpdate();
});
this.workSectionRefs.forEach(item=>{
this.workSectionRefs.forEach(item => {
if (item.waitForRender) {

@@ -478,5 +743,18 @@ item.forceUpdate();

}
this.freeRefs.forEach(item=>{
if (item.waitForRender) item.positionUpdate();
});
this.freeSectionRefs.forEach(section=>{
if (section.waitForRender) section.forceUpdate();
});
}
_positionUpdate() {
this.workRefs.forEach(item => {
if (item.waitForRender) item.positionUpdate();
});
this.freeRefs.forEach(item=>{
if (item.waitForRender) item.positionUpdate();
})
}
_onLayout(e) {

@@ -496,4 +774,9 @@ this.size = e.nativeEvent.layout;

_onSizeConfirm(){
if (!this.sizeConfirmed && this.size!=undefined && this.footerHeight!=undefined &&this.headerHeight!=undefined){
_onSizeConfirm() {
if (
!this.sizeConfirmed &&
this.size !== null &&
this.footerHeight !== null &&
this.headerHeight !== null
) {
this.sizeConfirmed = true;

@@ -505,18 +788,24 @@ this.initCells();

_nextIndexPathWithIndexPath(indexPath:IndexPath){
if (indexPath.row+1 < this.props.numberOfRowsInSection(indexPath.section)) {
return {section:indexPath.section, row:indexPath.row+1};
_nextIndexPathWithIndexPath(indexPath: IndexPath) {
if (
indexPath.row + 1 <
this.props.numberOfRowsInSection(indexPath.section)
) {
return { section: indexPath.section, row: indexPath.row + 1 };
}
return {section:indexPath.section+1, row:-1};
return { section: indexPath.section + 1, row: -1 };
}
_previousIndexPathWithIndexPath(indexPath:IndexPath) {
_previousIndexPathWithIndexPath(indexPath: IndexPath) {
if (indexPath.row > -1) {
return {section:indexPath.section, row:indexPath.row-1};
return { section: indexPath.section, row: indexPath.row - 1 };
}
return {section:indexPath.section-1, row:this.props.numberOfRowsInSection(indexPath.section)-1};
return {
section: indexPath.section - 1,
row: this.props.numberOfRowsInSection(indexPath.section - 1) - 1
};
}
_compareIndexPath(indexPath1:IndexPath,indexPath2:IndexPath){
if (indexPath1.section != indexPath2.section)
_compareIndexPath(indexPath1: IndexPath, indexPath2: IndexPath) {
if (indexPath1.section !== indexPath2.section)
return indexPath1.section - indexPath2.section;

@@ -526,17 +815,57 @@ return indexPath1.row - indexPath2.row;

scrollTo(offset:Offset, animated:boolean=true) {
offset.animated=animated;
_topCellRef(): LargeListCell {
let top = this.contentSize.height;
let cell: LargeListCell;
this.workRefs.forEach(item => {
if (top > item.top) {
cell = item;
top = item.top;
}
});
return cell;
}
_bottomCellRef(): LargeListCell {
let top = 0;
let cell: LargeListCell;
this.workRefs.forEach(item => {
if (top < item.top) {
cell = item;
top = item.top;
}
});
return cell;
}
scrollTo(offset: Offset, animated: boolean = true) {
offset.animated = animated;
this.scrollViewRef.scrollTo(offset);
}
scrollToIndexPath(indexPath:IndexPath, animated:boolean = true) {
let sumHeight = this.headerHeight?this.headerHeight:0;
for (let section=0;section<this.props.numberOfSections;++section) {
sumHeight+=this.props.heightForSection(section);
for (let row=0;row<this.props.numberOfRowsInSection(section);++row) {
sumHeight += this.props.heightForCell(section,row);
if (this._compareIndexPath(indexPath,{section:section,row:row})===0) {
this.scrollTo({x:0,y:sumHeight},animated);
scrollToIndexPath(indexPath: IndexPath, animated: boolean = true) {
if (this.native) {
this.scrollViewRef.scrollToIndexPath(indexPath);
return;
}
let sumHeight = this.headerHeight ? this.headerHeight : 0;
sumHeight -= this.props.heightForSection(indexPath.section);
sumHeight += 1;
for (let section = 0; section < this.props.numberOfSections; ++section) {
sumHeight += this.props.heightForSection(section);
for (
let row = 0;
row < this.props.numberOfRowsInSection(section);
++row
) {
if (
this._compareIndexPath(indexPath, { section: section, row: row }) ===
0
) {
if (sumHeight > this.contentSize.height - this.size.height)
sumHeight = this.contentSize.height - this.size.height - 1;
if (sumHeight < 0) sumHeight = 0;
this.scrollTo({ x: 0, y: sumHeight }, animated);
return;
}
sumHeight += this.props.heightForCell(section, row);
}

@@ -546,20 +875,74 @@ }

scrollToEnd(animated:boolean=true){
this.scrollViewRef.scrollToEnd({animated:animated});
scrollToEnd(animated: boolean = true) {
this.scrollViewRef.scrollToEnd({ animated: animated });
}
visiableIndexPaths():IndexPath[]{
let indexPaths:IndexPath[] = [];
this.workRefs.forEach(item=>{
if (item.top+item.height>this.contentOffset.y && item.top<this.contentOffset.y+this.size.height) {
indexPaths.push({section:item.indexPath.section,row:item.indexPath.row});
reloadIndexPath(indexPath: IndexPath) {
this.workRefs.forEach(cell => {
if (this._compareIndexPath(indexPath, cell.indexPath) === 0) {
cell.forceUpdate();
}
});
}
reloadIndexPaths(indexPaths: IndexPath[]) {
indexPaths.forEach(indexPath => {
this.reloadIndexPath(indexPath);
});
}
reloadAll() {
this.workRefs.forEach(cell => {
cell.forceUpdate();
});
}
reloadData() {
let offset = this.contentOffset;
this.initVar();
this.workRefs.forEach(cell => {
this.freeRefs.splice(0, 0, cell);
});
this.freeRefs.forEach(cell => {
cell.waitForRender = true;
let index = this.workRefs.indexOf(cell);
this.workRefs.splice(index, index > -1 ? 1 : 0);
cell.updateToIndexPath(cell.indexPath,-10000,cell.height);
// cell.positionUpdate();
});
this.workSectionRefs.forEach(section => {
this.freeSectionRefs.splice(0, 0, section);
});
this.freeSectionRefs.forEach(section => {
let index = this.workSectionRefs.indexOf(section);
this.workSectionRefs.splice(index, index > -1 ? 1 : 0);
section.updateToSection(section.section,-10000,section.height,false);
// section.po();
});
this._onScroll({ nativeEvent: { contentOffset: offset } });
}
visiableIndexPaths(): IndexPath[] {
let indexPaths: IndexPath[] = [];
this.workRefs.forEach(item => {
if (
item.top + item.height > this.contentOffset.y &&
item.top < this.contentOffset.y + this.size.height
) {
indexPaths.push({
section: item.indexPath.section,
row: item.indexPath.row
});
}
});
return indexPaths;
}
renderedIndexPaths():IndexPath[] {
let indexPaths:IndexPath[] = [];
this.workRefs.forEach(item=>{
indexPaths.push({section:item.indexPath.section,row:item.indexPath.row});
renderedIndexPaths(): IndexPath[] {
let indexPaths: IndexPath[] = [];
this.workRefs.forEach(item => {
indexPaths.push({
section: item.indexPath.section,
row: item.indexPath.row
});
});

@@ -572,5 +955,4 @@ return indexPaths;

}
}
export { LargeList };

@@ -22,3 +22,5 @@ /*

renderCell: PropTypes.func,
indexPath: PropTypes.object
indexPath: PropTypes.object,
numberOfRowsInSection: PropTypes.func,
numberOfSections: PropTypes.number
};

@@ -32,28 +34,23 @@

waitForRender: boolean;
locationUpdated: boolean;
forceUpdate() {
this.waitForRender = false;
if (this.locationUpdated) this.positionUpdate();
this.locationUpdated = false;
this.setState({});
}
updateToIndexPath(
indexPath: IndexPath,
top: number,
height: number,
force: boolean
) {
positionUpdate() {
this.locationUpdated = true;
this.rootView.setNativeProps({
style: { top: this.top, height: this.height }
});
}
updateToIndexPath(indexPath: IndexPath, top: number, height: number) {
this.waitForRender = true;
this.indexPath = { section: indexPath.section, row: indexPath.row };
this.top = top;
this.height = height;
if (!force) {
this.waitForRender = true;
this.rootView.setNativeProps({
style: {
top: top,
height: height
}
});
return;
}
this.forceUpdate();
}

@@ -72,2 +69,9 @@

render() {
let { section, row } = this.indexPath;
let show =
this.top !== -10000 &&
section >= 0 &&
section < this.props.numberOfSections &&
row >= 0 &&
row < this.props.numberOfRowsInSection(section);
return (

@@ -78,3 +82,3 @@ <View

>
{this.top !== -10000 &&
{show &&
this.props.renderCell(this.indexPath.section, this.indexPath.row)}

@@ -84,4 +88,10 @@ </View>

}
_compareIndexPath(indexPath1: IndexPath, indexPath2: IndexPath) {
if (indexPath1.section !== indexPath2.section)
return indexPath1.section - indexPath2.section;
return indexPath1.row - indexPath2.row;
}
}
export { LargeListCell };

@@ -21,2 +21,3 @@ /*

static propTypes = {
numberOfSections: PropTypes.number,
renderSection: PropTypes.func,

@@ -34,3 +35,8 @@ section: PropTypes.number

forceUpdate() {
if (this.waitForRender)
this.rootView.setNativeProps({
style: { top: this.top, height: this.height }
});
this.waitForRender = false;
this.setState({});

@@ -70,2 +76,3 @@ }

render() {
let show = this.section>=0 && this.section<this.props.numberOfSections && this.top !== -10000;
return (

@@ -76,3 +83,3 @@ <View

>
{this.props.renderSection(this.section)}
{show && this.props.renderSection(this.section)}
</View>

@@ -79,0 +86,0 @@ );

{
"name": "react-native-largelist",
"version": "0.0.6",
"version": "1.0.0",
"private": false,

@@ -5,0 +5,0 @@ "description": "A high performance large list component which is much better than SectionList for React Native.",

@@ -19,3 +19,9 @@ import React from "react";

super(props);
this.state = { row: props.row, style: props.style, update: updateIdf };
this.state = {
section: Math.floor(props.row / this.props.numberOfMostRows),
row: props.row % props.numberOfMostRows,
style: props.style,
update: updateIdf,
jsRenderedRow:props.row
};
}

@@ -27,10 +33,9 @@ render() {

style={this.state.style}
jsRenderedRow={this.state.row}
jsRenderedRow={this.state.jsRenderedRow}
jsFree={++busyIdf}
onUpdate={this.onUpdate.bind(this)}
onChange={this.onUpdate.bind(this)}
>
{this.props.renderChildren({
section: Math.floor(this.state.row / this.props.numberOfMostRows),
row: this.state.row % this.props.numberOfMostRows
section: this.state.section,
row: this.state.row
})}

@@ -52,3 +57,2 @@ </NativeCell>

};
console.log("onUpdate",new Date().getTime());
this.setState({

@@ -58,3 +62,4 @@ section: section,

style: style,
update: ++updateIdf
update: ++updateIdf,
jsRenderedRow:e.nativeEvent.row
});

@@ -61,0 +66,0 @@ }

@@ -152,3 +152,3 @@ import {

scrollTo(indexPath: IndexPathType) {
scrollToIndexPath(indexPath: IndexPathType) {
TableViewModule.scrollTo(indexPath, this.tag);

@@ -155,0 +155,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc