PLT-2321 Move the toggle icon next to the link being previewed (#3071)

* PLT-2321 Move the toggle icon next to the link being previewed
only applicable to one-line messages started with link

* remove useless "Youtube" header when no title is available

* allow breaking long links instead of toggle

* simplify "/" to "/<wbr />" replacing
fix empty post without additional content body

* discard buggy "simplification"
Этот коммит содержится в:
samogot
2016-05-28 02:31:02 +03:00
коммит произвёл Harrison Healey
родитель c7615920df
Коммит e1bebb2d77
6 изменённых файлов: 81 добавлений и 38 удалений

Просмотреть файл

@@ -136,7 +136,6 @@ export default class PostBody extends React.Component {
} }
let message; let message;
let additionalContent = null;
if (this.props.post.state === Constants.POST_DELETED) { if (this.props.post.state === Constants.POST_DELETED) {
message = ( message = (
<FormattedMessage <FormattedMessage
@@ -151,9 +150,28 @@ export default class PostBody extends React.Component {
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message)}} dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message)}}
/> />
); );
}
additionalContent = ( let messageWrapper = (
<PostBodyAdditionalContent post={this.props.post}/> <div
key={`${post.id}_message`}
id={`${post.id}_message`}
className={postClass}
>
{loading}
{message}
</div>
);
let messageWithAdditionalContent;
if (this.props.post.state === Constants.POST_DELETED) {
messageWithAdditionalContent = messageWrapper;
} else {
messageWithAdditionalContent = (
<PostBodyAdditionalContent
post={this.props.post}
message={messageWrapper}
/>
); );
} }
@@ -161,16 +179,8 @@ export default class PostBody extends React.Component {
<div> <div>
{comment} {comment}
<div className='post__body'> <div className='post__body'>
<div {messageWithAdditionalContent}
key={`${post.id}_message`}
id={`${post.id}_message`}
className={postClass}
>
{loading}
{message}
</div>
{fileAttachmentHolder} {fileAttachmentHolder}
{additionalContent}
</div> </div>
</div> </div>
); );

Просмотреть файл

@@ -117,21 +117,31 @@ export default class PostBodyAdditionalContent extends React.Component {
const generateEmbed = this.generateEmbed(); const generateEmbed = this.generateEmbed();
if (generateEmbed) { if (generateEmbed) {
let toggle; let messageWithToggle = [];
if (Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_TOGGLE)) { if (Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_TOGGLE)) {
toggle = ( // if message has only one line and starts with a link place toggle in this only line
// else - place it in new line between message and embed
const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message);
messageWithToggle.push(
<a <a
className='post__embed-visibility' className={`post__embed-visibility ${prependToggle ? 'pull-left' : ''}`}
data-expanded={this.state.embedVisible} data-expanded={this.state.embedVisible}
aria-label='Toggle Embed Visibility' aria-label='Toggle Embed Visibility'
onClick={this.toggleEmbedVisibility} onClick={this.toggleEmbedVisibility}
/> />
); );
if (prependToggle) {
messageWithToggle.push(this.props.message);
} else {
messageWithToggle.unshift(this.props.message);
}
} else {
messageWithToggle.push(this.props.message);
} }
return ( return (
<div> <div>
{toggle} {messageWithToggle}
<div <div
className='post__embed-container' className='post__embed-container'
hidden={!this.state.embedVisible} hidden={!this.state.embedVisible}
@@ -142,10 +152,11 @@ export default class PostBodyAdditionalContent extends React.Component {
); );
} }
return null; return this.props.message;
} }
} }
PostBodyAdditionalContent.propTypes = { PostBodyAdditionalContent.propTypes = {
post: React.PropTypes.object.isRequired post: React.PropTypes.object.isRequired,
message: React.PropTypes.element.isRequired
}; };

Просмотреть файл

@@ -210,6 +210,14 @@ export default class RhsRootPost extends React.Component {
/> />
); );
const messageWrapper = (
<div
ref='message_holder'
onClick={TextFormatting.handleClick}
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
/>
);
return ( return (
<div className={'post post--root ' + userCss + ' ' + systemMessageClass}> <div className={'post post--root ' + userCss + ' ' + systemMessageClass}>
<div className='post-right-channel__name'>{channelName}</div> <div className='post-right-channel__name'>{channelName}</div>
@@ -241,13 +249,9 @@ export default class RhsRootPost extends React.Component {
</li> </li>
</ul> </ul>
<div className='post__body'> <div className='post__body'>
<div
ref='message_holder'
onClick={TextFormatting.handleClick}
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
/>
<PostBodyAdditionalContent <PostBodyAdditionalContent
post={post} post={post}
message={messageWrapper}
/> />
{fileAttachment} {fileAttachment}
</div> </div>

Просмотреть файл

@@ -144,9 +144,22 @@ export default class YoutubeVideo extends React.Component {
return <div className='video-loading'/>; return <div className='video-loading'/>;
} }
let header = 'Youtube'; let header;
if (this.state.title) { if (this.state.title) {
header = header + ' - '; header = (
<h4>
<span className='video-type'>{'Youtube - '}</span>
<span className='video-title'>
<a
href={this.props.link}
target='blank'
rel='noopener noreferrer'
>
{this.state.title}
</a>
</span>
</h4>
);
} }
let content; let content;
@@ -190,18 +203,7 @@ export default class YoutubeVideo extends React.Component {
return ( return (
<div> <div>
<h4> {header}
<span className='video-type'>{header}</span>
<span className='video-title'>
<a
href={this.props.link}
target='blank'
rel='noopener noreferrer'
>
{this.state.title}
</a>
</span>
</h4>
<div <div
className='video-div embed-responsive-item' className='video-div embed-responsive-item'
onClick={this.play} onClick={this.play}

Просмотреть файл

@@ -914,9 +914,13 @@ body.ios {
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
font: normal normal normal 14px/1 FontAwesome; font: normal normal normal 14px/1 FontAwesome;
margin: 5px 0 10px; margin: 0 0 10px;
text-rendering: auto; text-rendering: auto;
&.pull-left{
margin: 5px 5px 0 0;
}
&:hover { &:hover {
text-decoration: none; text-decoration: none;
} }

Просмотреть файл

@@ -34,6 +34,8 @@ export function formatText(text, options = {}) {
output = replaceNewlines(output); output = replaceNewlines(output);
} }
output = insertLongLinkWbr(output);
return output; return output;
} }
@@ -76,6 +78,9 @@ export function doFormatText(text, options) {
}); });
} }
//replace all "/" to "/<wbr />"
output = output.replace(/\//g, '/<wbr />');
// reinsert tokens with formatted versions of the important words and phrases // reinsert tokens with formatted versions of the important words and phrases
output = replaceTokens(output, tokens); output = replaceTokens(output, tokens);
@@ -425,3 +430,10 @@ export function handleClick(e) {
browserHistory.push(linkAttribute.value); browserHistory.push(linkAttribute.value);
} }
} }
//replace all "/" inside <a> tags to "/<wbr />"
function insertLongLinkWbr(test) {
return test.replace(/\//g, (match, position, string) => {
return match + ((/a[^>]*>[^<]*$/).test(string.substr(0, position)) ? '<wbr />' : '');
});
}