diff options
author | Reverite <github@reverite.sh> | 2019-10-07 13:53:25 -0700 |
---|---|---|
committer | Reverite <github@reverite.sh> | 2019-10-07 13:53:25 -0700 |
commit | 38afc782051fe6faf06c2c9ca20304dd946cfb5c (patch) | |
tree | 2ff5e256635cbbeabe3347b6a0772415f9f1426c /app/javascript/flavours/glitch/features | |
parent | 46ada47e09af0da9c776ef83c0ff034c720a83d6 (diff) | |
parent | d2f7b8685cfd0ec9b69af505b56c791d9b5f1c82 (diff) |
Merge branch 'glitch' into production
Diffstat (limited to 'app/javascript/flavours/glitch/features')
29 files changed, 119 insertions, 41 deletions
diff --git a/app/javascript/flavours/glitch/features/account/components/profile_column_header.js b/app/javascript/flavours/glitch/features/account/components/profile_column_header.js index b6d373a2c..17c08e375 100644 --- a/app/javascript/flavours/glitch/features/account/components/profile_column_header.js +++ b/app/javascript/flavours/glitch/features/account/components/profile_column_header.js @@ -12,11 +12,12 @@ class ProfileColumnHeader extends React.PureComponent { static propTypes = { onClick: PropTypes.func, + multiColumn: PropTypes.bool, intl: PropTypes.object.isRequired, }; render() { - const { onClick, intl } = this.props; + const { onClick, intl, multiColumn } = this.props; return ( <ColumnHeader @@ -24,6 +25,7 @@ class ProfileColumnHeader extends React.PureComponent { title={intl.formatMessage(messages.profile)} onClick={onClick} showBackButton + multiColumn={multiColumn} /> ); } diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js index ff39764bb..f5fe6c930 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/index.js +++ b/app/javascript/flavours/glitch/features/account_gallery/index.js @@ -55,6 +55,7 @@ class AccountGallery extends ImmutablePureComponent { isLoading: PropTypes.bool, hasMore: PropTypes.bool, isAccount: PropTypes.bool, + multiColumn: PropTypes.bool, }; state = { @@ -130,7 +131,7 @@ class AccountGallery extends ImmutablePureComponent { } render () { - const { attachments, isLoading, hasMore, isAccount } = this.props; + const { attachments, isLoading, hasMore, isAccount, multiColumn } = this.props; const { width } = this.state; if (!isAccount) { @@ -157,7 +158,7 @@ class AccountGallery extends ImmutablePureComponent { return ( <Column ref={this.setColumnRef}> - <ProfileColumnHeader onClick={this.handleHeaderClick} /> + <ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} /> <ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={this.shouldUpdateScroll}> <div className='scrollable scrollable--flex' onScroll={this.handleScroll}> diff --git a/app/javascript/flavours/glitch/features/account_timeline/index.js b/app/javascript/flavours/glitch/features/account_timeline/index.js index 2f0859341..1f02c1be5 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/index.js +++ b/app/javascript/flavours/glitch/features/account_timeline/index.js @@ -39,6 +39,7 @@ class AccountTimeline extends ImmutablePureComponent { hasMore: PropTypes.bool, withReplies: PropTypes.bool, isAccount: PropTypes.bool, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -76,7 +77,7 @@ class AccountTimeline extends ImmutablePureComponent { } render () { - const { statusIds, featuredStatusIds, isLoading, hasMore, isAccount } = this.props; + const { statusIds, featuredStatusIds, isLoading, hasMore, isAccount, multiColumn } = this.props; if (!isAccount) { return ( @@ -96,7 +97,7 @@ class AccountTimeline extends ImmutablePureComponent { return ( <Column ref={this.setRef} name='account'> - <ProfileColumnHeader onClick={this.handleHeaderClick} /> + <ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} /> <StatusList prepend={<HeaderContainer accountId={this.props.params.accountId} />} @@ -108,6 +109,7 @@ class AccountTimeline extends ImmutablePureComponent { hasMore={hasMore} onLoadMore={this.handleLoadMore} emptyMessage={<FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/blocks/index.js b/app/javascript/flavours/glitch/features/blocks/index.js index 8a84f5a55..9eb6fe02e 100644 --- a/app/javascript/flavours/glitch/features/blocks/index.js +++ b/app/javascript/flavours/glitch/features/blocks/index.js @@ -31,6 +31,7 @@ class Blocks extends ImmutablePureComponent { accountIds: ImmutablePropTypes.list, hasMore: PropTypes.bool, intl: PropTypes.object.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -42,7 +43,7 @@ class Blocks extends ImmutablePureComponent { }, 300, { leading: true }); render () { - const { intl, accountIds, hasMore } = this.props; + const { intl, accountIds, hasMore, multiColumn } = this.props; if (!accountIds) { return ( @@ -55,13 +56,14 @@ class Blocks extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />; return ( - <Column name='blocks' icon='ban' heading={intl.formatMessage(messages.heading)}> + <Column name='blocks' bindToDocument={!multiColumn} icon='ban' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <ScrollableList scrollKey='blocks' onLoadMore={this.handleLoadMore} hasMore={hasMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} /> diff --git a/app/javascript/flavours/glitch/features/bookmarked_statuses/index.js b/app/javascript/flavours/glitch/features/bookmarked_statuses/index.js index 7d550e362..58b9e6396 100644 --- a/app/javascript/flavours/glitch/features/bookmarked_statuses/index.js +++ b/app/javascript/flavours/glitch/features/bookmarked_statuses/index.js @@ -73,7 +73,7 @@ class Bookmarks extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.bookmarked_statuses' defaultMessage="You don't have any bookmarked toots yet. When you bookmark one, it will show up here." />; return ( - <Column ref={this.setRef} name='bookmarks'> + <Column bindToDocument={!multiColumn} ref={this.setRef} name='bookmarks'> <ColumnHeader icon='bookmark' title={intl.formatMessage(messages.heading)} @@ -93,6 +93,7 @@ class Bookmarks extends ImmutablePureComponent { isLoading={isLoading} onLoadMore={this.handleLoadMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/community_timeline/index.js b/app/javascript/flavours/glitch/features/community_timeline/index.js index 5585edc9c..c548824ce 100644 --- a/app/javascript/flavours/glitch/features/community_timeline/index.js +++ b/app/javascript/flavours/glitch/features/community_timeline/index.js @@ -105,7 +105,7 @@ class CommunityTimeline extends React.PureComponent { const pinned = !!columnId; return ( - <Column ref={this.setRef} name='local' label={intl.formatMessage(messages.title)}> + <Column ref={this.setRef} name='local' bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}> <ColumnHeader icon='users' active={hasUnread} @@ -125,6 +125,7 @@ class CommunityTimeline extends React.PureComponent { timelineId={`community${onlyMedia ? ':media' : ''}`} onLoadMore={this.handleLoadMore} emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/direct_timeline/index.js b/app/javascript/flavours/glitch/features/direct_timeline/index.js index e2c0a439a..7741c6922 100644 --- a/app/javascript/flavours/glitch/features/direct_timeline/index.js +++ b/app/javascript/flavours/glitch/features/direct_timeline/index.js @@ -135,7 +135,7 @@ class DirectTimeline extends React.PureComponent { } return ( - <Column ref={this.setRef} label={intl.formatMessage(messages.title)}> + <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}> <ColumnHeader icon='envelope' active={hasUnread} diff --git a/app/javascript/flavours/glitch/features/domain_blocks/index.js b/app/javascript/flavours/glitch/features/domain_blocks/index.js index 49e0368d7..cd105a49b 100644 --- a/app/javascript/flavours/glitch/features/domain_blocks/index.js +++ b/app/javascript/flavours/glitch/features/domain_blocks/index.js @@ -32,6 +32,7 @@ class Blocks extends ImmutablePureComponent { hasMore: PropTypes.bool, domains: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -43,7 +44,7 @@ class Blocks extends ImmutablePureComponent { }, 300, { leading: true }); render () { - const { intl, domains, hasMore } = this.props; + const { intl, domains, hasMore, multiColumn } = this.props; if (!domains) { return ( @@ -56,13 +57,14 @@ class Blocks extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no hidden domains yet.' />; return ( - <Column icon='minus-circle' heading={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <ScrollableList scrollKey='domain_blocks' onLoadMore={this.handleLoadMore} hasMore={hasMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {domains.map(domain => <DomainContainer key={domain} domain={domain} /> diff --git a/app/javascript/flavours/glitch/features/favourited_statuses/index.js b/app/javascript/flavours/glitch/features/favourited_statuses/index.js index 719a31d6e..c6470ba74 100644 --- a/app/javascript/flavours/glitch/features/favourited_statuses/index.js +++ b/app/javascript/flavours/glitch/features/favourited_statuses/index.js @@ -73,7 +73,7 @@ class Favourites extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.favourited_statuses' defaultMessage="You don't have any favourite toots yet. When you favourite one, it will show up here." />; return ( - <Column ref={this.setRef} name='favourites' label={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} ref={this.setRef} name='favourites' label={intl.formatMessage(messages.heading)}> <ColumnHeader icon='star' title={intl.formatMessage(messages.heading)} @@ -93,6 +93,7 @@ class Favourites extends ImmutablePureComponent { isLoading={isLoading} onLoadMore={this.handleLoadMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/favourites/index.js b/app/javascript/flavours/glitch/features/favourites/index.js index 7afadf12e..953bf171f 100644 --- a/app/javascript/flavours/glitch/features/favourites/index.js +++ b/app/javascript/flavours/glitch/features/favourites/index.js @@ -6,6 +6,7 @@ import LoadingIndicator from 'flavours/glitch/components/loading_indicator'; import { fetchFavourites } from 'flavours/glitch/actions/interactions'; import AccountContainer from 'flavours/glitch/containers/account_container'; import Column from 'flavours/glitch/features/ui/components/column'; +import Icon from 'flavours/glitch/components/icon'; import ColumnHeader from 'flavours/glitch/components/column_header'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -13,6 +14,7 @@ import ScrollableList from '../../components/scrollable_list'; const messages = defineMessages({ heading: { id: 'column.favourited_by', defaultMessage: 'Favourited by' }, + refresh: { id: 'refresh', defaultMessage: 'Refresh' }, }); const mapStateToProps = (state, props) => ({ @@ -27,6 +29,7 @@ class Favourites extends ImmutablePureComponent { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, accountIds: ImmutablePropTypes.list, + multiColumn: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -50,8 +53,12 @@ class Favourites extends ImmutablePureComponent { this.column = c; } + handleRefresh = () => { + this.props.dispatch(fetchFavourites(this.props.params.statusId)); + } + render () { - const { intl, accountIds } = this.props; + const { intl, accountIds, multiColumn } = this.props; if (!accountIds) { return ( @@ -70,10 +77,15 @@ class Favourites extends ImmutablePureComponent { title={intl.formatMessage(messages.heading)} onClick={this.handleHeaderClick} showBackButton + multiColumn={multiColumn} + extraButton={( + <button className='column-header__button' title={intl.formatMessage(messages.refresh)} aria-label={intl.formatMessage(messages.refresh)} onClick={this.handleRefresh}><Icon id='refresh' /></button> + )} /> <ScrollableList scrollKey='favourites' emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} /> diff --git a/app/javascript/flavours/glitch/features/follow_requests/index.js b/app/javascript/flavours/glitch/features/follow_requests/index.js index a7e8f4b61..36770aace 100644 --- a/app/javascript/flavours/glitch/features/follow_requests/index.js +++ b/app/javascript/flavours/glitch/features/follow_requests/index.js @@ -31,6 +31,7 @@ class FollowRequests extends ImmutablePureComponent { hasMore: PropTypes.bool, accountIds: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -42,7 +43,7 @@ class FollowRequests extends ImmutablePureComponent { }, 300, { leading: true }); render () { - const { intl, accountIds, hasMore } = this.props; + const { intl, accountIds, hasMore, multiColumn } = this.props; if (!accountIds) { return ( @@ -55,7 +56,7 @@ class FollowRequests extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />; return ( - <Column name='follow-requests' icon='user-plus' heading={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} name='follow-requests' icon='user-plus' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <ScrollableList @@ -63,6 +64,7 @@ class FollowRequests extends ImmutablePureComponent { onLoadMore={this.handleLoadMore} hasMore={hasMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountAuthorizeContainer key={id} id={id} /> diff --git a/app/javascript/flavours/glitch/features/followers/index.js b/app/javascript/flavours/glitch/features/followers/index.js index 2bd0e6e2f..c78dcc8e4 100644 --- a/app/javascript/flavours/glitch/features/followers/index.js +++ b/app/javascript/flavours/glitch/features/followers/index.js @@ -33,6 +33,7 @@ class Followers extends ImmutablePureComponent { accountIds: ImmutablePropTypes.list, hasMore: PropTypes.bool, isAccount: PropTypes.bool, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -70,7 +71,7 @@ class Followers extends ImmutablePureComponent { } render () { - const { accountIds, hasMore, isAccount } = this.props; + const { accountIds, hasMore, isAccount, multiColumn } = this.props; if (!isAccount) { return ( @@ -92,7 +93,7 @@ class Followers extends ImmutablePureComponent { return ( <Column ref={this.setRef}> - <ProfileColumnHeader onClick={this.handleHeaderClick} /> + <ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} /> <ScrollableList scrollKey='followers' @@ -101,6 +102,7 @@ class Followers extends ImmutablePureComponent { prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />} alwaysPrepend emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} /> diff --git a/app/javascript/flavours/glitch/features/following/index.js b/app/javascript/flavours/glitch/features/following/index.js index f03da0c94..df7c19c22 100644 --- a/app/javascript/flavours/glitch/features/following/index.js +++ b/app/javascript/flavours/glitch/features/following/index.js @@ -33,6 +33,7 @@ class Following extends ImmutablePureComponent { accountIds: ImmutablePropTypes.list, hasMore: PropTypes.bool, isAccount: PropTypes.bool, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -70,7 +71,7 @@ class Following extends ImmutablePureComponent { } render () { - const { accountIds, hasMore, isAccount } = this.props; + const { accountIds, hasMore, isAccount, multiColumn } = this.props; if (!isAccount) { return ( @@ -92,7 +93,7 @@ class Following extends ImmutablePureComponent { return ( <Column ref={this.setRef}> - <ProfileColumnHeader onClick={this.handleHeaderClick} /> + <ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} /> <ScrollableList scrollKey='following' @@ -101,6 +102,7 @@ class Following extends ImmutablePureComponent { prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />} alwaysPrepend emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} /> diff --git a/app/javascript/flavours/glitch/features/getting_started/index.js b/app/javascript/flavours/glitch/features/getting_started/index.js index a5095fbd9..d8a51c689 100644 --- a/app/javascript/flavours/glitch/features/getting_started/index.js +++ b/app/javascript/flavours/glitch/features/getting_started/index.js @@ -166,7 +166,7 @@ const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2); ]); return ( - <Column name='getting-started' icon='asterisk' heading={intl.formatMessage(messages.heading)} label={intl.formatMessage(messages.menu)} hideHeadingOnMobile> + <Column bindToDocument={!multiColumn} name='getting-started' icon='asterisk' heading={intl.formatMessage(messages.heading)} label={intl.formatMessage(messages.menu)} hideHeadingOnMobile> <div className='scrollable optionally-scrollable'> <div className='getting-started__wrapper'> {!multiColumn && <NavigationBar account={myAccount} />} diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/index.js b/app/javascript/flavours/glitch/features/hashtag_timeline/index.js index d39505f46..16dd80c4f 100644 --- a/app/javascript/flavours/glitch/features/hashtag_timeline/index.js +++ b/app/javascript/flavours/glitch/features/hashtag_timeline/index.js @@ -145,6 +145,7 @@ class HashtagTimeline extends React.PureComponent { pinned={pinned} multiColumn={multiColumn} showBackButton + bindToDocument={!multiColumn} > {columnId && <ColumnSettingsContainer columnId={columnId} />} </ColumnHeader> @@ -155,6 +156,7 @@ class HashtagTimeline extends React.PureComponent { timelineId={`hashtag:${id}`} onLoadMore={this.handleLoadMore} emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.js b/app/javascript/flavours/glitch/features/home_timeline/index.js index defb1dcc1..9b71a4404 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/index.js +++ b/app/javascript/flavours/glitch/features/home_timeline/index.js @@ -97,7 +97,7 @@ class HomeTimeline extends React.PureComponent { const pinned = !!columnId; return ( - <Column ref={this.setRef} name='home' label={intl.formatMessage(messages.title)}> + <Column bindToDocument={!multiColumn} ref={this.setRef} name='home' label={intl.formatMessage(messages.title)}> <ColumnHeader icon='home' active={hasUnread} @@ -117,6 +117,7 @@ class HomeTimeline extends React.PureComponent { onLoadMore={this.handleLoadMore} timelineId='home' emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js index 95daa6907..e40dbf44e 100644 --- a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js +++ b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js @@ -25,10 +25,10 @@ class KeyboardShortcuts extends ImmutablePureComponent { }; render () { - const { intl, collapseEnabled } = this.props; + const { intl, collapseEnabled, multiColumn } = this.props; return ( - <Column icon='question' heading={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} icon='question' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <div className='keyboard-shortcuts scrollable optionally-scrollable'> <table> diff --git a/app/javascript/flavours/glitch/features/list_timeline/index.js b/app/javascript/flavours/glitch/features/list_timeline/index.js index 8c3d0af51..908a65597 100644 --- a/app/javascript/flavours/glitch/features/list_timeline/index.js +++ b/app/javascript/flavours/glitch/features/list_timeline/index.js @@ -174,6 +174,7 @@ class ListTimeline extends React.PureComponent { onClick={this.handleHeaderClick} pinned={pinned} multiColumn={multiColumn} + bindToDocument={!multiColumn} > <div className='column-header__links'> <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.handleEditClick}> @@ -212,6 +213,7 @@ class ListTimeline extends React.PureComponent { timelineId={`list:${id}`} onLoadMore={this.handleLoadMore} emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet.' />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/lists/index.js b/app/javascript/flavours/glitch/features/lists/index.js index 79bf2e601..adde3dd5c 100644 --- a/app/javascript/flavours/glitch/features/lists/index.js +++ b/app/javascript/flavours/glitch/features/lists/index.js @@ -40,6 +40,7 @@ class Lists extends ImmutablePureComponent { dispatch: PropTypes.func.isRequired, lists: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -47,7 +48,7 @@ class Lists extends ImmutablePureComponent { } render () { - const { intl, lists } = this.props; + const { intl, lists, multiColumn } = this.props; if (!lists) { return ( @@ -60,7 +61,7 @@ class Lists extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.lists' defaultMessage="You don't have any lists yet. When you create one, it will show up here." />; return ( - <Column icon='bars' heading={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} icon='bars' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <NewListForm /> @@ -69,6 +70,7 @@ class Lists extends ImmutablePureComponent { <ScrollableList scrollKey='lists' emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {lists.map(list => <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} /> diff --git a/app/javascript/flavours/glitch/features/mutes/index.js b/app/javascript/flavours/glitch/features/mutes/index.js index 7c20ca9b9..c27a530d5 100644 --- a/app/javascript/flavours/glitch/features/mutes/index.js +++ b/app/javascript/flavours/glitch/features/mutes/index.js @@ -31,6 +31,7 @@ class Mutes extends ImmutablePureComponent { hasMore: PropTypes.bool, accountIds: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -42,7 +43,7 @@ class Mutes extends ImmutablePureComponent { }, 300, { leading: true }); render () { - const { intl, accountIds, hasMore } = this.props; + const { intl, accountIds, hasMore, multiColumn } = this.props; if (!accountIds) { return ( @@ -55,13 +56,14 @@ class Mutes extends ImmutablePureComponent { const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />; return ( - <Column name='mutes' icon='volume-off' heading={intl.formatMessage(messages.heading)}> + <Column bindToDocument={!multiColumn} name='mutes' icon='volume-off' heading={intl.formatMessage(messages.heading)}> <ColumnBackButtonSlim /> <ScrollableList scrollKey='mutes' onLoadMore={this.handleLoadMore} hasMore={hasMore} emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} /> diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index 99b2391c7..7f06d70c5 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -226,6 +226,7 @@ class Notifications extends React.PureComponent { onScrollToTop={this.handleScrollToTop} onScroll={this.handleScroll} shouldUpdateScroll={shouldUpdateScroll} + bindToDocument={!multiColumn} > {scrollableContent} </ScrollableList> @@ -233,6 +234,7 @@ class Notifications extends React.PureComponent { return ( <Column + bindToDocument={!multiColumn} ref={this.setColumnRef} name='notifications' extraClasses={this.props.notifCleaningActive ? 'notif-cleaning' : null} diff --git a/app/javascript/flavours/glitch/features/pinned_statuses/index.js b/app/javascript/flavours/glitch/features/pinned_statuses/index.js index 8d406ddf4..34d8e465f 100644 --- a/app/javascript/flavours/glitch/features/pinned_statuses/index.js +++ b/app/javascript/flavours/glitch/features/pinned_statuses/index.js @@ -27,6 +27,7 @@ class PinnedStatuses extends ImmutablePureComponent { statusIds: ImmutablePropTypes.list.isRequired, intl: PropTypes.object.isRequired, hasMore: PropTypes.bool.isRequired, + multiColumn: PropTypes.bool, }; componentWillMount () { @@ -42,15 +43,16 @@ class PinnedStatuses extends ImmutablePureComponent { } render () { - const { intl, statusIds, hasMore } = this.props; + const { intl, statusIds, hasMore, multiColumn } = this.props; return ( - <Column icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}> + <Column bindToDocument={!multiColumn} icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}> <ColumnBackButtonSlim /> <StatusList statusIds={statusIds} scrollKey='pinned_statuses' hasMore={hasMore} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/public_timeline/index.js b/app/javascript/flavours/glitch/features/public_timeline/index.js index 4bcf3da9d..49a5011c0 100644 --- a/app/javascript/flavours/glitch/features/public_timeline/index.js +++ b/app/javascript/flavours/glitch/features/public_timeline/index.js @@ -104,7 +104,7 @@ class PublicTimeline extends React.PureComponent { const pinned = !!columnId; return ( - <Column ref={this.setRef} name='federated' label={intl.formatMessage(messages.title)}> + <Column bindToDocument={!multiColumn} ref={this.setRef} name='federated' label={intl.formatMessage(messages.title)}> <ColumnHeader icon='globe' active={hasUnread} @@ -124,6 +124,7 @@ class PublicTimeline extends React.PureComponent { trackScroll={!pinned} scrollKey={`public_timeline-${columnId}`} emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' />} + bindToDocument={!multiColumn} /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/reblogs/index.js b/app/javascript/flavours/glitch/features/reblogs/index.js index a8e9db7f5..258070358 100644 --- a/app/javascript/flavours/glitch/features/reblogs/index.js +++ b/app/javascript/flavours/glitch/features/reblogs/index.js @@ -6,6 +6,7 @@ import LoadingIndicator from 'flavours/glitch/components/loading_indicator'; import { fetchReblogs } from 'flavours/glitch/actions/interactions'; import AccountContainer from 'flavours/glitch/containers/account_container'; import Column from 'flavours/glitch/features/ui/components/column'; +import Icon from 'flavours/glitch/components/icon'; import ColumnHeader from 'flavours/glitch/components/column_header'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -13,6 +14,7 @@ import ScrollableList from 'flavours/glitch/components/scrollable_list'; const messages = defineMessages({ heading: { id: 'column.reblogged_by', defaultMessage: 'Boosted by' }, + refresh: { id: 'refresh', defaultMessage: 'Refresh' }, }); const mapStateToProps = (state, props) => ({ @@ -27,6 +29,7 @@ class Reblogs extends ImmutablePureComponent { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, accountIds: ImmutablePropTypes.list, + multiColumn: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -50,8 +53,12 @@ class Reblogs extends ImmutablePureComponent { this.column = c; } + handleRefresh = () => { + this.props.dispatch(fetchReblogs(this.props.params.statusId)); + } + render () { - const { intl, accountIds } = this.props; + const { intl, accountIds, multiColumn } = this.props; if (!accountIds) { return ( @@ -70,11 +77,16 @@ class Reblogs extends ImmutablePureComponent { title={intl.formatMessage(messages.heading)} onClick={this.handleHeaderClick} showBackButton + multiColumn={multiColumn} + extraButton={( + <button className='column-header__button' title={intl.formatMessage(messages.refresh)} aria-label={intl.formatMessage(messages.refresh)} onClick={this.handleRefresh}><Icon id='refresh' /></button> + )} /> <ScrollableList scrollKey='reblogs' emptyMessage={emptyMessage} + bindToDocument={!multiColumn} > {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} /> diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index dd17823ad..508510c4e 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -155,6 +155,7 @@ class Status extends ImmutablePureComponent { descendantsIds: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, askReplyConfirmation: PropTypes.bool, + multiColumn: PropTypes.bool, domain: PropTypes.string.isRequired, }; @@ -497,13 +498,13 @@ class Status extends ImmutablePureComponent { render () { let ancestors, descendants; const { setExpansion } = this; - const { status, settings, ancestorsIds, descendantsIds, intl, domain } = this.props; + const { status, settings, ancestorsIds, descendantsIds, intl, domain, multiColumn } = this.props; const { fullscreen, isExpanded } = this.state; if (status === null) { return ( <Column> - <ColumnBackButton /> + <ColumnBackButton multiColumn={multiColumn} /> <MissingIndicator /> </Column> ); @@ -531,12 +532,13 @@ class Status extends ImmutablePureComponent { }; return ( - <Column ref={this.setColumnRef} label={intl.formatMessage(messages.detailedStatus)}> + <Column bindToDocument={!multiColumn} ref={this.setColumnRef} label={intl.formatMessage(messages.detailedStatus)}> <ColumnHeader icon='comment' title={intl.formatMessage(messages.tootHeading)} onClick={this.handleHeaderClick} showBackButton + multiColumn={multiColumn} extraButton={( <button className='column-header__button' title={intl.formatMessage(!isExpanded ? messages.revealAll : messages.hideAll)} aria-label={intl.formatMessage(!isExpanded ? messages.revealAll : messages.hideAll)} onClick={this.handleToggleAll} aria-pressed={!isExpanded ? 'false' : 'true'}><Icon id={status.get('hidden') ? 'eye-slash' : 'eye'} /></button> )} diff --git a/app/javascript/flavours/glitch/features/ui/components/column_loading.js b/app/javascript/flavours/glitch/features/ui/components/column_loading.js index ba2d0824e..22c00c915 100644 --- a/app/javascript/flavours/glitch/features/ui/components/column_loading.js +++ b/app/javascript/flavours/glitch/features/ui/components/column_loading.js @@ -21,7 +21,7 @@ export default class ColumnLoading extends ImmutablePureComponent { let { title, icon } = this.props; return ( <Column> - <ColumnHeader icon={icon} title={title} multiColumn={false} focusable={false} /> + <ColumnHeader icon={icon} title={title} multiColumn={false} focusable={false} placeholder /> <div className='scrollable' /> </Column> ); diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js index 117ce4c55..488daf0cc 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Base from '../../../components/modal_root'; +import { getScrollbarWidth } from 'flavours/glitch/util/scrollbar'; +import Base from 'flavours/glitch/components/modal_root'; import BundleContainer from '../containers/bundle_container'; import BundleModalError from './bundle_modal_error'; import ModalLoading from './modal_loading'; @@ -61,8 +62,10 @@ export default class ModalRoot extends React.PureComponent { componentDidUpdate (prevProps, prevState, { visible }) { if (visible) { document.body.classList.add('with-modals--active'); + document.documentElement.style.marginRight = `${getScrollbarWidth()}px`; } else { document.body.classList.remove('with-modals--active'); + document.documentElement.style.marginRight = 0; } } diff --git a/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js b/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js index 90e645a82..a67405215 100644 --- a/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js +++ b/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js @@ -73,9 +73,13 @@ class TabsBar extends React.PureComponent { const { intl: { formatMessage } } = this.props; return ( - <nav className='tabs-bar' ref={this.setRef}> - {links.map(link => React.cloneElement(link, { key: link.props.to, onClick: this.handleClick, 'aria-label': formatMessage({ id: link.props['data-preview-title-id'] }) }))} - </nav> + <div className='tabs-bar__wrapper'> + <nav className='tabs-bar' ref={this.setRef}> + {links.map(link => React.cloneElement(link, { key: link.props.to, onClick: this.handleClick, 'aria-label': formatMessage({ id: link.props['data-preview-title-id'] }) }))} + </nav> + + <div id='tabs-bar__portal' /> + </div> ); } diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index c201cd93d..e5925a484 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -129,12 +129,25 @@ class SwitchingColumnsArea extends React.PureComponent { componentWillMount () { window.addEventListener('resize', this.handleResize, { passive: true }); + + if (this.state.mobile) { + document.body.classList.toggle('layout-single-column', true); + document.body.classList.toggle('layout-multiple-columns', false); + } else { + document.body.classList.toggle('layout-single-column', false); + document.body.classList.toggle('layout-multiple-columns', true); + } } - componentDidUpdate (prevProps) { + componentDidUpdate (prevProps, prevState) { if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) { this.node.handleChildrenContentChange(); } + + if (prevState.mobile !== this.state.mobile) { + document.body.classList.toggle('layout-single-column', this.state.mobile); + document.body.classList.toggle('layout-multiple-columns', !this.state.mobile); + } } componentWillUnmount () { |