Compare commits
4 Commits
main
...
unify-time
Author | SHA1 | Date |
---|---|---|
kibigo! | 4d0fde3d93 | |
kibigo! | ff0ecca84c | |
kibigo! | cdd7f792cb | |
kibigo! | 77908849bb |
|
@ -1,144 +1,44 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
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 {
|
||||
refreshCommunityTimeline,
|
||||
expandCommunityTimeline,
|
||||
updateTimeline,
|
||||
deleteFromTimelines,
|
||||
connectTimeline,
|
||||
disconnectTimeline,
|
||||
} from '../../actions/timelines';
|
||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import createStream from '../../stream';
|
||||
import Timeline from '../timeline';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.community', defaultMessage: 'Local timeline' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
hasUnread: state.getIn(['timelines', 'community', 'unread']) > 0,
|
||||
streamingAPIBaseURL: state.getIn(['meta', 'streaming_api_base_url']),
|
||||
accessToken: state.getIn(['meta', 'access_token']),
|
||||
});
|
||||
|
||||
@connect(mapStateToProps)
|
||||
@injectIntl
|
||||
export default class CommunityTimeline extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
columnId: PropTypes.string,
|
||||
intl: PropTypes.object.isRequired,
|
||||
streamingAPIBaseURL: PropTypes.string.isRequired,
|
||||
accessToken: PropTypes.string.isRequired,
|
||||
hasUnread: PropTypes.bool,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
handlePin = () => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
|
||||
if (columnId) {
|
||||
dispatch(removeColumn(columnId));
|
||||
} else {
|
||||
dispatch(addColumn('COMMUNITY', {}));
|
||||
}
|
||||
}
|
||||
|
||||
handleMove = (dir) => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
dispatch(moveColumn(columnId, dir));
|
||||
}
|
||||
|
||||
handleHeaderClick = () => {
|
||||
this.column.scrollTop();
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch, streamingAPIBaseURL, accessToken } = this.props;
|
||||
|
||||
dispatch(refreshCommunityTimeline());
|
||||
|
||||
if (typeof this._subscription !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
this._subscription = createStream(streamingAPIBaseURL, accessToken, 'public:local', {
|
||||
|
||||
connected () {
|
||||
dispatch(connectTimeline('community'));
|
||||
},
|
||||
|
||||
reconnected () {
|
||||
dispatch(connectTimeline('community'));
|
||||
},
|
||||
|
||||
disconnected () {
|
||||
dispatch(disconnectTimeline('community'));
|
||||
},
|
||||
|
||||
received (data) {
|
||||
switch(data.event) {
|
||||
case 'update':
|
||||
dispatch(updateTimeline('community', JSON.parse(data.payload)));
|
||||
break;
|
||||
case 'delete':
|
||||
dispatch(deleteFromTimelines(data.payload));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (typeof this._subscription !== 'undefined') {
|
||||
this._subscription.close();
|
||||
this._subscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.column = c;
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
this.props.dispatch(expandCommunityTimeline());
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
||||
const pinned = !!columnId;
|
||||
const { intl, columnId, multiColumn } = this.props;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ColumnHeader
|
||||
icon='users'
|
||||
active={hasUnread}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
onPin={this.handlePin}
|
||||
onMove={this.handleMove}
|
||||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
>
|
||||
<ColumnSettingsContainer />
|
||||
</ColumnHeader>
|
||||
|
||||
<StatusListContainer
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`community_timeline-${columnId}`}
|
||||
timelineId='community'
|
||||
loadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />}
|
||||
/>
|
||||
</Column>
|
||||
<Timeline
|
||||
expand={expandCommunityTimeline}
|
||||
refresh={refreshCommunityTimeline}
|
||||
streamId='public:local'
|
||||
columnName='COMMUNITY'
|
||||
columnId={columnId}
|
||||
mulitColumn={multiColumn}
|
||||
emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />}
|
||||
icon='users'
|
||||
title={intl.formatMessage(messages.title)}
|
||||
settings={<ColumnSettingsContainer />}
|
||||
scrollName='community_timeline'
|
||||
timelineId='community'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,138 +1,53 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
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 {
|
||||
refreshHashtagTimeline,
|
||||
expandHashtagTimeline,
|
||||
updateTimeline,
|
||||
deleteFromTimelines,
|
||||
} from '../../actions/timelines';
|
||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import createStream from '../../stream';
|
||||
import Timeline from '../timeline';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
hasUnread: state.getIn(['timelines', 'tag', 'unread']) > 0,
|
||||
streamingAPIBaseURL: state.getIn(['meta', 'streaming_api_base_url']),
|
||||
accessToken: state.getIn(['meta', 'access_token']),
|
||||
});
|
||||
|
||||
@connect(mapStateToProps)
|
||||
export default class HashtagTimeline extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
columnId: PropTypes.string,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
streamingAPIBaseURL: PropTypes.string.isRequired,
|
||||
accessToken: PropTypes.string.isRequired,
|
||||
hasUnread: PropTypes.bool,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
handlePin = () => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
|
||||
if (columnId) {
|
||||
dispatch(removeColumn(columnId));
|
||||
} else {
|
||||
dispatch(addColumn('HASHTAG', { id: this.props.params.id }));
|
||||
}
|
||||
}
|
||||
|
||||
handleMove = (dir) => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
dispatch(moveColumn(columnId, dir));
|
||||
}
|
||||
|
||||
handleHeaderClick = () => {
|
||||
this.column.scrollTop();
|
||||
}
|
||||
|
||||
_subscribe (dispatch, id) {
|
||||
const { streamingAPIBaseURL, accessToken } = this.props;
|
||||
|
||||
this.subscription = createStream(streamingAPIBaseURL, accessToken, `hashtag&tag=${id}`, {
|
||||
|
||||
received (data) {
|
||||
switch(data.event) {
|
||||
case 'update':
|
||||
dispatch(updateTimeline(`hashtag:${id}`, JSON.parse(data.payload)));
|
||||
break;
|
||||
case 'delete':
|
||||
dispatch(deleteFromTimelines(data.payload));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
_unsubscribe () {
|
||||
if (typeof this.subscription !== 'undefined') {
|
||||
this.subscription.close();
|
||||
this.subscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch } = this.props;
|
||||
const { id } = this.props.params;
|
||||
|
||||
dispatch(refreshHashtagTimeline(id));
|
||||
this._subscribe(dispatch, id);
|
||||
componentWillMount () {
|
||||
const id = this.props.params.id;
|
||||
this.expand = () => expandHashtagTimeline(id);
|
||||
this.refresh = () => refreshHashtagTimeline(id);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.props.dispatch(refreshHashtagTimeline(nextProps.params.id));
|
||||
this._unsubscribe();
|
||||
this._subscribe(this.props.dispatch, nextProps.params.id);
|
||||
const id = nextProps.params.id;
|
||||
this.expand = () => expandHashtagTimeline(id);
|
||||
this.refresh = () => refreshHashtagTimeline(id);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this._unsubscribe();
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.column = c;
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
this.props.dispatch(expandHashtagTimeline(this.props.params.id));
|
||||
}
|
||||
|
||||
render () {
|
||||
const { hasUnread, columnId, multiColumn } = this.props;
|
||||
const { columnId, multiColumn } = this.props;
|
||||
const { id } = this.props.params;
|
||||
const pinned = !!columnId;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ColumnHeader
|
||||
icon='hashtag'
|
||||
active={hasUnread}
|
||||
title={id}
|
||||
onPin={this.handlePin}
|
||||
onMove={this.handleMove}
|
||||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
showBackButton
|
||||
/>
|
||||
|
||||
<StatusListContainer
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`hashtag_timeline-${columnId}`}
|
||||
timelineId={`hashtag:${id}`}
|
||||
loadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
|
||||
/>
|
||||
</Column>
|
||||
<Timeline
|
||||
expand={this.expand}
|
||||
refresh={this.refresh}
|
||||
streamId={`hashtag&tag=${id}`}
|
||||
columnName='HASHTAG'
|
||||
columnProps={{ id }}
|
||||
columnId={columnId}
|
||||
mulitColumn={multiColumn}
|
||||
emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
|
||||
icon='hashtag'
|
||||
title={id}
|
||||
scrollName='hashtag_timeline'
|
||||
timelineId={`hashtag:${id}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,9 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
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 { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import Timeline from '../timeline';
|
||||
import Link from 'react-router-dom/Link';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -15,7 +12,6 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
||||
hasFollows: state.getIn(['accounts_counters', state.getIn(['meta', 'me']), 'following_count']) > 0,
|
||||
});
|
||||
|
||||
|
@ -24,44 +20,14 @@ const mapStateToProps = state => ({
|
|||
export default class HomeTimeline extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
hasUnread: PropTypes.bool,
|
||||
hasFollows: PropTypes.bool,
|
||||
columnId: PropTypes.string,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
handlePin = () => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
|
||||
if (columnId) {
|
||||
dispatch(removeColumn(columnId));
|
||||
} else {
|
||||
dispatch(addColumn('HOME', {}));
|
||||
}
|
||||
}
|
||||
|
||||
handleMove = (dir) => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
dispatch(moveColumn(columnId, dir));
|
||||
}
|
||||
|
||||
handleHeaderClick = () => {
|
||||
this.column.scrollTop();
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.column = c;
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
this.props.dispatch(expandHomeTimeline());
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, hasUnread, hasFollows, columnId, multiColumn } = this.props;
|
||||
const pinned = !!columnId;
|
||||
const { intl, hasFollows, columnId, multiColumn } = this.props;
|
||||
|
||||
let emptyMessage;
|
||||
|
||||
|
@ -72,28 +38,18 @@ export default class HomeTimeline extends React.PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ColumnHeader
|
||||
icon='home'
|
||||
active={hasUnread}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
onPin={this.handlePin}
|
||||
onMove={this.handleMove}
|
||||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
>
|
||||
<ColumnSettingsContainer />
|
||||
</ColumnHeader>
|
||||
|
||||
<StatusListContainer
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`home_timeline-${columnId}`}
|
||||
loadMore={this.handleLoadMore}
|
||||
timelineId='home'
|
||||
emptyMessage={emptyMessage}
|
||||
/>
|
||||
</Column>
|
||||
<Timeline
|
||||
expand={expandHomeTimeline}
|
||||
columnName='HOME'
|
||||
columnId={columnId}
|
||||
mulitColumn={multiColumn}
|
||||
emptyMessage={emptyMessage}
|
||||
icon='home'
|
||||
title={intl.formatMessage(messages.title)}
|
||||
settings={<ColumnSettingsContainer />}
|
||||
scrollName='home_timeline'
|
||||
timelineId='home'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,144 +1,44 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
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 {
|
||||
refreshPublicTimeline,
|
||||
expandPublicTimeline,
|
||||
updateTimeline,
|
||||
deleteFromTimelines,
|
||||
connectTimeline,
|
||||
disconnectTimeline,
|
||||
} from '../../actions/timelines';
|
||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import createStream from '../../stream';
|
||||
import Timeline from '../timeline';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.public', defaultMessage: 'Federated timeline' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
hasUnread: state.getIn(['timelines', 'public', 'unread']) > 0,
|
||||
streamingAPIBaseURL: state.getIn(['meta', 'streaming_api_base_url']),
|
||||
accessToken: state.getIn(['meta', 'access_token']),
|
||||
});
|
||||
|
||||
@connect(mapStateToProps)
|
||||
@injectIntl
|
||||
export default class PublicTimeline extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
columnId: PropTypes.string,
|
||||
multiColumn: PropTypes.bool,
|
||||
streamingAPIBaseURL: PropTypes.string.isRequired,
|
||||
accessToken: PropTypes.string.isRequired,
|
||||
hasUnread: PropTypes.bool,
|
||||
};
|
||||
|
||||
handlePin = () => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
|
||||
if (columnId) {
|
||||
dispatch(removeColumn(columnId));
|
||||
} else {
|
||||
dispatch(addColumn('PUBLIC', {}));
|
||||
}
|
||||
}
|
||||
|
||||
handleMove = (dir) => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
dispatch(moveColumn(columnId, dir));
|
||||
}
|
||||
|
||||
handleHeaderClick = () => {
|
||||
this.column.scrollTop();
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch, streamingAPIBaseURL, accessToken } = this.props;
|
||||
|
||||
dispatch(refreshPublicTimeline());
|
||||
|
||||
if (typeof this._subscription !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
this._subscription = createStream(streamingAPIBaseURL, accessToken, 'public', {
|
||||
|
||||
connected () {
|
||||
dispatch(connectTimeline('public'));
|
||||
},
|
||||
|
||||
reconnected () {
|
||||
dispatch(connectTimeline('public'));
|
||||
},
|
||||
|
||||
disconnected () {
|
||||
dispatch(disconnectTimeline('public'));
|
||||
},
|
||||
|
||||
received (data) {
|
||||
switch(data.event) {
|
||||
case 'update':
|
||||
dispatch(updateTimeline('public', JSON.parse(data.payload)));
|
||||
break;
|
||||
case 'delete':
|
||||
dispatch(deleteFromTimelines(data.payload));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (typeof this._subscription !== 'undefined') {
|
||||
this._subscription.close();
|
||||
this._subscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.column = c;
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
this.props.dispatch(expandPublicTimeline());
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, columnId, hasUnread, multiColumn } = this.props;
|
||||
const pinned = !!columnId;
|
||||
const { intl, columnId, multiColumn } = this.props;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ColumnHeader
|
||||
icon='globe'
|
||||
active={hasUnread}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
onPin={this.handlePin}
|
||||
onMove={this.handleMove}
|
||||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
>
|
||||
<ColumnSettingsContainer />
|
||||
</ColumnHeader>
|
||||
|
||||
<StatusListContainer
|
||||
timelineId='public'
|
||||
loadMore={this.handleLoadMore}
|
||||
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 instances to fill it up' />}
|
||||
/>
|
||||
</Column>
|
||||
<Timeline
|
||||
expand={expandPublicTimeline}
|
||||
refresh={refreshPublicTimeline}
|
||||
streamId='public'
|
||||
columnName='PUBLIC'
|
||||
columnId={columnId}
|
||||
mulitColumn={multiColumn}
|
||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
|
||||
icon='globe'
|
||||
title={intl.formatMessage(messages.title)}
|
||||
settings={<ColumnSettingsContainer />}
|
||||
scrollName='public_timeline'
|
||||
timelineId='public'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
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 {
|
||||
updateTimeline,
|
||||
deleteFromTimelines,
|
||||
connectTimeline,
|
||||
disconnectTimeline,
|
||||
} from '../../actions/timelines';
|
||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import createStream from '../../stream';
|
||||
|
||||
const mapStateToProps = (state, ownprops) => ({
|
||||
streamingAPIBaseURL: state.getIn(['meta', 'streaming_api_base_url']),
|
||||
accessToken: state.getIn(['meta', 'access_token']),
|
||||
hasUnread: state.getIn(['timelines', ownprops.timelineId, 'unread']) > 0,
|
||||
});
|
||||
|
||||
@connect(mapStateToProps)
|
||||
export default class Timeline extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
streamingAPIBaseURL: PropTypes.string.isRequired,
|
||||
accessToken: PropTypes.string.isRequired,
|
||||
expand: PropTypes.func.isRequired,
|
||||
refresh: PropTypes.func,
|
||||
streamId: PropTypes.string,
|
||||
hasUnread: PropTypes.bool,
|
||||
columnName: PropTypes.string.isRequired,
|
||||
columnProps: PropTypes.object,
|
||||
columnId: PropTypes.string,
|
||||
multiColumn: PropTypes.bool,
|
||||
emptyMessage: PropTypes.oneOfType([
|
||||
PropTypes.element,
|
||||
PropTypes.string,
|
||||
]),
|
||||
icon: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
settings: PropTypes.element,
|
||||
scrollName: PropTypes.string.isRequired,
|
||||
timelineId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
handlePin = () => {
|
||||
const { columnName, columnProps, columnId, dispatch } = this.props;
|
||||
|
||||
if (columnId) {
|
||||
dispatch(removeColumn(columnId));
|
||||
} else {
|
||||
dispatch(addColumn(columnName, columnProps || {}));
|
||||
}
|
||||
}
|
||||
|
||||
handleMove = (dir) => {
|
||||
const { columnId, dispatch } = this.props;
|
||||
dispatch(moveColumn(columnId, dir));
|
||||
}
|
||||
|
||||
handleHeaderClick = () => {
|
||||
this.column.scrollTop();
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.column = c;
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
this.props.dispatch(this.props.expand());
|
||||
}
|
||||
|
||||
_subscribe (dispatch, streamId, timelineId) {
|
||||
const { streamingAPIBaseURL, accessToken } = this.props;
|
||||
|
||||
if (!streamId || !timelineId) return;
|
||||
|
||||
this.subscription = createStream(streamingAPIBaseURL, accessToken, streamId, {
|
||||
|
||||
connected () {
|
||||
dispatch(connectTimeline(timelineId));
|
||||
},
|
||||
|
||||
reconnected () {
|
||||
dispatch(connectTimeline(timelineId));
|
||||
},
|
||||
|
||||
disconnected () {
|
||||
dispatch(disconnectTimeline(timelineId));
|
||||
},
|
||||
|
||||
received (data) {
|
||||
switch(data.event) {
|
||||
case 'update':
|
||||
dispatch(updateTimeline(timelineId, JSON.parse(data.payload)));
|
||||
break;
|
||||
case 'delete':
|
||||
dispatch(deleteFromTimelines(data.payload));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
_unsubscribe () {
|
||||
if (typeof this.subscription !== 'undefined') {
|
||||
this.subscription.close();
|
||||
this.subscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch, refresh, streamId, timelineId } = this.props;
|
||||
|
||||
if (typeof refresh !== 'function') return;
|
||||
|
||||
dispatch(refresh());
|
||||
this._subscribe(dispatch, streamId, timelineId);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.streamId !== this.props.streamId || nextProps.timelineId !== this.props.timelineId) {
|
||||
|
||||
if (typeof refresh !== 'function') return;
|
||||
|
||||
this.props.dispatch(this.props.refresh());
|
||||
this._unsubscribe();
|
||||
this._subscribe(this.props.dispatch, nextProps.streamId, nextProps.timelineId);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this._unsubscribe();
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
hasUnread,
|
||||
columnId,
|
||||
multiColumn,
|
||||
emptyMessage,
|
||||
icon,
|
||||
title,
|
||||
settings,
|
||||
scrollName,
|
||||
timelineId,
|
||||
} = this.props;
|
||||
const pinned = !!columnId;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ColumnHeader
|
||||
icon={icon}
|
||||
active={hasUnread}
|
||||
title={title}
|
||||
onPin={this.handlePin}
|
||||
onMove={this.handleMove}
|
||||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
>
|
||||
{settings}
|
||||
</ColumnHeader>
|
||||
|
||||
<StatusListContainer
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`${scrollName}-${columnId}`}
|
||||
loadMore={this.handleLoadMore}
|
||||
timelineId={timelineId}
|
||||
emptyMessage={emptyMessage}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue