commit
42f2045c21
@ -0,0 +1,60 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class Api::V1::Timelines::DirectController < Api::BaseController |
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show] |
||||
before_action :require_user!, only: [:show] |
||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? } |
||||
|
||||
respond_to :json |
||||
|
||||
def show |
||||
@statuses = load_statuses |
||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) |
||||
end |
||||
|
||||
private |
||||
|
||||
def load_statuses |
||||
cached_direct_statuses |
||||
end |
||||
|
||||
def cached_direct_statuses |
||||
cache_collection direct_statuses, Status |
||||
end |
||||
|
||||
def direct_statuses |
||||
direct_timeline_statuses.paginate_by_max_id( |
||||
limit_param(DEFAULT_STATUSES_LIMIT), |
||||
params[:max_id], |
||||
params[:since_id] |
||||
) |
||||
end |
||||
|
||||
def direct_timeline_statuses |
||||
Status.as_direct_timeline(current_account) |
||||
end |
||||
|
||||
def insert_pagination_headers |
||||
set_pagination_headers(next_path, prev_path) |
||||
end |
||||
|
||||
def pagination_params(core_params) |
||||
params.permit(:local, :limit).merge(core_params) |
||||
end |
||||
|
||||
def next_path |
||||
api_v1_timelines_direct_url pagination_params(max_id: pagination_max_id) |
||||
end |
||||
|
||||
def prev_path |
||||
api_v1_timelines_direct_url pagination_params(since_id: pagination_since_id) |
||||
end |
||||
|
||||
def pagination_max_id |
||||
@statuses.last.id |
||||
end |
||||
|
||||
def pagination_since_id |
||||
@statuses.first.id |
||||
end |
||||
end |
@ -0,0 +1,17 @@ |
||||
import { connect } from 'react-redux'; |
||||
import ColumnSettings from '../../community_timeline/components/column_settings'; |
||||
import { changeSetting } from '../../../actions/settings'; |
||||
|
||||
const mapStateToProps = state => ({ |
||||
settings: state.getIn(['settings', 'direct']), |
||||
}); |
||||
|
||||
const mapDispatchToProps = dispatch => ({ |
||||
|
||||
onChange (key, checked) { |
||||
dispatch(changeSetting(['direct', ...key], checked)); |
||||
}, |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); |
@ -0,0 +1,107 @@ |
||||
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 { |
||||
refreshDirectTimeline, |
||||
expandDirectTimeline, |
||||
} 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 { connectDirectStream } from '../../actions/streaming'; |
||||
|
||||
const messages = defineMessages({ |
||||
title: { id: 'column.direct', defaultMessage: 'Direct messages' }, |
||||
}); |
||||
|
||||
const mapStateToProps = state => ({ |
||||
hasUnread: state.getIn(['timelines', 'direct', 'unread']) > 0, |
||||
}); |
||||
|
||||
@connect(mapStateToProps) |
||||
@injectIntl |
||||
export default class DirectTimeline extends React.PureComponent { |
||||
|
||||
static propTypes = { |
||||
dispatch: PropTypes.func.isRequired, |
||||
columnId: PropTypes.string, |
||||
intl: PropTypes.object.isRequired, |
||||
hasUnread: PropTypes.bool, |
||||
multiColumn: PropTypes.bool, |
||||
}; |
||||
|
||||
handlePin = () => { |
||||
const { columnId, dispatch } = this.props; |
||||
|
||||
if (columnId) { |
||||
dispatch(removeColumn(columnId)); |
||||
} else { |
||||
dispatch(addColumn('DIRECT', {})); |
||||
} |
||||
} |
||||
|
||||
handleMove = (dir) => { |
||||
const { columnId, dispatch } = this.props; |
||||
dispatch(moveColumn(columnId, dir)); |
||||
} |
||||
|
||||
handleHeaderClick = () => { |
||||
this.column.scrollTop(); |
||||
} |
||||
|
||||
componentDidMount () { |
||||
const { dispatch } = this.props; |
||||
|
||||
dispatch(refreshDirectTimeline()); |
||||
this.disconnect = dispatch(connectDirectStream()); |
||||
} |
||||
|
||||
componentWillUnmount () { |
||||
if (this.disconnect) { |
||||
this.disconnect(); |
||||
this.disconnect = null; |
||||
} |
||||
} |
||||
|
||||
setRef = c => { |
||||
this.column = c; |
||||
} |
||||
|
||||
handleLoadMore = () => { |
||||
this.props.dispatch(expandDirectTimeline()); |
||||
} |
||||
|
||||
render () { |
||||
const { intl, hasUnread, columnId, multiColumn } = this.props; |
||||
const pinned = !!columnId; |
||||
|
||||
return ( |
||||
<Column ref={this.setRef}> |
||||
<ColumnHeader |
||||
icon='envelope' |
||||
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={`direct_timeline-${columnId}`} |
||||
timelineId='direct' |
||||
loadMore={this.handleLoadMore} |
||||
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any direct messages yet. When you send or receive one, it will show up here." />} |
||||
/> |
||||
</Column> |
||||
); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue