mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
* Major post list refactor * Fix post and thread deletion * Fix preferences not selecting correctly * Fix military time displaying * Fix UP key for editing posts * Fix ESLint error * Various fixes and updates per feedback * Fix for permalink view * Revert to old scrolling method and various fixes * Add floating timestamp, new message indicator, scroll arrows * Update post loading for focus mode and add visibility limit * Fix pinning posts and a react warning * Add loading UI updates from Asaad * Fix refreshing loop * Temporarily bump post visibility limit * Update infinite scrolling * Remove infinite scrolling
229 lines
7.2 KiB
JavaScript
229 lines
7.2 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
import $ from 'jquery';
|
|
import React, {Component} from 'react';
|
|
import PropTypes from 'prop-types';
|
|
|
|
import DotMenuFlag from './dot_menu_flag.jsx';
|
|
import DotMenuItem from './dot_menu_item.jsx';
|
|
import DotMenuEdit from './dot_menu_edit.jsx';
|
|
|
|
import * as Utils from 'utils/utils.jsx';
|
|
import * as PostUtils from 'utils/post_utils.jsx';
|
|
import Constants from 'utils/constants.jsx';
|
|
import DelayedAction from 'utils/delayed_action.jsx';
|
|
|
|
export default class DotMenu extends Component {
|
|
static propTypes = {
|
|
idPrefix: PropTypes.string.isRequired,
|
|
idCount: PropTypes.number,
|
|
post: PropTypes.object.isRequired,
|
|
commentCount: PropTypes.number,
|
|
isFlagged: PropTypes.bool,
|
|
handleCommentClick: PropTypes.func,
|
|
handleDropdownOpened: PropTypes.func,
|
|
|
|
actions: PropTypes.shape({
|
|
|
|
/*
|
|
* Function flag the post
|
|
*/
|
|
flagPost: PropTypes.func.isRequired,
|
|
|
|
/*
|
|
* Function to unflag the post
|
|
*/
|
|
unflagPost: PropTypes.func.isRequired,
|
|
|
|
/*
|
|
* Function to pin the post
|
|
*/
|
|
pinPost: PropTypes.func.isRequired,
|
|
|
|
/*
|
|
* Function to unpin the post
|
|
*/
|
|
unpinPost: PropTypes.func.isRequired
|
|
}).isRequired
|
|
}
|
|
|
|
static defaultProps = {
|
|
idCount: -1,
|
|
post: {},
|
|
commentCount: 0,
|
|
isFlagged: false
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.handleDropdownOpened = this.handleDropdownOpened.bind(this);
|
|
this.canDelete = false;
|
|
this.canEdit = false;
|
|
this.editDisableAction = new DelayedAction(this.handleEditDisable);
|
|
}
|
|
|
|
componentDidMount() {
|
|
$('#' + this.props.idPrefix + '_dropdown' + this.props.post.id).on('shown.bs.dropdown', this.handleDropdownOpened);
|
|
$('#' + this.props.idPrefix + '_dropdown' + this.props.post.id).on('hidden.bs.dropdown', () => this.props.handleDropdownOpened(false));
|
|
}
|
|
|
|
handleDropdownOpened() {
|
|
this.props.handleDropdownOpened(true);
|
|
|
|
const position = $('#post-list').height() - $(this.refs.dropdownToggle).offset().top;
|
|
const dropdown = $(this.refs.dropdown);
|
|
|
|
if (position < dropdown.height()) {
|
|
dropdown.addClass('bottom');
|
|
}
|
|
}
|
|
|
|
handleEditDisable() {
|
|
this.canEdit = false;
|
|
}
|
|
|
|
render() {
|
|
const isSystemMessage = PostUtils.isSystemMessage(this.props.post);
|
|
const isMobile = Utils.isMobile();
|
|
this.canDelete = PostUtils.canDeletePost(this.props.post);
|
|
this.canEdit = PostUtils.canEditPost(this.props.post, this.editDisableAction);
|
|
|
|
if (this.props.idPrefix === Constants.CENTER && (!isMobile && isSystemMessage && !this.canDelete && !this.canEdit)) {
|
|
return null;
|
|
}
|
|
|
|
if (this.props.idPrefix === Constants.RHS && (this.props.post.state === Constants.POST_FAILED || this.props.post.state === Constants.POST_LOADING)) {
|
|
return null;
|
|
}
|
|
|
|
let type = 'Post';
|
|
if (this.props.post.root_id && this.props.post.root_id.length > 0) {
|
|
type = 'Comment';
|
|
}
|
|
|
|
const idPrefix = this.props.idPrefix + 'DotMenu';
|
|
|
|
let dotMenuFlag = null;
|
|
if (isMobile) {
|
|
dotMenuFlag = (
|
|
<DotMenuFlag
|
|
idPrefix={idPrefix + 'Flag'}
|
|
idCount={this.props.idCount}
|
|
postId={this.props.post.id}
|
|
isFlagged={this.props.isFlagged}
|
|
actions={{
|
|
flagPost: this.props.actions.flagPost,
|
|
unflagPost: this.props.actions.unflagPost
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
let dotMenuReply = null;
|
|
let dotMenuPermalink = null;
|
|
let dotMenuPin = null;
|
|
if (!isSystemMessage) {
|
|
if (this.props.idPrefix === Constants.CENTER) {
|
|
dotMenuReply = (
|
|
<DotMenuItem
|
|
idPrefix={idPrefix + 'Reply'}
|
|
idCount={this.props.idCount}
|
|
handleOnClick={this.props.handleCommentClick}
|
|
/>
|
|
);
|
|
}
|
|
|
|
dotMenuPermalink = (
|
|
<DotMenuItem
|
|
idPrefix={idPrefix + 'Permalink'}
|
|
idCount={this.props.idCount}
|
|
post={this.props.post}
|
|
/>
|
|
);
|
|
|
|
dotMenuPin = (
|
|
<DotMenuItem
|
|
idPrefix={idPrefix + 'Pin'}
|
|
idCount={this.props.idCount}
|
|
post={this.props.post}
|
|
actions={{
|
|
pinPost: this.props.actions.pinPost,
|
|
unpinPost: this.props.actions.unpinPost
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
let dotMenuDelete = null;
|
|
if (this.canDelete) {
|
|
dotMenuDelete = (
|
|
<DotMenuItem
|
|
idPrefix={idPrefix + 'Delete'}
|
|
idCount={this.props.idCount}
|
|
post={this.props.post}
|
|
commentCount={type === 'Post' ? this.props.commentCount : 0}
|
|
/>
|
|
);
|
|
}
|
|
|
|
let dotMenuEdit = null;
|
|
if (this.canEdit) {
|
|
dotMenuEdit = (
|
|
<DotMenuEdit
|
|
idPrefix={idPrefix + 'Edit'}
|
|
idCount={this.props.idCount}
|
|
post={this.props.post}
|
|
type={type}
|
|
commentCount={type === 'Post' ? this.props.commentCount : 0}
|
|
/>
|
|
);
|
|
}
|
|
|
|
let dotMenuId = null;
|
|
if (this.props.idCount > -1) {
|
|
dotMenuId = Utils.createSafeId(idPrefix + this.props.idCount);
|
|
}
|
|
|
|
if (this.props.idPrefix === Constants.RHS_ROOT) {
|
|
dotMenuId = idPrefix;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
id={dotMenuId}
|
|
className='dropdown'
|
|
ref='dotMenu'
|
|
>
|
|
<div
|
|
id={this.props.idPrefix + '_dropdown' + this.props.post.id}
|
|
>
|
|
<a
|
|
ref='dropdownToggle'
|
|
href='#'
|
|
className='dropdown-toggle post__dropdown theme'
|
|
type='button'
|
|
data-toggle='dropdown'
|
|
aria-expanded='false'
|
|
/>
|
|
<div className='dropdown-menu__content'>
|
|
<ul
|
|
ref='dropdown'
|
|
className='dropdown-menu'
|
|
role='menu'
|
|
>
|
|
{dotMenuReply}
|
|
{dotMenuFlag}
|
|
{dotMenuPermalink}
|
|
{dotMenuPin}
|
|
{dotMenuDelete}
|
|
{dotMenuEdit}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|