Merge branch 'develop' into bugfix/patch-fix-mention-button-mobile
This commit is contained in:
@@ -208,7 +208,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
return [
|
||||
<div className='compose-form__autosuggest-wrapper'>
|
||||
<div className='compose-form__autosuggest-wrapper' key='compose-form__autosuggest-wrapper'>
|
||||
<div className='autosuggest-textarea'>
|
||||
<label>
|
||||
<span style={{ display: 'none' }}>{placeholder}</span>
|
||||
@@ -233,7 +233,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||
</div>
|
||||
{children}
|
||||
</div>,
|
||||
<div className='autosuggest-textarea__suggestions-wrapper'>
|
||||
<div className='autosuggest-textarea__suggestions-wrapper' key='autosuggest-textarea__suggestions-wrapper'>
|
||||
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
|
||||
{suggestions.map(this.renderSuggestion)}
|
||||
</div>
|
||||
|
||||
109
app/javascript/gabsocial/components/home_column_header.js
Normal file
109
app/javascript/gabsocial/components/home_column_header.js
Normal file
@@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Icon from 'gabsocial/components/icon';
|
||||
|
||||
const messages = defineMessages({
|
||||
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
|
||||
hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
|
||||
homeTitle: { id: 'home_column_header.home', defaultMessage: 'Home' },
|
||||
allTitle: { id: 'home_column_header.all', defaultMessage: 'All' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
class ColumnHeader extends React.PureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
active: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
activeItem: PropTypes.string,
|
||||
};
|
||||
|
||||
state = {
|
||||
collapsed: true,
|
||||
animating: false,
|
||||
};
|
||||
|
||||
handleToggleClick = (e) => {
|
||||
e.stopPropagation();
|
||||
this.setState({ collapsed: !this.state.collapsed, animating: true });
|
||||
}
|
||||
|
||||
handleTransitionEnd = () => {
|
||||
this.setState({ animating: false });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { active, children, intl: { formatMessage }, activeItem } = this.props;
|
||||
const { collapsed, animating } = this.state;
|
||||
|
||||
const wrapperClassName = classNames('column-header__wrapper', {
|
||||
'active': active,
|
||||
});
|
||||
|
||||
const buttonClassName = classNames('column-header', {
|
||||
'active': active,
|
||||
});
|
||||
|
||||
const collapsibleClassName = classNames('column-header__collapsible', {
|
||||
'collapsed': collapsed,
|
||||
'animating': animating,
|
||||
});
|
||||
|
||||
const collapsibleButtonClassName = classNames('column-header__button', {
|
||||
'active': !collapsed,
|
||||
});
|
||||
|
||||
let extraContent, collapseButton;
|
||||
|
||||
if (children) {
|
||||
extraContent = (
|
||||
<div key='extra-content' className='column-header__collapsible__extra'>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
collapseButton = <button className={collapsibleButtonClassName} title={formatMessage(collapsed ? messages.show : messages.hide)} aria-label={formatMessage(collapsed ? messages.show : messages.hide)} aria-pressed={collapsed ? 'false' : 'true'} onClick={this.handleToggleClick}><Icon id='sliders' /></button>;
|
||||
}
|
||||
|
||||
const collapsedContent = [
|
||||
extraContent,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={wrapperClassName}>
|
||||
<h1 className={buttonClassName}>
|
||||
<Link to='/home' className={classNames('btn grouped', {'active': 'home' === activeItem})}>
|
||||
<Icon id='home' fixedWidth className='column-header__icon' />
|
||||
{formatMessage(messages.homeTitle)}
|
||||
</Link>
|
||||
|
||||
<Link to='/timeline/all' className={classNames('btn grouped', {'active': 'all' === activeItem})}>
|
||||
<Icon id='globe' fixedWidth className='column-header__icon' />
|
||||
{formatMessage(messages.allTitle)}
|
||||
</Link>
|
||||
|
||||
<div className='column-header__buttons'>
|
||||
{collapseButton}
|
||||
</div>
|
||||
</h1>
|
||||
|
||||
<div className={collapsibleClassName} tabIndex={collapsed ? -1 : null} onTransitionEnd={this.handleTransitionEnd}>
|
||||
<div className='column-header__collapsible-inner'>
|
||||
{(!collapsed || animating) && collapsedContent}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import StatusListContainer from '../ui/containers/status_list_container';
|
||||
import Column from '../../components/column';
|
||||
import ColumnHeader from '../../components/column_header';
|
||||
import { expandCommunityTimeline } from '../../actions/timelines';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import { connectCommunityStream } from '../../actions/streaming';
|
||||
import HomeColumnHeader from '../../components/home_column_header';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.community', defaultMessage: 'Local timeline' },
|
||||
@@ -79,14 +79,12 @@ class CommunityTimeline extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.title)}>
|
||||
<ColumnHeader
|
||||
icon='users'
|
||||
<HomeColumnHeader
|
||||
activeItem='all'
|
||||
active={hasUnread}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
>
|
||||
<ColumnSettingsContainer columnId={columnId} />
|
||||
</ColumnHeader>
|
||||
|
||||
<ColumnSettingsContainer />
|
||||
</HomeColumnHeader>
|
||||
<StatusListContainer
|
||||
scrollKey={`community_timeline-${columnId}`}
|
||||
timelineId={`community${onlyMedia ? ':media' : ''}`}
|
||||
|
||||
@@ -4,13 +4,9 @@ import { expandHomeTimeline } from '../../actions/timelines';
|
||||
import PropTypes from 'prop-types';
|
||||
import StatusListContainer from '../ui/containers/status_list_container';
|
||||
import Column from '../../components/column';
|
||||
import ColumnHeader from '../../components/column_header';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { me } from '../../initial_state';
|
||||
import ComposeFormContainer from '../compose/containers/compose_form_container';
|
||||
import Avatar from '../../components/avatar';
|
||||
import HomeColumnHeader from '../../components/home_column_header';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.home', defaultMessage: 'Home' },
|
||||
@@ -19,7 +15,6 @@ const messages = defineMessages({
|
||||
const mapStateToProps = state => ({
|
||||
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
||||
isPartial: state.getIn(['timelines', 'home', 'isPartial']),
|
||||
account: state.getIn(['accounts', me]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@@ -72,22 +67,16 @@ class HomeTimeline extends React.PureComponent {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, hasUnread, columnId, account } = this.props;
|
||||
const { intl, hasUnread, columnId } = this.props;
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.title)}>
|
||||
|
||||
<div className='timeline-compose-block'>
|
||||
<div className='timeline-compose-block__avatar'>
|
||||
<Avatar account={account} size={46} />
|
||||
</div>
|
||||
<ComposeFormContainer shouldCondense={true} autoFocus={false}/>
|
||||
</div>
|
||||
|
||||
<ColumnHeader icon='home' active={hasUnread} title={intl.formatMessage(messages.title)}>
|
||||
<HomeColumnHeader
|
||||
activeItem='home'
|
||||
active={hasUnread}
|
||||
>
|
||||
<ColumnSettingsContainer />
|
||||
</ColumnHeader>
|
||||
|
||||
</HomeColumnHeader>
|
||||
<StatusListContainer
|
||||
scrollKey={`home_timeline-${columnId}`}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
|
||||
@@ -64,6 +64,10 @@ class Notifications extends React.PureComponent {
|
||||
this.props.dispatch(scrollTopNotifications(false));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(scrollTopNotifications(true));
|
||||
}
|
||||
|
||||
handleLoadGap = (maxId) => {
|
||||
this.props.dispatch(expandNotifications({ maxId }));
|
||||
};
|
||||
|
||||
@@ -24,17 +24,14 @@ import TabsBar from './components/tabs_bar';
|
||||
// import TrendsPanel from './components/trends_panel';
|
||||
import WhoToFollowPanel from './components/who_to_follow_panel';
|
||||
import LinkFooter from './components/link_footer';
|
||||
import ProfileInfoPanel from './components/profile_info_panel';
|
||||
import UserPanel from './components/user_panel';
|
||||
import PromoPanel from './components/promo_panel';
|
||||
import ProfilePage from 'gabsocial/pages/profile_page';
|
||||
import SearchPage from 'gabsocial/pages/search_page';
|
||||
import HomePage from 'gabsocial/pages/home_page';
|
||||
|
||||
import {
|
||||
Compose,
|
||||
Status,
|
||||
GettingStarted,
|
||||
PublicTimeline,
|
||||
CommunityTimeline,
|
||||
AccountTimeline,
|
||||
AccountGallery,
|
||||
@@ -110,17 +107,6 @@ const LAYOUT = {
|
||||
LEFT: null,
|
||||
RIGHT: null,
|
||||
},
|
||||
HOME: {
|
||||
LEFT: [
|
||||
<UserPanel />,
|
||||
<PromoPanel />,
|
||||
<LinkFooter />,
|
||||
],
|
||||
RIGHT: [
|
||||
// <TrendsPanel />,
|
||||
<WhoToFollowPanel />,
|
||||
],
|
||||
},
|
||||
DEFAULT: {
|
||||
LEFT: [
|
||||
<WhoToFollowPanel />,
|
||||
@@ -181,7 +167,8 @@ class SwitchingColumnsArea extends React.PureComponent {
|
||||
return (
|
||||
<Switch>
|
||||
<Redirect from='/' to='/home' exact />
|
||||
<WrappedRoute path='/home' exact layout={LAYOUT.HOME} component={HomeTimeline} content={children} />
|
||||
<WrappedRoute path='/home' exact page={HomePage} component={HomeTimeline} content={children} />
|
||||
<WrappedRoute path='/timeline/all' exact page={HomePage} component={CommunityTimeline} content={children} />
|
||||
|
||||
<WrappedRoute path='/groups' component={Groups} content={children} />
|
||||
<WrappedRoute path='/groups/:id' component={GroupTimeline} content={children} />
|
||||
|
||||
58
app/javascript/gabsocial/pages/home_page.js
Normal file
58
app/javascript/gabsocial/pages/home_page.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { me } from 'gabsocial/initial_state';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import WhoToFollowPanel from '../features/ui/components/who_to_follow_panel';
|
||||
import LinkFooter from '../features/ui/components/link_footer';
|
||||
import PromoPanel from '../features/ui/components/promo_panel';
|
||||
import UserPanel from '../features/ui/components/user_panel';
|
||||
import ComposeFormContainer from '../features/compose/containers/compose_form_container';
|
||||
import Avatar from '../components/avatar';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
account: state.getIn(['accounts', me]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class HomePage extends ImmutablePureComponent {
|
||||
render () {
|
||||
const {children, account} = this.props;
|
||||
|
||||
return (
|
||||
<div className='page'>
|
||||
<div className='page__columns'>
|
||||
<div className='columns-area__panels'>
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<UserPanel />
|
||||
<PromoPanel />
|
||||
<LinkFooter />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__main'>
|
||||
<div className='columns-area columns-area--mobile'>
|
||||
<div className='timeline-compose-block'>
|
||||
<div className='timeline-compose-block__avatar'>
|
||||
<Avatar account={account} size={46} />
|
||||
</div>
|
||||
<ComposeFormContainer shouldCondense={true} autoFocus={false}/>
|
||||
</div>
|
||||
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<WhoToFollowPanel />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@
|
||||
align-items: flex-start;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 10px;
|
||||
background: $gab-background-container;
|
||||
body.theme-gabsocial-light & {
|
||||
@include light-theme-shadow();
|
||||
@@ -1475,7 +1475,8 @@ a.account__display-name {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
.column,
|
||||
.drawer {
|
||||
width: 100%;
|
||||
@@ -2445,6 +2446,9 @@ a.status-card.compact:hover {
|
||||
.column-header__wrapper {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
border-top-right-radius: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
&.active {
|
||||
&::before {
|
||||
@@ -2481,18 +2485,29 @@ a.status-card.compact:hover {
|
||||
outline: 0;
|
||||
overflow: hidden;
|
||||
|
||||
& > button {
|
||||
& > button,
|
||||
& > .btn {
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 15px 0 15px 15px;
|
||||
padding: 15px;
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
|
||||
&.grouped {
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $primary-text-color;
|
||||
border-radius: 10px;
|
||||
background-color: rgba($highlight-text-color, .1);
|
||||
}
|
||||
}
|
||||
|
||||
& > .column-header__back-button {
|
||||
@@ -2517,6 +2532,7 @@ a.status-card.compact:hover {
|
||||
.column-header__buttons {
|
||||
height: 48px;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.column-header__links .text-btn {
|
||||
|
||||
Reference in New Issue
Block a user