@ -69,6 +69,10 @@ class Status extends ImmutablePureComponent {
onMoveUp : PropTypes . func ,
onMoveUp : PropTypes . func ,
onMoveDown : PropTypes . func ,
onMoveDown : PropTypes . func ,
showThread : PropTypes . bool ,
showThread : PropTypes . bool ,
getScrollPosition : PropTypes . func ,
updateScrollBottom : PropTypes . func ,
cacheMediaWidth : PropTypes . func ,
cachedMediaWidth : PropTypes . number ,
} ;
} ;
// Avoid checking props that are functions (and whose equality will always
// Avoid checking props that are functions (and whose equality will always
@ -80,6 +84,43 @@ class Status extends ImmutablePureComponent {
'hidden' ,
'hidden' ,
] ;
] ;
// Track height changes we know about to compensate scrolling
componentDidMount ( ) {
this . didShowCard = ! this . props . muted && ! this . props . hidden && this . props . status . get ( 'card' ) ;
}
getSnapshotBeforeUpdate ( ) {
if ( this . props . getScrollPosition ) {
return this . props . getScrollPosition ( ) ;
} else {
return null ;
}
}
// Compensate height changes
componentDidUpdate ( prevProps , prevState , snapshot ) {
const doShowCard = ! this . props . muted && ! this . props . hidden && this . props . status . get ( 'card' ) ;
if ( doShowCard && ! this . didShowCard ) {
this . didShowCard = true ;
if ( snapshot !== null && this . props . updateScrollBottom ) {
if ( this . node && this . node . offsetTop < snapshot . top ) {
this . props . updateScrollBottom ( snapshot . height - snapshot . top ) ;
}
}
}
}
componentWillUnmount ( ) {
if ( this . node && this . props . getScrollPosition ) {
const position = this . props . getScrollPosition ( ) ;
if ( position !== null && this . node . offsetTop < position . top ) {
requestAnimationFrame ( ( ) => {
this . props . updateScrollBottom ( position . height - position . top ) ;
} ) ;
}
}
}
handleClick = ( ) => {
handleClick = ( ) => {
if ( this . props . onClick ) {
if ( this . props . onClick ) {
this . props . onClick ( ) ;
this . props . onClick ( ) ;
@ -166,6 +207,10 @@ class Status extends ImmutablePureComponent {
}
}
}
}
handleRef = c => {
this . node = c ;
}
render ( ) {
render ( ) {
let media = null ;
let media = null ;
let statusAvatar , prepend , rebloggedByText ;
let statusAvatar , prepend , rebloggedByText ;
@ -180,7 +225,7 @@ class Status extends ImmutablePureComponent {
if ( hidden ) {
if ( hidden ) {
return (
return (
< div >
< div ref = { this . handleRef } >
{ status . getIn ( [ 'account' , 'display_name' ] ) || status . getIn ( [ 'account' , 'username' ] ) }
{ status . getIn ( [ 'account' , 'display_name' ] ) || status . getIn ( [ 'account' , 'username' ] ) }
{ status . get ( 'content' ) }
{ status . get ( 'content' ) }
< / d i v >
< / d i v >
@ -195,7 +240,7 @@ class Status extends ImmutablePureComponent {
return (
return (
< HotKeys handlers = { minHandlers } >
< HotKeys handlers = { minHandlers } >
< div className = 'status__wrapper status__wrapper--filtered focusable' tabIndex = '0' >
< div className = 'status__wrapper status__wrapper--filtered focusable' tabIndex = '0' ref = { this . handleRef } >
< FormattedMessage id = 'status.filtered' defaultMessage = 'Filtered' / >
< FormattedMessage id = 'status.filtered' defaultMessage = 'Filtered' / >
< / d i v >
< / d i v >
< / H o t K e y s >
< / H o t K e y s >
@ -243,11 +288,12 @@ class Status extends ImmutablePureComponent {
preview = { video . get ( 'preview_url' ) }
preview = { video . get ( 'preview_url' ) }
src = { video . get ( 'url' ) }
src = { video . get ( 'url' ) }
alt = { video . get ( 'description' ) }
alt = { video . get ( 'description' ) }
width = { 239 }
width = { this . props . cachedMediaWidth }
height = { 110 }
height = { 110 }
inline
inline
sensitive = { status . get ( 'sensitive' ) }
sensitive = { status . get ( 'sensitive' ) }
onOpenVideo = { this . handleOpenVideo }
onOpenVideo = { this . handleOpenVideo }
cacheWidth = { this . props . cacheMediaWidth }
/ >
/ >
) }
) }
< / B u n d l e >
< / B u n d l e >
@ -255,7 +301,16 @@ class Status extends ImmutablePureComponent {
} else {
} else {
media = (
media = (
< Bundle fetchComponent = { MediaGallery } loading = { this . renderLoadingMediaGallery } >
< Bundle fetchComponent = { MediaGallery } loading = { this . renderLoadingMediaGallery } >
{ Component => < Component media = { status . get ( 'media_attachments' ) } sensitive = { status . get ( 'sensitive' ) } height = { 110 } onOpenMedia = { this . props . onOpenMedia } / > }
{ Component => (
< Component
media = { status . get ( 'media_attachments' ) }
sensitive = { status . get ( 'sensitive' ) }
height = { 110 }
onOpenMedia = { this . props . onOpenMedia }
cacheWidth = { this . props . cacheMediaWidth }
defaultWidth = { this . props . cachedMediaWidth }
/ >
) }
< / B u n d l e >
< / B u n d l e >
) ;
) ;
}
}
@ -265,6 +320,8 @@ class Status extends ImmutablePureComponent {
onOpenMedia = { this . props . onOpenMedia }
onOpenMedia = { this . props . onOpenMedia }
card = { status . get ( 'card' ) }
card = { status . get ( 'card' ) }
compact
compact
cacheWidth = { this . props . cacheMediaWidth }
defaultWidth = { this . props . cachedMediaWidth }
/ >
/ >
) ;
) ;
}
}
@ -291,7 +348,7 @@ class Status extends ImmutablePureComponent {
return (
return (
< HotKeys handlers = { handlers } >
< HotKeys handlers = { handlers } >
< div className = { classNames ( 'status__wrapper' , ` status__wrapper- ${ status . get ( 'visibility' ) } ` , { 'status__wrapper-reply' : ! ! status . get ( 'in_reply_to_id' ) , read : unread === false , focusable : ! this . props . muted } ) } tabIndex = { this . props . muted ? null : 0 } data - featured = { featured ? 'true' : null } aria - label = { textForScreenReader ( intl , status , rebloggedByText , ! status . get ( 'hidden' ) ) } >
< div className = { classNames ( 'status__wrapper' , ` status__wrapper- ${ status . get ( 'visibility' ) } ` , { 'status__wrapper-reply' : ! ! status . get ( 'in_reply_to_id' ) , read : unread === false , focusable : ! this . props . muted } ) } tabIndex = { this . props . muted ? null : 0 } data - featured = { featured ? 'true' : null } aria - label = { textForScreenReader ( intl , status , rebloggedByText , ! status . get ( 'hidden' ) ) } ref = { this . handleRef } >
{ prepend }
{ prepend }
< div className = { classNames ( 'status' , ` status- ${ status . get ( 'visibility' ) } ` , { 'status-reply' : ! ! status . get ( 'in_reply_to_id' ) , muted : this . props . muted , read : unread === false } ) } data - id = { status . get ( 'id' ) } >
< div className = { classNames ( 'status' , ` status- ${ status . get ( 'visibility' ) } ` , { 'status-reply' : ! ! status . get ( 'in_reply_to_id' ) , muted : this . props . muted , read : unread === false } ) } data - id = { status . get ( 'id' ) } >