promotion fe

This commit is contained in:
2458773093 2019-08-31 14:54:03 +03:00
parent 0499184b38
commit 168642a1b9
4 changed files with 53 additions and 14 deletions

@ -92,6 +92,7 @@ class Status extends ImmutablePureComponent {
cacheMediaWidth: PropTypes.func, cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number, cachedMediaWidth: PropTypes.number,
group: ImmutablePropTypes.map, group: ImmutablePropTypes.map,
promoted: PropTypes.bool
}; };
// Avoid checking props that are functions (and whose equality will always // Avoid checking props that are functions (and whose equality will always
@ -261,7 +262,7 @@ class Status extends ImmutablePureComponent {
let media = null; let media = null;
let statusAvatar, prepend, rebloggedByText, reblogContent; let statusAvatar, prepend, rebloggedByText, reblogContent;
const { intl, hidden, featured, otherAccounts, unread, showThread, group } = this.props; const { intl, hidden, featured, otherAccounts, unread, showThread, group, promoted } = this.props;
let { status, account, ...other } = this.props; let { status, account, ...other } = this.props;
@ -293,7 +294,14 @@ class Status extends ImmutablePureComponent {
); );
} }
if (featured) { if (promoted) {
prepend = (
<div className='status__prepend'>
<div className='status__prepend-icon-wrapper'><Icon id='star' className='status__prepend-icon' fixedWidth /></div>
<FormattedMessage id='status.promoted' defaultMessage='Promoted gab' />
</div>
);
} else if (featured) {
prepend = ( prepend = (
<div className='status__prepend'> <div className='status__prepend'>
<div className='status__prepend-icon-wrapper'><Icon id='thumb-tack' className='status__prepend-icon' fixedWidth /></div> <div className='status__prepend-icon-wrapper'><Icon id='thumb-tack' className='status__prepend-icon' fixedWidth /></div>

@ -29,12 +29,24 @@ export default class StatusList extends ImmutablePureComponent {
withGroupAdmin: PropTypes.bool, withGroupAdmin: PropTypes.bool,
onScrollToTop: PropTypes.func, onScrollToTop: PropTypes.func,
onScroll: PropTypes.func, onScroll: PropTypes.func,
promotion: PropTypes.object,
promotedStatus: ImmutablePropTypes.map,
fetchStatus: PropTypes.func,
}; };
componentDidMount() { componentDidMount() {
this.handleDequeueTimeline(); this.handleDequeueTimeline();
this.fetchPromotedStatus();
}; };
fetchPromotedStatus() {
const { promotion, promotedStatus, fetchStatus } = this.props;
if (promotion && !promotedStatus) {
fetchStatus(promotion.status_id);
}
}
getFeaturedStatusCount = () => { getFeaturedStatusCount = () => {
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0; return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
} }
@ -86,7 +98,7 @@ export default class StatusList extends ImmutablePureComponent {
} }
render () { render () {
const { statusIds, featuredStatusIds, onLoadMore, timelineId, totalQueuedItemsCount, isLoading, isPartial, withGroupAdmin, group, ...other } = this.props; const { statusIds, featuredStatusIds, onLoadMore, timelineId, totalQueuedItemsCount, isLoading, isPartial, withGroupAdmin, group, promotion, promotedStatus, ...other } = this.props;
if (isPartial) { if (isPartial) {
return ( return (
@ -110,16 +122,26 @@ export default class StatusList extends ImmutablePureComponent {
onClick={onLoadMore} onClick={onLoadMore}
/> />
) : ( ) : (
<StatusContainer <React.Fragment key={statusId}>
key={statusId} <StatusContainer
id={statusId} id={statusId}
onMoveUp={this.handleMoveUp} onMoveUp={this.handleMoveUp}
onMoveDown={this.handleMoveDown} onMoveDown={this.handleMoveDown}
contextType={timelineId} contextType={timelineId}
group={group} group={group}
withGroupAdmin={withGroupAdmin} withGroupAdmin={withGroupAdmin}
showThread showThread
/> />
{promotedStatus && index === promotion.position && (
<StatusContainer
id={promotion.status_id}
contextType={timelineId}
promoted
showThread
/>
)}
</React.Fragment>
)) ))
) : null; ) : null;

@ -3,9 +3,11 @@ import StatusList from '../../../components/status_list';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { me } from '../../../initial_state'; import { me, promotions } from '../../../initial_state';
import { dequeueTimeline } from 'gabsocial/actions/timelines'; import { dequeueTimeline } from 'gabsocial/actions/timelines';
import { scrollTopTimeline } from '../../../actions/timelines'; import { scrollTopTimeline } from '../../../actions/timelines';
import { sample } from 'lodash';
import { fetchStatus } from '../../../actions/statuses';
const makeGetStatusIds = () => createSelector([ const makeGetStatusIds = () => createSelector([
(state, { type, id }) => state.getIn(['settings', type], ImmutableMap()), (state, { type, id }) => state.getIn(['settings', type], ImmutableMap()),
@ -32,6 +34,7 @@ const makeGetStatusIds = () => createSelector([
const mapStateToProps = (state, {timelineId}) => { const mapStateToProps = (state, {timelineId}) => {
const getStatusIds = makeGetStatusIds(); const getStatusIds = makeGetStatusIds();
const promotion = promotions.length > 0 && sample(promotions.filter(p => p.timeline_id === timelineId));
return { return {
statusIds: getStatusIds(state, { type: timelineId.substring(0,5) === 'group' ? 'group' : timelineId, id: timelineId }), statusIds: getStatusIds(state, { type: timelineId.substring(0,5) === 'group' ? 'group' : timelineId, id: timelineId }),
@ -39,6 +42,8 @@ const mapStateToProps = (state, {timelineId}) => {
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false), isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
hasMore: state.getIn(['timelines', timelineId, 'hasMore']), hasMore: state.getIn(['timelines', timelineId, 'hasMore']),
totalQueuedItemsCount: state.getIn(['timelines', timelineId, 'totalQueuedItemsCount']), totalQueuedItemsCount: state.getIn(['timelines', timelineId, 'totalQueuedItemsCount']),
promotion: promotion,
promotedStatus: promotion && state.getIn(['statuses', promotion.status_id])
}; };
}; };
@ -52,6 +57,9 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
onScroll: debounce(() => { onScroll: debounce(() => {
dispatch(scrollTopTimeline(ownProps.timelineId, false)); dispatch(scrollTopTimeline(ownProps.timelineId, false));
}, 100), }, 100),
fetchStatus(id) {
dispatch(fetchStatus(id));
}
}); });
export default connect(mapStateToProps, mapDispatchToProps)(StatusList); export default connect(mapStateToProps, mapDispatchToProps)(StatusList);

@ -23,5 +23,6 @@ export const mascot = getMeta('mascot');
export const profile_directory = getMeta('profile_directory'); export const profile_directory = getMeta('profile_directory');
export const isStaff = getMeta('is_staff'); export const isStaff = getMeta('is_staff');
export const forceSingleColumn = !getMeta('advanced_layout'); export const forceSingleColumn = !getMeta('advanced_layout');
export const promotions = initialState && initialState.promotions;
export default initialState; export default initialState;