summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/activity_log_modal.jsx3
-rw-r--r--web/react/components/create_post.jsx2
-rw-r--r--web/react/components/post_body.jsx2
-rw-r--r--web/react/components/removed_from_channel_modal.jsx64
-rw-r--r--web/react/components/sidebar.jsx14
-rw-r--r--web/react/components/textbox.jsx37
-rw-r--r--web/react/components/user_settings.jsx2
-rw-r--r--web/react/pages/channel.jsx6
-rw-r--r--web/react/utils/utils.jsx9
-rw-r--r--web/sass-files/sass/partials/_activity-log.scss3
-rw-r--r--web/sass-files/sass/partials/_signup.scss12
-rw-r--r--web/static/images/Bladekick-logodark.pngbin7754 -> 10380 bytes
-rw-r--r--web/static/images/Mattermost-logodark.pngbin7754 -> 10380 bytes
-rw-r--r--web/templates/channel.html1
-rw-r--r--web/templates/head.html7
15 files changed, 116 insertions, 46 deletions
diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx
index 7cce807a9..90f139e8b 100644
--- a/web/react/components/activity_log_modal.jsx
+++ b/web/react/components/activity_log_modal.jsx
@@ -102,8 +102,9 @@ module.exports = React.createClass({
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
- <h4 className="modal-title" id="myModalLabel">Active Devices</h4>
+ <h4 className="modal-title" id="myModalLabel">Active Sessions</h4>
</div>
+ <p className="session-help-text">Sessions are created when you log in with your email and password to a new browser on a device. Sessions let you use Mattermost for up to 30 days without having to log in again. If you want to log out sooner, use the "Logout" button below to end a session.</p>
<div ref="modalBody" className="modal-body">
<form role="form">
{ activityList }
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx
index 87895588e..327520210 100644
--- a/web/react/components/create_post.jsx
+++ b/web/react/components/create_post.jsx
@@ -32,7 +32,7 @@ module.exports = React.createClass({
post.message = this.state.messageText;
// if this is a reply, trim off any carets from the beginning of a message
- if (this.state.rootId && post.message.startsWith("^")) {
+ if (this.state.rootId && post.message[0] === "^") {
post.message = post.message.replace(/^\^+\s*/g, "");
}
diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx
index 7871f52b7..9f598ecb3 100644
--- a/web/react/components/post_body.jsx
+++ b/web/react/components/post_body.jsx
@@ -126,7 +126,7 @@ module.exports = React.createClass({
} else if (i < Constants.MAX_DISPLAY_FILES) {
postFiles.push(
<div className="post-image__column custom-file" key={fileInfo.name+i}>
- <a href={fileInfo.path+"."+fileInfo.ext} download={fileInfo.name+"."+fileInfo.ext}>
+ <a href={fileInfo.path + (fileInfo.ext ? "." + fileInfo.ext : "")} download={fileInfo.name + (fileInfo.ext ? "." + fileInfo.ext : "")}>
<div className={"file-icon "+utils.getIconClassName(type)}/>
</a>
</div>
diff --git a/web/react/components/removed_from_channel_modal.jsx b/web/react/components/removed_from_channel_modal.jsx
new file mode 100644
index 000000000..a8889a92a
--- /dev/null
+++ b/web/react/components/removed_from_channel_modal.jsx
@@ -0,0 +1,64 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+var ChannelStore = require('../stores/channel_store.jsx');
+var UserStore = require('../stores/user_store.jsx');
+var BrowserStore = require('../stores/browser_store.jsx')
+var utils = require('../utils/utils.jsx');
+
+module.exports = React.createClass({
+ handleShow: function() {
+ var newState = {};
+ if(BrowserStore.getItem("channel-removed-state")) {
+ newState = BrowserStore.getItem("channel-removed-state");
+ BrowserStore.removeItem("channel-removed-state");
+ }
+
+ this.setState(newState);
+ },
+ handleClose: function() {
+ var townSquare = ChannelStore.getByName("town-square");
+ utils.switchChannel(townSquare);
+
+ this.setState({channelName: "", remover: ""})
+ },
+ componentDidMount: function() {
+ $(this.getDOMNode()).on('show.bs.modal',this.handleShow);
+ $(this.getDOMNode()).on('hidden.bs.modal',this.handleClose);
+ },
+ componentWillUnmount: function() {
+ $(this.getDOMNode()).off('show.bs.modal',this.handleShow);
+ $(this.getDOMNode()).off('hidden.bs.modal',this.handleClose);
+ },
+ getInitialState: function() {
+ return {channelName: "", remover: ""}
+ },
+ render: function() {
+ var currentUser = UserStore.getCurrentUser();
+ var channelName = this.state.channelName ? this.state.channelName : "the channel"
+ var remover = this.state.remover ? this.state.remover : "Someone"
+
+ if (currentUser != null) {
+ return (
+ <div className="modal fade" ref="modal" id="removed_from_channel" tabIndex="-1" role="dialog" aria-hidden="true">
+ <div className="modal-dialog">
+ <div className="modal-content">
+ <div className="modal-header">
+ <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 className="modal-title">Removed from {channelName}</h4>
+ </div>
+ <div className="modal-body">
+ <p>{remover} removed you from {channelName}</p>
+ </div>
+ <div className="modal-footer">
+ <button type="button" className="btn btn-primary" data-dismiss="modal">Okay</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ } else {
+ return <div/>;
+ }
+ }
+}); \ No newline at end of file
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 3cf67e410..5b8d6c542 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -7,6 +7,7 @@ var AsyncClient = require('../utils/async_client.jsx');
var SocketStore = require('../stores/socket_store.jsx');
var UserStore = require('../stores/user_store.jsx');
var TeamStore = require('../stores/team_store.jsx');
+var BrowserStore = require('../stores/browser_store.jsx')
var utils = require('../utils/utils.jsx');
var SidebarHeader = require('./sidebar_header.jsx');
var SearchBox = require('./search_bar.jsx');
@@ -197,6 +198,19 @@ module.exports = React.createClass({
if (UserStore.getCurrentId() === msg.user_id) {
AsyncClient.getChannels(true);
}
+ } else if(msg.action === "user_removed") {
+ if(msg.user_id === UserStore.getCurrentId()) {
+ AsyncClient.getChannels(true);
+
+ if(msg.props.channel_id === ChannelStore.getCurrentId() && $('#removed_from_channel').length > 0) {
+ var sentState = {};
+ sentState.channelName = ChannelStore.getCurrent().display_name;
+ sentState.remover = UserStore.getProfile(msg.props.remover).username;
+
+ BrowserStore.setItem('channel-removed-state',sentState);
+ $('#removed_from_channel').modal('show');
+ }
+ }
}
},
updateTitle: function() {
diff --git a/web/react/components/textbox.jsx b/web/react/components/textbox.jsx
index ad50b7920..bbd1f84b6 100644
--- a/web/react/components/textbox.jsx
+++ b/web/react/components/textbox.jsx
@@ -36,7 +36,6 @@ module.exports = React.createClass({
this.resize();
this.processMentions();
- this.updateTextdiv();
},
componentWillUnmount: function() {
PostStore.removeAddMentionListener(this._onChange);
@@ -87,7 +86,6 @@ module.exports = React.createClass({
this.processMentions();
this.doProcessMentions = false;
}
- this.updateTextdiv();
this.resize();
},
componentWillReceiveProps: function(nextProps) {
@@ -117,17 +115,6 @@ module.exports = React.createClass({
});
}, 1);
},
- updateTextdiv: function() {
- var html = utils.insertHtmlEntities(this.refs.message.getDOMNode().value);
- for (var k in this.mentions) {
- var m = this.mentions[k];
- var re = new RegExp('( |^)@' + m + '( |$|\n)', 'm');
- html = html.replace(re, '$1<span class="mention">@'+m+'</span>$2');
- }
- var re2 = new RegExp('(^$)(?![.\n])', 'gm');
- html = html.replace(re2, '<br/><br/>');
- $(this.refs.textdiv.getDOMNode()).html(html);
- },
handleChange: function() {
this.props.onUserInput(this.refs.message.getDOMNode().value);
this.resize();
@@ -181,7 +168,7 @@ module.exports = React.createClass({
}
},
processMentions: function() {
- /* First, find all the possible mentions, highlight them in the HTML and add
+ /* First, find all the possible mentions and add
them all to a list of mentions */
var text = utils.insertHtmlEntities(this.refs.message.getDOMNode().value);
@@ -192,9 +179,7 @@ module.exports = React.createClass({
var matches = text.match(re1);
if (!matches) {
- $(this.refs.textdiv.getDOMNode()).text(text);
this.updateMentionTab(null, []);
- this.mentions = [];
return;
}
@@ -207,7 +192,7 @@ module.exports = React.createClass({
}
/* Figure out what the user is currently typing. If it's a mention then we don't
- want to highlight it and add it to the mention list yet, so we remove it if
+ want to add it to the mention list yet, so we remove it if
there is only one occurence of that mention so far. */
var caret = utils.getCaretPosition(this.refs.message.getDOMNode());
@@ -225,14 +210,13 @@ module.exports = React.createClass({
typingMention = text.substring(atIndex+1, caret);
}
- var re3 = new RegExp('@' + typingMention + '( |$|\n)', 'g');
+ var re2 = new RegExp('@' + typingMention + '( |$|\n)', 'g');
- if ((text.match(re3) || []).length === 1 && mentions.indexOf(typingMention) !== -1) {
+ if ((text.match(re2) || []).length === 1 && mentions.indexOf(typingMention) !== -1) {
mentions.splice(mentions.indexOf(typingMention), 1);
}
this.updateMentionTab(null, mentions);
- this.mentions = mentions;
},
checkForNewMention: function(text) {
var caret = utils.getCaretPosition(this.refs.message.getDOMNode());
@@ -287,15 +271,9 @@ module.exports = React.createClass({
elm.value = cmd;
this.handleChange();
},
- scroll: function() {
- var e = this.refs.message.getDOMNode();
- var d = this.refs.textdiv.getDOMNode();
- $(d).scrollTop($(e).scrollTop());
- },
resize: function() {
var e = this.refs.message.getDOMNode();
var w = this.refs.wrapper.getDOMNode();
- var d = this.refs.textdiv.getDOMNode();
var lht = parseInt($(e).css('lineHeight'),10);
var lines = e.scrollHeight / lht;
@@ -303,15 +281,11 @@ module.exports = React.createClass({
if (e.scrollHeight - mod < 167) {
$(e).css({'height':'auto','overflow-y':'hidden'}).height(e.scrollHeight - mod);
- $(d).css({'height':'auto','overflow-y':'hidden'}).height(e.scrollHeight - mod);
$(w).css({'height':'auto'}).height(e.scrollHeight+2);
} else {
$(e).css({'height':'auto','overflow-y':'scroll'}).height(167);
- $(d).css({'height':'auto','overflow-y':'scroll'}).height(167);
$(w).css({'height':'auto'}).height(167);
}
-
- $(d).scrollTop($(e).scrollTop());
},
handleFocus: function() {
var elm = this.refs.message.getDOMNode();
@@ -332,8 +306,7 @@ module.exports = React.createClass({
return (
<div ref="wrapper" className="textarea-wrapper">
<CommandList ref='commands' addCommand={this.addCommand} channelId={this.props.channelId} />
- <div className="form-control textarea-div" ref="textdiv"/>
- <textarea id={this.props.id} ref="message" className={"form-control custom-textarea " + this.state.connection} spellCheck="true" autoComplete="off" autoCorrect="off" rows="1" placeholder={this.props.createMessage} value={this.props.messageText} onInput={this.handleChange} onChange={this.handleChange} onKeyPress={this.handleKeyPress} onKeyDown={this.handleKeyDown} onScroll={this.scroll} onFocus={this.handleFocus} onBlur={this.handleBlur} onPaste={this.handlePaste} />
+ <textarea id={this.props.id} ref="message" className={"form-control custom-textarea " + this.state.connection} spellCheck="true" autoComplete="off" autoCorrect="off" rows="1" placeholder={this.props.createMessage} value={this.props.messageText} onInput={this.handleChange} onChange={this.handleChange} onKeyPress={this.handleKeyPress} onKeyDown={this.handleKeyDown} onFocus={this.handleFocus} onBlur={this.handleBlur} onPaste={this.handlePaste} />
</div>
);
}
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index 2ac9a2371..e1ae6da52 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -617,7 +617,7 @@ var SecurityTab = React.createClass({
<br></br>
<a data-toggle="modal" className="security-links theme" data-target="#access-history" href="#" onClick={this.handleHistoryOpen}><i className="fa fa-clock-o"></i>View Access History</a>
<b> </b>
- <a data-toggle="modal" className="security-links theme" data-target="#activity-log" href="#" onClick={this.handleDevicesOpen}><i className="fa fa-globe"></i>View and Logout of Active Devices</a>
+ <a data-toggle="modal" className="security-links theme" data-target="#activity-log" href="#" onClick={this.handleDevicesOpen}><i className="fa fa-globe"></i>View and Logout of Active Sessions</a>
</div>
</div>
);
diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx
index cc78df120..90d90b29f 100644
--- a/web/react/pages/channel.jsx
+++ b/web/react/pages/channel.jsx
@@ -34,6 +34,7 @@ var MentionList = require('../components/mention_list.jsx');
var ChannelInfoModal = require('../components/channel_info_modal.jsx');
var AccessHistoryModal = require('../components/access_history_modal.jsx');
var ActivityLogModal = require('../components/activity_log_modal.jsx');
+var RemovedFromChannelModal = require('../components/removed_from_channel_modal.jsx')
var Constants = require('../utils/constants.jsx');
@@ -217,4 +218,9 @@ global.window.setup_channel_page = function(team_name, team_type, team_id, chann
document.getElementById('activity_log_modal')
);
+ React.render(
+ <RemovedFromChannelModal />,
+ document.getElementById('removed_from_channel_modal')
+ );
+
};
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 00580af6e..fbf1e0d4f 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -546,10 +546,13 @@ module.exports.getIconClassName = function(fileType) {
module.exports.splitFileLocation = function(fileLocation) {
var fileSplit = fileLocation.split('.');
- if (fileSplit.length < 2) return {};
- var ext = fileSplit[fileSplit.length-1];
- fileSplit.splice(fileSplit.length-1,1)
+ var ext = "";
+ if (fileSplit.length > 1) {
+ ext = fileSplit[fileSplit.length - 1];
+ fileSplit.splice(fileSplit.length - 1, 1);
+ }
+
var filePath = fileSplit.join('.');
var filename = filePath.split('/')[filePath.split('/').length-1];
diff --git a/web/sass-files/sass/partials/_activity-log.scss b/web/sass-files/sass/partials/_activity-log.scss
index 36eb48750..3f0c3090d 100644
--- a/web/sass-files/sass/partials/_activity-log.scss
+++ b/web/sass-files/sass/partials/_activity-log.scss
@@ -28,4 +28,7 @@
.report__info {
color: #999;
}
+}
+.session-help-text {
+ padding: 20px 20px 5px 20px;
} \ No newline at end of file
diff --git a/web/sass-files/sass/partials/_signup.scss b/web/sass-files/sass/partials/_signup.scss
index 826394a10..5996306d2 100644
--- a/web/sass-files/sass/partials/_signup.scss
+++ b/web/sass-files/sass/partials/_signup.scss
@@ -8,7 +8,6 @@
padding: 100px 0px 50px 0px;
max-width: 380px;
margin: 0 auto;
- font-size: 1.1em;
position: relative;
h1, h2, h3, h4, h5, h6, p {
line-height: 1.3;
@@ -17,18 +16,18 @@
font-weight: 600;
margin-bottom: 0.5em;
letter-spacing: -0.5px;
- font-size: em(28px);
+ font-size: em(30px);
}
h3 {
font-weight: 600;
margin: 0 0 1.3em 0;
- font-size: 1.4em;
+ font-size: 1.5em;
&.extra-margin {
margin-bottom: 2.5em;
}
}
h4 {
- font-size: em(18px);
+ font-size: em(20px);
font-weight: 600;
margin-bottom: 1em;
&.text--light {
@@ -78,6 +77,7 @@
width: 33px;
top: -10px;
position: relative;
+ font-size: em(16px);
line-height: 20px;
font-weight: 600;
background: #fff;
@@ -87,7 +87,7 @@
.btn {
padding: em(7px) em(15px);
font-weight: 600;
- font-size: em(13px);
+ margin-right: 5px;
&.btn-custom-login {
display: block;
min-width: 200px;
@@ -126,13 +126,11 @@
font-size: 0.9em;
}
&.glyphicon-chevron-right {
- margin-left: 0.3em;
font-size: 0.8em;
right: -2px;
top: 0px;
}
&.glyphicon-chevron-left {
- margin-right: 0.3em;
font-size: 0.8em;
left: -2px;
top: 0px;
diff --git a/web/static/images/Bladekick-logodark.png b/web/static/images/Bladekick-logodark.png
index 8f1268fdd..c16978ba8 100644
--- a/web/static/images/Bladekick-logodark.png
+++ b/web/static/images/Bladekick-logodark.png
Binary files differ
diff --git a/web/static/images/Mattermost-logodark.png b/web/static/images/Mattermost-logodark.png
index 8f1268fdd..c16978ba8 100644
--- a/web/static/images/Mattermost-logodark.png
+++ b/web/static/images/Mattermost-logodark.png
Binary files differ
diff --git a/web/templates/channel.html b/web/templates/channel.html
index 8e856032d..6325069ee 100644
--- a/web/templates/channel.html
+++ b/web/templates/channel.html
@@ -47,6 +47,7 @@
<div id="channel_info_modal"></div>
<div id="access_history_modal"></div>
<div id="activity_log_modal"></div>
+ <div id="removed_from_channel_modal"></div>
<script>
window.setup_channel_page('{{ .Props.TeamDisplayName }}', '{{ .Props.TeamType }}', '{{ .Props.TeamId }}', '{{ .Props.ChannelName }}', '{{ .Props.ChannelId }}');
</script>
diff --git a/web/templates/head.html b/web/templates/head.html
index d14340998..7a7d4fe8e 100644
--- a/web/templates/head.html
+++ b/web/templates/head.html
@@ -36,6 +36,13 @@
<script type="text/javascript" src="https://cloudfront.loggly.com/js/loggly.tracker.js" async></script>
<script id="config" type="text/javascript" src="/static/config/config.js"></script>
+ <style id="antiClickjack">body{display:none !important;}</style>
+ <script type="text/javascript">
+ if (self === top) {
+ var blocker = document.getElementById("antiClickjack");
+ blocker.parentNode.removeChild(blocker);
+ }
+ </script>
<script>
if (config == null) {
config = {};