mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Add permalink to timestamp (#5206)
* Add permalink to timestamp * Add permalink to timestamp * Add permalink to timestamp * Add permalink to timestamp * fix error with duplicated import * underline permalink on hover
This commit is contained in:
committed by
Corey Hulen
parent
1359f7f391
commit
1bbed1cb2b
@@ -376,6 +376,7 @@ export default class PostInfo extends React.Component {
|
||||
sameUser={this.props.sameUser}
|
||||
compactDisplay={this.props.compactDisplay}
|
||||
useMilitaryTime={this.props.useMilitaryTime}
|
||||
postId={post.id}
|
||||
/>
|
||||
{flagTrigger}
|
||||
</li>
|
||||
|
||||
@@ -6,26 +6,40 @@ import React from 'react';
|
||||
import Constants from 'utils/constants.jsx';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
|
||||
import {getDateForUnixTicks} from 'utils/utils.jsx';
|
||||
import {getDateForUnixTicks, isMobile, updateWindowDimensions} from 'utils/utils.jsx';
|
||||
|
||||
import {Link} from 'react-router/es6';
|
||||
import TeamStore from 'stores/team_store.jsx';
|
||||
|
||||
export default class PostTime extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
|
||||
this.state = {
|
||||
currentTeamDisplayName: TeamStore.getCurrent().name,
|
||||
width: '',
|
||||
height: ''
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.intervalId = setInterval(() => {
|
||||
this.forceUpdate();
|
||||
}, Constants.TIME_SINCE_UPDATE_INTERVAL);
|
||||
window.addEventListener('resize', () => {
|
||||
updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.intervalId);
|
||||
window.removeEventListener('resize', () => {
|
||||
updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
renderTimeTag() {
|
||||
return (
|
||||
<time
|
||||
className='post__time'
|
||||
@@ -35,6 +49,20 @@ export default class PostTime extends React.Component {
|
||||
</time>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return isMobile() ?
|
||||
this.renderTimeTag() :
|
||||
(
|
||||
<Link
|
||||
to={`/${this.state.currentTeamDisplayName}/pl/${this.props.postId}`}
|
||||
target='_blank'
|
||||
className='post__permalink'
|
||||
>
|
||||
{this.renderTimeTag()}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PostTime.defaultProps = {
|
||||
@@ -46,5 +74,6 @@ PostTime.propTypes = {
|
||||
eventTime: React.PropTypes.number.isRequired,
|
||||
sameUser: React.PropTypes.bool,
|
||||
compactDisplay: React.PropTypes.bool,
|
||||
useMilitaryTime: React.PropTypes.bool.isRequired
|
||||
useMilitaryTime: React.PropTypes.bool.isRequired,
|
||||
postId: React.PropTypes.string
|
||||
};
|
||||
|
||||
@@ -12,6 +12,8 @@ import RhsDropdown from 'components/rhs_dropdown.jsx';
|
||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||
import {flagPost, unflagPost} from 'actions/post_actions.jsx';
|
||||
|
||||
import TeamStore from 'stores/team_store.jsx';
|
||||
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import * as PostUtils from 'utils/post_utils.jsx';
|
||||
|
||||
@@ -24,6 +26,7 @@ import {FormattedMessage} from 'react-intl';
|
||||
import loadingGif from 'images/load.gif';
|
||||
|
||||
import React from 'react';
|
||||
import {Link} from 'react-router/es6';
|
||||
|
||||
export default class RhsComment extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -38,7 +41,23 @@ export default class RhsComment extends React.Component {
|
||||
this.canDelete = false;
|
||||
this.editDisableAction = new DelayedAction(this.handleEditDisable);
|
||||
|
||||
this.state = {};
|
||||
this.state = {
|
||||
currentTeamDisplayName: TeamStore.getCurrent().name,
|
||||
width: '',
|
||||
height: ''
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
handlePermalink(e) {
|
||||
@@ -235,6 +254,31 @@ export default class RhsComment extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
timeTag(post, timeOptions) {
|
||||
return (
|
||||
<time
|
||||
className='post__time'
|
||||
dateTime={Utils.getDateForUnixTicks(post.create_at).toISOString()}
|
||||
>
|
||||
{Utils.getDateForUnixTicks(post.create_at).toLocaleString('en', timeOptions)}
|
||||
</time>
|
||||
);
|
||||
}
|
||||
|
||||
renderTimeTag(post, timeOptions) {
|
||||
return Utils.isMobile() ?
|
||||
this.timeTag(post, timeOptions) :
|
||||
(
|
||||
<Link
|
||||
to={`/${this.state.currentTeamDisplayName}/pl/${post.id}`}
|
||||
target='_blank'
|
||||
className='post__permalink'
|
||||
>
|
||||
{this.timeTag(post, timeOptions)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const post = this.props.post;
|
||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
||||
@@ -479,12 +523,7 @@ export default class RhsComment extends React.Component {
|
||||
</li>
|
||||
{botIndicator}
|
||||
<li className='col'>
|
||||
<time
|
||||
className='post__time'
|
||||
dateTime={Utils.getDateForUnixTicks(post.create_at).toISOString()}
|
||||
>
|
||||
{Utils.getDateForUnixTicks(post.create_at).toLocaleString('en', timeOptions)}
|
||||
</time>
|
||||
{this.renderTimeTag(post, timeOptions)}
|
||||
{flagTrigger}
|
||||
</li>
|
||||
{options}
|
||||
|
||||
@@ -11,6 +11,7 @@ import RhsDropdown from 'components/rhs_dropdown.jsx';
|
||||
|
||||
import ChannelStore from 'stores/channel_store.jsx';
|
||||
import UserStore from 'stores/user_store.jsx';
|
||||
import TeamStore from 'stores/team_store.jsx';
|
||||
|
||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||
import {flagPost, unflagPost} from 'actions/post_actions.jsx';
|
||||
@@ -25,6 +26,7 @@ import {Tooltip, OverlayTrigger} from 'react-bootstrap';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import React from 'react';
|
||||
import {Link} from 'react-router/es6';
|
||||
|
||||
export default class RhsRootPost extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -38,7 +40,23 @@ export default class RhsRootPost extends React.Component {
|
||||
this.canDelete = false;
|
||||
this.editDisableAction = new DelayedAction(this.handleEditDisable);
|
||||
|
||||
this.state = {};
|
||||
this.state = {
|
||||
currentTeamDisplayName: TeamStore.getCurrent().name,
|
||||
width: '',
|
||||
height: ''
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
handlePermalink(e) {
|
||||
@@ -100,6 +118,31 @@ export default class RhsRootPost extends React.Component {
|
||||
unflagPost(this.props.post.id);
|
||||
}
|
||||
|
||||
timeTag(post, timeOptions) {
|
||||
return (
|
||||
<time
|
||||
className='post__time'
|
||||
dateTime={Utils.getDateForUnixTicks(post.create_at).toISOString()}
|
||||
>
|
||||
{Utils.getDateForUnixTicks(post.create_at).toLocaleString('en', timeOptions)}
|
||||
</time>
|
||||
);
|
||||
}
|
||||
|
||||
renderTimeTag(post, timeOptions) {
|
||||
return Utils.isMobile() ?
|
||||
this.timeTag(post, timeOptions) :
|
||||
(
|
||||
<Link
|
||||
to={`/${this.state.currentTeamDisplayName}/pl/${post.id}`}
|
||||
target='_blank'
|
||||
className='post__permalink'
|
||||
>
|
||||
{this.timeTag(post, timeOptions)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const post = this.props.post;
|
||||
const user = this.props.user;
|
||||
@@ -426,12 +469,7 @@ export default class RhsRootPost extends React.Component {
|
||||
<li className='col__name'>{userProfile}</li>
|
||||
{botIndicator}
|
||||
<li className='col'>
|
||||
<time
|
||||
className='post__time'
|
||||
dateTime={Utils.getDateForUnixTicks(post.create_at).toISOString()}
|
||||
>
|
||||
{Utils.getDateForUnixTicks(post.create_at).toLocaleString('en', timeOptions)}
|
||||
</time>
|
||||
{this.renderTimeTag(post, timeOptions)}
|
||||
<OverlayTrigger
|
||||
key={'rootpostflagtooltipkey' + flagVisible}
|
||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
||||
|
||||
@@ -22,7 +22,7 @@ const ActionTypes = Constants.ActionTypes;
|
||||
|
||||
import React from 'react';
|
||||
import {FormattedMessage, FormattedDate} from 'react-intl';
|
||||
import {browserHistory} from 'react-router/es6';
|
||||
import {browserHistory, Link} from 'react-router/es6';
|
||||
|
||||
export default class SearchResultsItem extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -32,6 +32,24 @@ export default class SearchResultsItem extends React.Component {
|
||||
this.shrinkSidebar = this.shrinkSidebar.bind(this);
|
||||
this.unflagPost = this.unflagPost.bind(this);
|
||||
this.flagPost = this.flagPost.bind(this);
|
||||
|
||||
this.state = {
|
||||
currentTeamDisplayName: TeamStore.getCurrent().name,
|
||||
width: '',
|
||||
height: ''
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', () => {
|
||||
Utils.updateWindowDimensions(this);
|
||||
});
|
||||
}
|
||||
|
||||
hideSidebar() {
|
||||
@@ -59,6 +77,33 @@ export default class SearchResultsItem extends React.Component {
|
||||
unflagPost(this.props.post.id);
|
||||
}
|
||||
|
||||
timeTag(post) {
|
||||
return (
|
||||
<time className='search-item-time'>
|
||||
<FormattedDate
|
||||
value={post.create_at}
|
||||
hour12={!this.props.useMilitaryTime}
|
||||
hour='2-digit'
|
||||
minute='2-digit'
|
||||
/>
|
||||
</time>
|
||||
);
|
||||
}
|
||||
|
||||
renderTimeTag(post) {
|
||||
return Utils.isMobile() ?
|
||||
this.timeTag(post) :
|
||||
(
|
||||
<Link
|
||||
to={`/${this.state.currentTeamDisplayName}/pl/${post.id}`}
|
||||
target='_blank'
|
||||
className='post__permalink'
|
||||
>
|
||||
{this.timeTag(post)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
let channelName = null;
|
||||
const channel = this.props.channel;
|
||||
@@ -276,14 +321,7 @@ export default class SearchResultsItem extends React.Component {
|
||||
</strong></li>
|
||||
{botIndicator}
|
||||
<li className='col'>
|
||||
<time className='search-item-time'>
|
||||
<FormattedDate
|
||||
value={post.create_at}
|
||||
hour12={!this.props.useMilitaryTime}
|
||||
hour='2-digit'
|
||||
minute='2-digit'
|
||||
/>
|
||||
</time>
|
||||
{this.renderTimeTag(post)}
|
||||
{flagContent}
|
||||
</li>
|
||||
{rhsControls}
|
||||
|
||||
@@ -1199,6 +1199,19 @@
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.post__permalink {
|
||||
color: #333;
|
||||
&:hover, &:focus {
|
||||
color: #333;
|
||||
}
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.post-loading-gif {
|
||||
height: 10px;
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -366,7 +366,9 @@
|
||||
text-rendering: auto;
|
||||
top: -2px;
|
||||
width: 51px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,3 +1287,7 @@ export function isEmptyObject(object) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function updateWindowDimensions(component) {
|
||||
component.setState({width: window.innerWidth, height: window.innerHeight});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user