|
@ -14,12 +14,13 @@ import HeaderContainer from 'flavours/glitch/features/account_timeline/container |
|
|
import { ScrollContainer } from 'react-router-scroll-4'; |
|
|
import { ScrollContainer } from 'react-router-scroll-4'; |
|
|
import LoadMore from 'flavours/glitch/components/load_more'; |
|
|
import LoadMore from 'flavours/glitch/components/load_more'; |
|
|
import MissingIndicator from 'flavours/glitch/components/missing_indicator'; |
|
|
import MissingIndicator from 'flavours/glitch/components/missing_indicator'; |
|
|
|
|
|
import { openModal } from 'flavours/glitch/actions/modal'; |
|
|
|
|
|
|
|
|
const mapStateToProps = (state, props) => ({ |
|
|
const mapStateToProps = (state, props) => ({ |
|
|
isAccount: !!state.getIn(['accounts', props.params.accountId]), |
|
|
isAccount: !!state.getIn(['accounts', props.params.accountId]), |
|
|
medias: getAccountGallery(state, props.params.accountId), |
|
|
|
|
|
|
|
|
attachments: getAccountGallery(state, props.params.accountId), |
|
|
isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']), |
|
|
isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']), |
|
|
hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']), |
|
|
|
|
|
|
|
|
hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']), |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
class LoadMoreMedia extends ImmutablePureComponent { |
|
|
class LoadMoreMedia extends ImmutablePureComponent { |
|
@ -50,12 +51,16 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
static propTypes = { |
|
|
static propTypes = { |
|
|
params: PropTypes.object.isRequired, |
|
|
params: PropTypes.object.isRequired, |
|
|
dispatch: PropTypes.func.isRequired, |
|
|
dispatch: PropTypes.func.isRequired, |
|
|
medias: ImmutablePropTypes.list.isRequired, |
|
|
|
|
|
|
|
|
attachments: ImmutablePropTypes.list.isRequired, |
|
|
isLoading: PropTypes.bool, |
|
|
isLoading: PropTypes.bool, |
|
|
hasMore: PropTypes.bool, |
|
|
hasMore: PropTypes.bool, |
|
|
isAccount: PropTypes.bool, |
|
|
isAccount: PropTypes.bool, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
state = { |
|
|
|
|
|
width: 323, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
componentDidMount () { |
|
|
componentDidMount () { |
|
|
this.props.dispatch(fetchAccount(this.props.params.accountId)); |
|
|
this.props.dispatch(fetchAccount(this.props.params.accountId)); |
|
|
this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId)); |
|
|
this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId)); |
|
@ -74,11 +79,11 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
|
|
|
|
|
|
handleScrollToBottom = () => { |
|
|
handleScrollToBottom = () => { |
|
|
if (this.props.hasMore) { |
|
|
if (this.props.hasMore) { |
|
|
this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined); |
|
|
|
|
|
|
|
|
this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
handleScroll = (e) => { |
|
|
|
|
|
|
|
|
handleScroll = e => { |
|
|
const { scrollTop, scrollHeight, clientHeight } = e.target; |
|
|
const { scrollTop, scrollHeight, clientHeight } = e.target; |
|
|
const offset = scrollHeight - scrollTop - clientHeight; |
|
|
const offset = scrollHeight - scrollTop - clientHeight; |
|
|
|
|
|
|
|
@ -91,7 +96,7 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId, { maxId })); |
|
|
this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId, { maxId })); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
handleLoadOlder = (e) => { |
|
|
|
|
|
|
|
|
handleLoadOlder = e => { |
|
|
e.preventDefault(); |
|
|
e.preventDefault(); |
|
|
this.handleScrollToBottom(); |
|
|
this.handleScrollToBottom(); |
|
|
} |
|
|
} |
|
@ -101,12 +106,30 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
return !(location.state && location.state.mastodonModalOpen); |
|
|
return !(location.state && location.state.mastodonModalOpen); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
setRef = c => { |
|
|
|
|
|
|
|
|
setColumnRef = c => { |
|
|
this.column = c; |
|
|
this.column = c; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
handleOpenMedia = attachment => { |
|
|
|
|
|
if (attachment.get('type') === 'video') { |
|
|
|
|
|
this.props.dispatch(openModal('VIDEO', { media: attachment })); |
|
|
|
|
|
} else { |
|
|
|
|
|
const media = attachment.getIn(['status', 'media_attachments']); |
|
|
|
|
|
const index = media.findIndex(x => x.get('id') === attachment.get('id')); |
|
|
|
|
|
|
|
|
|
|
|
this.props.dispatch(openModal('MEDIA', { media, index })); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
handleRef = c => { |
|
|
|
|
|
if (c) { |
|
|
|
|
|
this.setState({ width: c.offsetWidth }); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
render () { |
|
|
render () { |
|
|
const { medias, isLoading, hasMore, isAccount } = this.props; |
|
|
|
|
|
|
|
|
const { attachments, isLoading, hasMore, isAccount } = this.props; |
|
|
|
|
|
const { width } = this.state; |
|
|
|
|
|
|
|
|
if (!isAccount) { |
|
|
if (!isAccount) { |
|
|
return ( |
|
|
return ( |
|
@ -116,9 +139,7 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let loadOlder = null; |
|
|
|
|
|
|
|
|
|
|
|
if (!medias && isLoading) { |
|
|
|
|
|
|
|
|
if (!attachments && isLoading) { |
|
|
return ( |
|
|
return ( |
|
|
<Column> |
|
|
<Column> |
|
|
<LoadingIndicator /> |
|
|
<LoadingIndicator /> |
|
@ -126,35 +147,31 @@ export default class AccountGallery extends ImmutablePureComponent { |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (hasMore && !(isLoading && medias.size === 0)) { |
|
|
|
|
|
|
|
|
let loadOlder = null; |
|
|
|
|
|
|
|
|
|
|
|
if (hasMore && !(isLoading && attachments.size === 0)) { |
|
|
loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />; |
|
|
loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<Column ref={this.setRef}> |
|
|
|
|
|
|
|
|
<Column ref={this.setColumnRef}> |
|
|
<ProfileColumnHeader onClick={this.handleHeaderClick} /> |
|
|
<ProfileColumnHeader onClick={this.handleHeaderClick} /> |
|
|
|
|
|
|
|
|
<ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={this.shouldUpdateScroll}> |
|
|
<ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={this.shouldUpdateScroll}> |
|
|
<div className='scrollable scrollable--flex' onScroll={this.handleScroll}> |
|
|
<div className='scrollable scrollable--flex' onScroll={this.handleScroll}> |
|
|
<HeaderContainer accountId={this.props.params.accountId} /> |
|
|
<HeaderContainer accountId={this.props.params.accountId} /> |
|
|
|
|
|
|
|
|
<div role='feed' className='account-gallery__container'> |
|
|
|
|
|
{medias.map((media, index) => media === null ? ( |
|
|
|
|
|
<LoadMoreMedia |
|
|
|
|
|
key={'more:' + medias.getIn(index + 1, 'id')} |
|
|
|
|
|
maxId={index > 0 ? medias.getIn(index - 1, 'id') : null} |
|
|
|
|
|
onLoadMore={this.handleLoadMore} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
<div role='feed' className='account-gallery__container' ref={this.handleRef}> |
|
|
|
|
|
{attachments.map((attachment, index) => attachment === null ? ( |
|
|
|
|
|
<LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} /> |
|
|
) : ( |
|
|
) : ( |
|
|
<MediaItem |
|
|
|
|
|
key={media.get('id')} |
|
|
|
|
|
media={media} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
<MediaItem key={attachment.get('id')} attachment={attachment} displayWidth={width} onOpenMedia={this.handleOpenMedia} /> |
|
|
))} |
|
|
))} |
|
|
|
|
|
|
|
|
{loadOlder} |
|
|
{loadOlder} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
{isLoading && medias.size === 0 && ( |
|
|
|
|
|
|
|
|
{isLoading && attachments.size === 0 && ( |
|
|
<div className='scrollable__append'> |
|
|
<div className='scrollable__append'> |
|
|
<LoadingIndicator /> |
|
|
<LoadingIndicator /> |
|
|
</div> |
|
|
</div> |
|
|