Skip to content
This repository was archived by the owner on Feb 27, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 63 additions & 57 deletions lib/FullScreenContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import PropTypes from 'prop-types';
import {
DeviceEventEmitter,
Dimensions,
FlatList,
ListView,
View,
ViewPagerAndroid,
StyleSheet,
Platform,
StatusBar,
TouchableWithoutFeedback,
ViewPropTypes
Expand All @@ -19,17 +21,18 @@ export default class FullScreenContainer extends React.Component {

static propTypes = {
style: ViewPropTypes.style,
dataSource: PropTypes.instanceOf(ListView.DataSource).isRequired,
mediaList: PropTypes.array.isRequired,
/*
* opens grid view
*/
onGridButtonTap: PropTypes.func,

/*
* Display top bar
*/
displayTopBar: PropTypes.bool,

/*
* updates top bar title
*/
Expand Down Expand Up @@ -60,14 +63,8 @@ export default class FullScreenContainer extends React.Component {
onActionButton: PropTypes.func,
onPhotoLongPress: PropTypes.func,
delayLongPress: PropTypes.number,

/**
* Use a custom button in the bottom bar to the left of the Share button,
* without having to recreate the entire bottom bar and pass it in with the
* `bottomBarComponent` prop. The visibility of the Share button can still
* be controlled with `displayActionButton`.
*/
customBottomBarButton: PropTypes.element,
enablePinchToZoom: PropTypes.bool,
customBottomBarButton: PropTypes.element,
};

static defaultProps = {
Expand All @@ -80,14 +77,16 @@ export default class FullScreenContainer extends React.Component {
onGridButtonTap: () => {},
onPhotoLongPress: () => {},
delayLongPress: 1000,
enablePinchToZoom: true,
};

constructor(props, context) {
super(props, context);

this._renderItem = this._renderItem.bind(this);
this._renderRow = this._renderRow.bind(this);
this._toggleControls = this._toggleControls.bind(this);
this._onScroll = this._onScroll.bind(this);
this._onPageSelected = this._onPageSelected.bind(this);
this._onNextButtonTapped = this._onNextButtonTapped.bind(this);
this._onPhotoLongPress = this._onPhotoLongPress.bind(this);
this._onPreviousButtonTapped = this._onPreviousButtonTapped.bind(this);
Expand All @@ -111,14 +110,19 @@ export default class FullScreenContainer extends React.Component {
}

openPage(index, animated) {
if (!this.flatListView) {
if (!this.scrollView) {
return;
}

this.flatListView.scrollToIndex({
index,
if (Platform.OS === 'ios') {
const screenWidth = Dimensions.get('window').width;
this.scrollView.scrollTo({
x: index * screenWidth,
animated,
});
} else {
this.scrollView.setPageWithoutAnimation(index);
}

this._updatePageIndex(index);
}
Expand All @@ -130,10 +134,7 @@ export default class FullScreenContainer extends React.Component {
}, () => {
this._triggerPhotoLoad(index);

const { customTitle, mediaList } = this.props;

const rowCount = mediaList.length;
const newTitle = customTitle ? customTitle(index + 1, rowCount) : `${index + 1} of ${rowCount}`;
const newTitle = `${index + 1} of ${this.props.dataSource.getRowCount()}`;
this.props.updateTitle(newTitle);
});
}
Expand Down Expand Up @@ -166,7 +167,7 @@ export default class FullScreenContainer extends React.Component {
_onNextButtonTapped() {
let nextIndex = this.state.currentIndex + 1;
// go back to the first item when there is no more next item
if (nextIndex > this.props.mediaList.length - 1) {
if (nextIndex > this.props.dataSource.getRowCount() - 1) {
nextIndex = 0;
}
this.openPage(nextIndex, false);
Expand All @@ -176,7 +177,7 @@ export default class FullScreenContainer extends React.Component {
let prevIndex = this.state.currentIndex - 1;
// go to the last item when there is no more previous item
if (prevIndex < 0) {
prevIndex = this.props.mediaList.length - 1;
prevIndex = this.props.dataSource.getRowCount() - 1;
}
this.openPage(prevIndex, false);
}
Expand Down Expand Up @@ -204,6 +205,11 @@ export default class FullScreenContainer extends React.Component {
const { currentIndex } = this.state;
let newIndex = page;

// handle ViewPagerAndroid argument
if (typeof newIndex === 'object') {
newIndex = newIndex.nativeEvent.position;
}

if (currentIndex !== newIndex) {
this._updatePageIndex(newIndex);

Expand All @@ -212,88 +218,87 @@ export default class FullScreenContainer extends React.Component {
}
}
}

_onPhotoLongPress() {
const onPhotoLongPress = this.props.onPhotoLongPress;
const { currentMedia, currentIndex } = this.state;
onPhotoLongPress(currentMedia, currentIndex);
}

_renderItem({ item, index }) {
_renderRow(media: Object, sectionID: number, rowID: number) {
const {
displaySelectionButtons,
onMediaSelection,
useCircleProgress,
} = this.props;

return (
<View style={styles.flex}>
<TouchableWithoutFeedback
<View key={`row_${rowID}`} style={styles.flex}>
<Photo
ref={ref => this.photoRefs[rowID] = ref}
lazyLoad
useCircleProgress={useCircleProgress}
uri={media.photo}
displaySelectionButtons={displaySelectionButtons}
selected={media.selected}
enablePinchToZoom={this.props.enablePinchToZoom}
onSelection={(isSelected) => {
onMediaSelection(rowID, isSelected);
}}
onPress={this._toggleControls}
onLongPress={this._onPhotoLongPress}
delayLongPress={this.props.delayLongPress}>
<Photo
ref={ref => this.photoRefs[index] = ref}
lazyLoad
useCircleProgress={useCircleProgress}
uri={item.photo}
displaySelectionButtons={displaySelectionButtons}
selected={item.selected}
onSelection={(isSelected) => onMediaSelection(item, index, isSelected)}
/>
</TouchableWithoutFeedback>
delayLongPress={this.props.delayLongPress}
/>
</View>
);
}

getItemLayout = (data, index) => (
{ length: Dimensions.get('window').width, offset: Dimensions.get('window').width * index, index }
)

_renderScrollableContent() {
const { mediaList } = this.props;
const { dataSource, mediaList } = this.props;

if (Platform.OS === 'android') {
return (
<ViewPagerAndroid
style={styles.flex}
ref={scrollView => this.scrollView = scrollView}
onPageSelected={this._onPageSelected}
>
{mediaList.map((child, idx) => this._renderRow(child, 0, idx))}
</ViewPagerAndroid>
);
}

return (
<FlatList
ref={flatListView => this.flatListView = flatListView}
data={mediaList}
renderItem={this._renderItem}
<ListView
ref={scrollView => this.scrollView = scrollView}
dataSource={dataSource}
renderRow={this._renderRow}
onScroll={this._onScroll}
keyExtractor={this._keyExtractor}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
directionalLockEnabled
scrollEventThrottle={16}
getItemLayout={this.getItemLayout}
initialScrollIndex={this.state.currentIndex}
/>
);
}

_keyExtractor = item => item.id || item.thumb || item.photo;

render() {
const {
displayNavArrows,
alwaysDisplayStatusBar,
displayActionButton,
onGridButtonTap,
enableGrid,
customBottomBarButton,
customBottomBarButton,
} = this.props;
const { controlsDisplayed, currentMedia } = this.state;
const BottomBarComponent = this.props.bottomBarComponent || BottomBar;

return (
<View style={styles.flex}>
<StatusBar
hidden={alwaysDisplayStatusBar ? false : !controlsDisplayed}
showHideTransition={'slide'}
barStyle={'light-content'}
animated
translucent
backgroundColor={this.props.color_pri}
/>
{this._renderScrollableContent()}
<BottomBarComponent
Expand All @@ -308,11 +313,12 @@ export default class FullScreenContainer extends React.Component {
onNext={this._onNextButtonTapped}
onGrid={onGridButtonTap}
onAction={this._onActionButtonTapped}
customButton={customBottomBarButton}
customButton={customBottomBarButton}
/>
</View>
);
}

}

const styles = StyleSheet.create({
Expand Down
50 changes: 31 additions & 19 deletions lib/GridContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import {
Dimensions,
FlatList,
ListView,
TouchableHighlight,
View,
StyleSheet,
ViewPropTypes
} from 'react-native';

import { ifIphoneX } from 'react-native-iphone-x-helper';

import Constants from './constants';
import { Photo } from './media';

Expand All @@ -21,8 +19,8 @@ export default class GridContainer extends React.Component {

static propTypes = {
style: ViewPropTypes.style,
mediaList: PropTypes.array.isRequired,
square: PropTypes.bool,
dataSource: PropTypes.instanceOf(ListView.DataSource).isRequired,
displaySelectionButtons: PropTypes.bool,
onPhotoTap: PropTypes.func,
itemPerRow: PropTypes.number,
Expand All @@ -44,9 +42,15 @@ export default class GridContainer extends React.Component {
itemPerRow: 3,
};

keyExtractor = item => item.id || item.thumb || item.photo;
constructor(props, context) {
super(props, context);

this._renderRow = this._renderRow.bind(this);

renderItem = ({ item, index }) => {
this.state = {};
}

_renderRow(media: Object, sectionID: number, rowID: number) {
const {
displaySelectionButtons,
onPhotoTap,
Expand All @@ -59,7 +63,7 @@ export default class GridContainer extends React.Component {
const photoWidth = (screenWidth / itemPerRow) - (ITEM_MARGIN * 2);

return (
<TouchableHighlight onPress={() => onPhotoTap(index)}>
<TouchableHighlight onPress={() => onPhotoTap(parseInt(rowID, 10))}>
<View style={styles.row}>
<Photo
width={photoWidth}
Expand All @@ -68,28 +72,31 @@ export default class GridContainer extends React.Component {
thumbnail
progressImage={require('../Assets/hourglass.png')}
displaySelectionButtons={displaySelectionButtons}
uri={item.thumb || item.photo}
selected={item.selected}
onSelection={(isSelected) => onMediaSelection(item, index, isSelected)}
uri={media.thumb || media.photo}
selected={media.selected}
enablePinchToZoom={false}
onSelection={(isSelected) => {
onMediaSelection(rowID, isSelected);
}}
/>
</View>
</TouchableHighlight>
);
}

render() {
const { mediaList } = this.props;
const { dataSource } = this.props;

return (
<View style={styles.container}>
<FlatList
keyExtractor={this.keyExtractor}
data={mediaList}
initialNumToRender={21}
numColumns={3}
renderItem={this.renderItem}
<ListView
contentContainerStyle={styles.list}
dataSource={dataSource}
initialListSize={21}
pageSize={3}
scrollRenderAheadDistance={500}
renderRow={this._renderRow}
removeClippedSubviews={false}
getItemLayout={this.getItemLayout}
/>
</View>
);
Expand All @@ -100,9 +107,14 @@ export default class GridContainer extends React.Component {
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: ifIphoneX(18, 0),
paddingBottom: Constants.TOOLBAR_HEIGHT,
},
list: {
justifyContent: 'flex-start',
alignItems: 'flex-start',
flexDirection: 'row',
flexWrap: 'wrap',
},
row: {
justifyContent: 'center',
margin: 1,
Expand Down
Loading