Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

Fix photos not updated when mediaList prop changes #86

Merged
merged 2 commits into from
Dec 27, 2018
Merged
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
65 changes: 47 additions & 18 deletions Example/DetailScreen.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { ActionSheetIOS, Platform } from 'react-native';
import { ActionSheetIOS, Platform, Button } from 'react-native';

import PhotoBrowser from 'react-native-photo-browser';

Expand All @@ -8,8 +8,23 @@ export default class HomeScreen extends Component {
header: null,
};

state = {
mediaList: this.props.navigation.state.params.example.media,
selected: new Set(),
}

onSelectionChanged = (media, index, selected) => {
alert(`${media.photo} selection status: ${selected}`);
this.setState(prevState => {
const copy = new Set(prevState.selected);
if (selected) {
copy.add(index);
} else {
copy.delete(index);
}
return {
selected: copy,
};
});
};

onActionButton = (media, index) => {
Expand All @@ -29,7 +44,6 @@ export default class HomeScreen extends Component {

render() {
const {
media,
initialIndex,
displayNavArrows,
displayActionButton,
Expand All @@ -39,22 +53,37 @@ export default class HomeScreen extends Component {
alwaysDisplayStatusBar,
} = this.props.navigation.state.params.example;

const { mediaList, selected } = this.state;

return (
<PhotoBrowser
onBack={navigator.pop}
mediaList={media}
initialIndex={initialIndex}
displayNavArrows={displayNavArrows}
displaySelectionButtons={displaySelectionButtons}
displayActionButton={displayActionButton}
startOnGrid={startOnGrid}
enableGrid={enableGrid}
useCircleProgress
onSelectionChanged={this.onSelectionChanged}
onActionButton={this.onActionButton}
alwaysDisplayStatusBar={alwaysDisplayStatusBar}
customTitle={(index, rowCount) => `${index} sur ${rowCount}`}
/>
<>
<PhotoBrowser
onBack={navigator.pop}
mediaList={mediaList}
initialIndex={initialIndex}
displayNavArrows={displayNavArrows}
displaySelectionButtons={displaySelectionButtons}
displayActionButton={displayActionButton}
startOnGrid={startOnGrid}
enableGrid={enableGrid}
useCircleProgress
onSelectionChanged={this.onSelectionChanged}
onActionButton={this.onActionButton}
alwaysDisplayStatusBar={alwaysDisplayStatusBar}
customTitle={(index, rowCount) => `${index} sur ${rowCount}`}
/>
{selected.size > 0 && (
<Button
title="Delete"
onPress={() =>
this.setState(prevState => ({
mediaList: prevState.mediaList.filter((_, i) => !prevState.selected.has(i)),
selected: new Set(),
}))
}
/>
)}
</>
);
}
}
1 change: 1 addition & 0 deletions Example/HomeScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const EXAMPLES = [
description: 'showing grid first, custom action method',
startOnGrid: true,
displayActionButton: true,
displaySelectionButtons: true
},
];

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ The component has both iOS and Android support.
const media = {
thumb: '', // thumbnail version of the photo to be displayed in grid view. actual photo is used if thumb is not provided
photo: '', // a remote photo or local media url
id: 1, // unique identifer for the photo; can be omitted if the `thumb`/`photo` will always be unique
caption: '', // photo caption to be displayed
selected: true, // set the photo selected initially(default is false)
};
Expand Down
6 changes: 2 additions & 4 deletions lib/FullScreenContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,7 @@ export default class FullScreenContainer extends React.Component {
uri={item.photo}
displaySelectionButtons={displaySelectionButtons}
selected={item.selected}
onSelection={(isSelected) => {
onMediaSelection(index, isSelected);
}}
onSelection={(isSelected) => onMediaSelection(item, index, isSelected)}
/>
</TouchableWithoutFeedback>
</View>
Expand Down Expand Up @@ -289,7 +287,7 @@ export default class FullScreenContainer extends React.Component {
);
}

_keyExtractor = (item, index) => index.toString();
_keyExtractor = item => item.id || item.thumb || item.photo;

render() {
const {
Expand Down
6 changes: 2 additions & 4 deletions lib/GridContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class GridContainer extends React.Component {
itemPerRow: 3,
};

keyExtractor = (item, index) => index.toString();
keyExtractor = item => item.id || item.thumb || item.photo;

renderItem = ({ item, index }) => {
const {
Expand All @@ -68,9 +68,7 @@ export default class GridContainer extends React.Component {
displaySelectionButtons={displaySelectionButtons}
uri={item.thumb || item.photo}
selected={item.selected}
onSelection={(isSelected) => {
onMediaSelection(index, isSelected);
}}
onSelection={(isSelected) => onMediaSelection(item, index, isSelected)}
/>
</View>
</TouchableHighlight>
Expand Down
32 changes: 7 additions & 25 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,12 @@ export default class PhotoBrowser extends React.Component {

this._onGridPhotoTap = this._onGridPhotoTap.bind(this);
this._onGridButtonTap = this._onGridButtonTap.bind(this);
this._onMediaSelection = this._onMediaSelection.bind(this);
this._updateTitle = this._updateTitle.bind(this);
this._toggleTopBar = this._toggleTopBar.bind(this);

const { mediaList, startOnGrid, initialIndex } = props;
const { startOnGrid, initialIndex } = props;

this.state = {
mediaList,
isFullScreen: !startOnGrid,
fullScreenAnim: new Animated.Value(startOnGrid ? 0 : 1),
currentIndex: initialIndex,
Expand All @@ -162,23 +160,6 @@ export default class PhotoBrowser extends React.Component {
this._toggleFullScreen(false);
}

_onMediaSelection(index, isSelected) {
const {
mediaList: oldMediaList,
} = this.state;
const newMediaList = oldMediaList.slice();
const selectedMedia = {
...oldMediaList[index],
selected: isSelected,
};
newMediaList[index] = selectedMedia;

this.setState({
mediaList: newMediaList,
});
this.props.onSelectionChanged(selectedMedia, index, isSelected);
}

_updateTitle(title) {
this.setState({ title });
}
Expand Down Expand Up @@ -206,6 +187,7 @@ export default class PhotoBrowser extends React.Component {

render() {
const {
mediaList,
alwaysShowControls,
displayNavArrows,
alwaysDisplayStatusBar,
Expand All @@ -219,10 +201,10 @@ export default class PhotoBrowser extends React.Component {
style,
square,
gridOffset,
customTitle
customTitle,
onSelectionChanged
} = this.props;
const {
mediaList,
isFullScreen,
fullScreenAnim,
currentIndex,
Expand Down Expand Up @@ -251,7 +233,7 @@ export default class PhotoBrowser extends React.Component {
mediaList={mediaList}
displaySelectionButtons={displaySelectionButtons}
onPhotoTap={this._onGridPhotoTap}
onMediaSelection={this._onMediaSelection}
onMediaSelection={onSelectionChanged}
itemPerRow={itemPerRow}
/>
</Animated.View>
Expand All @@ -272,7 +254,7 @@ export default class PhotoBrowser extends React.Component {
useCircleProgress={useCircleProgress}
onActionButton={onActionButton}
customTitle={customTitle}
onMediaSelection={this._onMediaSelection}
onMediaSelection={onSelectionChanged}
onGridButtonTap={this._onGridButtonTap}
updateTitle={this._updateTitle}
toggleTopBar={this._toggleTopBar}
Expand All @@ -295,7 +277,7 @@ export default class PhotoBrowser extends React.Component {
<TopBarComponent
height={TOOLBAR_HEIGHT}
displayed={displayTopBar}
title={isFullScreen ? title : `${mediaList.length} photos`}
title={mediaList.length && isFullScreen ? title : `${mediaList.length} photos`}
onBack={onBack}
/>
</View>
Expand Down
12 changes: 6 additions & 6 deletions lib/media/Photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,13 @@ export default class Photo extends Component {
this._onLoad = this._onLoad.bind(this);
this._toggleSelection = this._toggleSelection.bind(this);

const { lazyLoad, uri } = props;
const { lazyLoad, uri, selected } = props;

this.state = {
uri: lazyLoad ? null : uri,
progress: 0,
error: false,
selected,
};
}

Expand Down Expand Up @@ -132,9 +133,8 @@ export default class Photo extends Component {
}

_toggleSelection() {
// onSelection is resolved in index.js
// and refreshes the dataSource with new media object
this.props.onSelection(!this.props.selected);
this.props.onSelection(!this.state.selected);
this.setState(prevState => ({ selected: !prevState.selected}))
}

_renderProgressIndicator() {
Expand Down Expand Up @@ -175,8 +175,8 @@ export default class Photo extends Component {
}

_renderSelectionButton() {
const { progress } = this.state;
const { displaySelectionButtons, selected, thumbnail } = this.props;
const { selected, progress } = this.state;
const { displaySelectionButtons, thumbnail } = this.props;

// do not display selection before image is loaded
if (!displaySelectionButtons || progress < 1) {
Expand Down