summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/channel_header.jsx44
-rw-r--r--web/react/components/edit_channel_modal.jsx2
-rw-r--r--web/react/components/get_link_modal.jsx2
-rw-r--r--web/react/components/member_list_item.jsx2
-rw-r--r--web/react/components/member_list_team.jsx2
-rw-r--r--web/react/components/navbar.jsx159
-rw-r--r--web/react/components/new_channel.jsx2
-rw-r--r--web/react/components/post_info.jsx3
-rw-r--r--web/react/components/post_list.jsx3
-rw-r--r--web/react/components/post_right.jsx2
-rw-r--r--web/react/components/search_bar.jsx2
-rw-r--r--web/react/components/sidebar_header.jsx50
-rw-r--r--web/react/components/user_profile.jsx4
-rw-r--r--web/react/components/user_settings.jsx21
-rw-r--r--web/react/stores/channel_store.jsx53
-rw-r--r--web/react/stores/user_store.jsx2
-rw-r--r--web/react/utils/utils.jsx31
17 files changed, 189 insertions, 195 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index fe381a59e..2e430489f 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -53,12 +53,12 @@ var PopoverListMembers = React.createClass({
});
members.forEach(function(m) {
- popoverHtml += "<div style='white-space: nowrap'>" + m.username + "</div>";
+ popoverHtml += "<div class='text--nowrap'>" + m.username + "</div>";
});
}
return (
- <div style={{cursor : "pointer"}} id="member_popover" data-toggle="popover" data-content={popoverHtml} data-original-title="Members" >
+ <div id="member_popover" data-toggle="popover" data-content={popoverHtml} data-original-title="Members" >
<div id="member_tooltip" data-toggle="tooltip" title="View Channel Members">
{count} <span className="glyphicon glyphicon-user" aria-hidden="true"></span>
</div>
@@ -142,10 +142,10 @@ module.exports = React.createClass({
return null;
}
- var description = utils.textToJsx(this.state.channel.description, {"singleline": true, "noMentionHighlight": true});
- var popoverContent = React.renderToString(<MessageWrapper message={this.state.channel.description}/>);
- var channelTitle = this.state.channel.display_name;
- var channelName = this.state.channel.name;
+ var channel = this.state.channel;
+ var description = utils.textToJsx(channel.description, {"singleline": true, "noMentionHighlight": true});
+ var popoverContent = React.renderToString(<MessageWrapper message={channel.description}/>);
+ var channelTitle = channel.display_name;
var currentId = UserStore.getCurrentId();
var isAdmin = this.state.memberChannel.roles.indexOf("admin") > -1 || this.state.memberTeam.roles.indexOf("admin") > -1;
var isDirect = (this.state.channel.type === 'D');
@@ -169,23 +169,26 @@ module.exports = React.createClass({
<span className="glyphicon glyphicon-chevron-down header-dropdown__icon"></span>
</a>
<ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
- <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_info" data-channelid={this.state.channel.id} href="#">View Info</a></li>
- <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_invite" href="#">Add Members</a></li>
- { isAdmin ?
+ <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_info" data-channelid={channel.id} href="#">View Info</a></li>
+ { !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_invite" href="#">Add Members</a></li>
+ : null
+ }
+ { isAdmin && !ChannelStore.isDefault(channel) ?
<li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_members" href="#">Manage Members</a></li>
: null
}
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={this.state.channel.description} data-title={channelTitle} data-channelid={this.state.channel.id}>Set Channel Description...</a></li>
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#channel_notifications" data-title={channelTitle} data-channelid={this.state.channel.id}>Notification Preferences</a></li>
- { isAdmin && channelName != Constants.DEFAULT_CHANNEL ?
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#rename_channel" data-display={channelTitle} data-name={this.state.channel.name} data-channelid={this.state.channel.id}>Rename Channel...</a></li>
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set Channel Description...</a></li>
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#channel_notifications" data-title={channel.display_name} data-channelid={channel.id}>Notification Preferences</a></li>
+ { isAdmin && !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#rename_channel" data-display={channel.display_name} data-name={channel.name} data-channelid={channel.id}>Rename Channel...</a></li>
: null
}
- { isAdmin && channelName != Constants.DEFAULT_CHANNEL ?
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#delete_channel" data-title={channelTitle} data-channelid={this.state.channel.id}>Delete Channel...</a></li>
+ { isAdmin && !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#delete_channel" data-title={channel.display_name} data-channelid={channel.id}>Delete Channel...</a></li>
: null
}
- { channelName != Constants.DEFAULT_CHANNEL ?
+ { !ChannelStore.isDefault(channel) ?
<li role="presentation"><a role="menuitem" href="#" onClick={this.handleLeave}>Leave Channel</a></li>
: null
}
@@ -197,14 +200,13 @@ module.exports = React.createClass({
<a href="#"><strong className="heading">{channelTitle}</strong></a>
}
</th>
- <th><PopoverListMembers members={this.state.users} channelId={this.state.channel.id} /></th>
+ <th><PopoverListMembers members={this.state.users} channelId={channel.id} /></th>
<th className="search-bar__container"><NavbarSearchBox /></th>
<th>
- <div className="dropdown" style={{marginLeft:5, marginRight:10}}>
+ <div className="dropdown channel-header__links">
<a href="#" className="dropdown-toggle theme" type="button" id="channel_header_right_dropdown" data-toggle="dropdown" aria-expanded="true">
- <i className="fa fa-caret-down"></i>
- </a>
- <ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_right_dropdown" style={{left: "-150px"}}>
+ <span dangerouslySetInnerHTML={{__html: " <svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>"}} /> </a>
+ <ul className="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="channel_header_right_dropdown">
<li role="presentation"><a role="menuitem" href="#" onClick={this.searchMentions}>Recent Mentions</a></li>
</ul>
</div>
diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx
index 255654fd5..c0818959a 100644
--- a/web/react/components/edit_channel_modal.jsx
+++ b/web/react/components/edit_channel_modal.jsx
@@ -43,7 +43,7 @@ module.exports = React.createClass({
<h4 className="modal-title" ref="title">Edit {this.state.title} Description</h4>
</div>
<div className="modal-body">
- <textarea className="form-control" style={{resize: "none"}} rows="6" ref="channelDesc" maxLength="1024" value={this.state.description} onChange={this.handleUserInput}></textarea>
+ <textarea className="form-control no-resize" rows="6" ref="channelDesc" maxLength="1024" value={this.state.description} onChange={this.handleUserInput}></textarea>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
diff --git a/web/react/components/get_link_modal.jsx b/web/react/components/get_link_modal.jsx
index bbfdce63a..af5314e64 100644
--- a/web/react/components/get_link_modal.jsx
+++ b/web/react/components/get_link_modal.jsx
@@ -38,7 +38,7 @@ module.exports = React.createClass({
<div className="modal-body">
<p>{"The link below is used for open " + strings.TeamPlural + " or if you allowed your " + strings.Team + " members to sign up using their " + strings.Company + " email addresses."}
</p>
- <textarea className="form-control" style={{resize: "none"}} readOnly="true" value={this.state.value}></textarea>
+ <textarea className="form-control no-resize" readOnly="true" value={this.state.value}></textarea>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx
index cf8c71d7e..a5279909b 100644
--- a/web/react/components/member_list_item.jsx
+++ b/web/react/components/member_list_item.jsx
@@ -49,7 +49,7 @@ module.exports = React.createClass({
</div>
);
} else {
- invite = <div className="member-role text-capitalize" style={{marginRight: 15}}>{member.roles || 'Member'}</div>;
+ invite = <div className="member-role text-capitalize">{member.roles || 'Member'}<span className="caret hidden"></span></div>;
}
return (
diff --git a/web/react/components/member_list_team.jsx b/web/react/components/member_list_team.jsx
index aa53c5db6..89b5e49d5 100644
--- a/web/react/components/member_list_team.jsx
+++ b/web/react/components/member_list_team.jsx
@@ -59,7 +59,7 @@ var MemberListTeamItem = React.createClass({
return {};
},
render: function() {
- var server_error = this.state.server_error ? <div style={{ clear: "both" }} className="has-error"><label className='has-error control-label'>{this.state.server_error}</label></div> : null;
+ var server_error = this.state.server_error ? <div className="has-error"><label className='has-error control-label'>{this.state.server_error}</label></div> : null;
var user = this.props.user;
var currentRoles = "Member";
var timestamp = UserStore.getCurrentUser().update_at;
diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx
index 35f7d9044..78cf7d8b8 100644
--- a/web/react/components/navbar.jsx
+++ b/web/react/components/navbar.jsx
@@ -2,21 +2,20 @@
// See License.txt for license information.
-var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
-var Sidebar = require('./sidebar.jsx');
var UserStore = require('../stores/user_store.jsx');
-var SocketStore = require('../stores/socket_store.jsx');
var ChannelStore = require('../stores/channel_store.jsx');
-var Constants = require('../utils/constants.jsx');
+
var UserProfile = require('./user_profile.jsx');
var MessageWrapper = require('./message_wrapper.jsx');
+
+var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes;
+var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
function getCountsStateFromStores() {
-
var count = 0;
var channels = ChannelStore.getAll();
var members = ChannelStore.getAllMembers();
@@ -34,7 +33,7 @@ function getCountsStateFromStores() {
}
});
- return { count: count }
+ return { count: count };
}
var NotifyCounts = React.createClass({
@@ -54,11 +53,10 @@ var NotifyCounts = React.createClass({
return getCountsStateFromStores();
},
render: function() {
- if (this.state.count == 0) {
- return (<span></span>);
- }
- else {
- return (<span className="badge badge-notify">{ this.state.count }</span>);
+ if (this.state.count) {
+ return <span className="badge badge-notify">{ this.state.count }</span>;
+ } else {
+ return null;
}
}
});
@@ -66,25 +64,25 @@ var NotifyCounts = React.createClass({
var NavbarLoginForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
- var state = { }
+ var state = { };
var domain = this.refs.domain.getDOMNode().value.trim();
if (!domain) {
- state.server_error = "A domain is required"
+ state.server_error = "A domain is required";
this.setState(state);
return;
}
var email = this.refs.email.getDOMNode().value.trim();
if (!email) {
- state.server_error = "An email is required"
+ state.server_error = "An email is required";
this.setState(state);
return;
}
var password = this.refs.password.getDOMNode().value.trim();
if (!password) {
- state.server_error = "A password is required"
+ state.server_error = "A password is required";
this.setState(state);
return;
}
@@ -105,7 +103,7 @@ var NavbarLoginForm = React.createClass({
window.location.href = '/channels/town-square';
}
- }.bind(this),
+ },
function(err) {
if (err.message == "Login failed because email address has not been verified") {
window.location.href = '/verify?domain=' + encodeURIComponent(domain) + '&email=' + encodeURIComponent(email);
@@ -159,13 +157,14 @@ function getStateFromStores() {
}
module.exports = React.createClass({
+ displayName: 'Navbar',
+
componentDidMount: function() {
ChannelStore.addChangeListener(this._onChange);
ChannelStore.addExtraInfoChangeListener(this._onChange);
- var self = this;
- $('.inner__wrap').click(self.hideSidebars);
+ $('.inner__wrap').click(this.hideSidebars);
- $('body').on('click.infopopover', function(e){
+ $('body').on('click.infopopover', function(e) {
if ($(e.target).attr('data-toggle') !== 'popover'
&& $(e.target).parents('.popover.in').length === 0) {
$('.info-popover').popover('hide');
@@ -181,13 +180,13 @@ module.exports = React.createClass({
},
handleLeave: function(e) {
client.leaveChannel(this.state.channel.id,
- function(data) {
+ function() {
AsyncClient.getChannels(true);
window.location.href = '/channels/town-square';
- }.bind(this),
+ },
function(err) {
AsyncClient.dispatchError(err, "handleLeave");
- }.bind(this)
+ }
);
},
hideSidebars: function(e) {
@@ -204,7 +203,7 @@ module.exports = React.createClass({
});
if (e.target.className != 'navbar-toggle' && e.target.className != 'icon-bar') {
- $('.inner__wrap').removeClass('move--right').removeClass('move--left').removeClass('move--left-small');
+ $('.inner__wrap').removeClass('move--right move--left move--left-small');
$('.sidebar--left').removeClass('move--right');
$('.sidebar--right').removeClass('move--left');
$('.sidebar--menu').removeClass('move--left');
@@ -229,24 +228,22 @@ module.exports = React.createClass({
render: function() {
var currentId = UserStore.getCurrentId();
- var channelName = "";
var popoverContent = "";
var channelTitle = this.props.teamName;
var isAdmin = false;
var isDirect = false;
var description = ""
+ var channel = this.state.channel;
- if (this.state.channel) {
- var channel = this.state.channel;
- description = utils.textToJsx(this.state.channel.description, {"singleline": true, "noMentionHighlight": true});
- popoverContent = React.renderToString(<MessageWrapper message={this.state.channel.description}/>);
- channelName = this.state.channel.name;
+ if (channel) {
+ description = utils.textToJsx(channel.description, {"singleline": true, "noMentionHighlight": true});
+ popoverContent = React.renderToString(<MessageWrapper message={channel.description}/>);
isAdmin = this.state.member.roles.indexOf("admin") > -1;
if (channel.type === 'O') {
- channelTitle = this.state.channel.display_name;
+ channelTitle = channel.display_name;
} else if (channel.type === 'P') {
- channelTitle = this.state.channel.display_name;
+ channelTitle = channel.display_name;
} else if (channel.type === 'D') {
isDirect = true;
if (this.state.users.length > 1) {
@@ -258,12 +255,11 @@ module.exports = React.createClass({
}
}
- if(this.state.channel.description.length == 0){
- popoverContent = React.renderToString(<div>No channel description yet. <br /><a href='#' data-toggle='modal' data-desc={this.state.channel.description} data-title={this.state.channel.display_name} data-channelid={this.state.channel.id} data-target='#edit_channel'>Click here</a> to add one.</div>);
+ if (channel.description.length == 0) {
+ popoverContent = React.renderToString(<div>No channel description yet. <br /><a href='#' data-toggle='modal' data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id} data-target='#edit_channel'>Click here</a> to add one.</div>);
}
}
- var loginForm = currentId == null ? <NavbarLoginForm /> : null;
var navbar_collapse_button = currentId != null ? null :
<button type="button" className="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
<span className="sr-only">Toggle sidebar</span>
@@ -292,60 +288,61 @@ module.exports = React.createClass({
{ navbar_collapse_button }
{ sidebar_collapse_button }
{ right_sidebar_collapse_button }
- { !isDirect && this.state.channel ?
- <div className="navbar-brand">
- <div className="dropdown">
- <div data-toggle="popover" data-content={popoverContent} className="description info-popover"></div>
- <a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
- <strong className="heading">{channelTitle} </strong>
- <span className="glyphicon glyphicon-chevron-down header-dropdown__icon"></span>
- </a>
- <ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
- <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_invite" href="#">Add Members</a></li>
- { isAdmin ?
- <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_members" href="#">Manage Members</a></li>
- : ""
- }
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={this.state.channel.description} data-title={this.state.channel.display_name} data-channelid={this.state.channel.id}>Set Channel Description...</a></li>
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#channel_notifications" data-title={this.state.channel.display_name} data-channelid={this.state.channel.id}>Notification Preferences</a></li>
- { isAdmin && channelName != Constants.DEFAULT_CHANNEL ?
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#rename_channel" data-display={this.state.channel.display_name} data-name={this.state.channel.name} data-channelid={this.state.channel.id}>Rename Channel...</a></li>
- : ""
- }
- { isAdmin && channelName != Constants.DEFAULT_CHANNEL ?
- <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#delete_channel" data-title={this.state.channel.display_name} data-channelid={this.state.channel.id}>Delete Channel...</a></li>
- : ""
- }
- { channelName != Constants.DEFAULT_CHANNEL ?
- <li role="presentation"><a role="menuitem" href="#" onClick={this.handleLeave}>Leave Channel</a></li>
- : ""
- }
- </ul>
+ { !isDirect && channel ?
+ <div className="navbar-brand">
+ <div className="dropdown">
+ <div data-toggle="popover" data-content={popoverContent} className="description info-popover"></div>
+ <a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
+ <span className="heading">{channelTitle} </span>
+ <span className="glyphicon glyphicon-chevron-down header-dropdown__icon"></span>
+ </a>
+ <ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
+ { !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_invite" href="#">Add Members</a></li>
+ : null
+ }
+ { isAdmin && !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_members" href="#">Manage Members</a></li>
+ : null
+ }
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set Channel Description...</a></li>
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#channel_notifications" data-title={channel.display_name} data-channelid={channel.id}>Notification Preferences</a></li>
+ { isAdmin && !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#rename_channel" data-display={channel.display_name} data-name={channel.name} data-channelid={channel.id}>Rename Channel...</a></li>
+ : null
+ }
+ { isAdmin && !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#delete_channel" data-title={channel.display_name} data-channelid={channel.id}>Delete Channel...</a></li>
+ : null
+ }
+ { !ChannelStore.isDefault(channel) ?
+ <li role="presentation"><a role="menuitem" href="#" onClick={this.handleLeave}>Leave Channel</a></li>
+ : null
+ }
+ </ul>
+ </div>
</div>
- </div>
- : "" }
- { isDirect && this.state.channel ?
+ : null
+ }
+ { isDirect && channel ?
<div className="navbar-brand">
- <strong>
- <a href="#"><strong className="heading">{channelTitle}</strong></a>
- </strong>
+ <a href="#" className="heading">{ channelTitle }</a>
</div>
- : "" }
- { !this.state.channel ?
+ : null }
+ { !channel ?
<div className="navbar-brand">
- <strong>
- <a href="/"><strong className="heading">{ channelTitle }</strong></a>
- </strong>
+ <a href="/" className="heading">{ channelTitle }</a>
</div>
- : "" }
- </div>
- <div className="collapse navbar-collapse" id="navbar-collapse-1">
- { loginForm }
+ : null }
</div>
+ { !currentId ?
+ <div className="collapse navbar-collapse" id="navbar-collapse-1">
+ <NavbarLoginForm />
+ </div>
+ : null
+ }
</div>
</nav>
);
-}
+ }
});
-
-
diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx
index 160241c1c..069e0d6b1 100644
--- a/web/react/components/new_channel.jsx
+++ b/web/react/components/new_channel.jsx
@@ -122,7 +122,7 @@ module.exports = React.createClass({
</div>
<div className="form-group">
<label className='control-label'>Description</label>
- <textarea className="form-control" style={{resize: "none"}} ref="channel_desc" rows="3" placeholder="Description" maxLength="1024"></textarea>
+ <textarea className="form-control no-resize" ref="channel_desc" rows="3" placeholder="Description" maxLength="1024"></textarea>
</div>
{ server_error }
</form>
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx
index cf01747f0..48efa95ba 100644
--- a/web/react/components/post_info.jsx
+++ b/web/react/components/post_info.jsx
@@ -11,6 +11,7 @@ module.exports = React.createClass({
render: function() {
var post = this.props.post;
var isOwner = UserStore.getCurrentId() == post.user_id;
+ var isAdmin = UserStore.getCurrentUser().roles.indexOf("admin") > -1
var type = "Post"
if (post.root_id.length > 0) {
@@ -36,7 +37,7 @@ module.exports = React.createClass({
<ul className="dropdown-menu" role="menu">
{ isOwner ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#edit_post" data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Edit</a></li>
: "" }
- { isOwner ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#delete_post" data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Delete</a></li>
+ { isOwner || isAdmin ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#delete_post" data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Delete</a></li>
: "" }
{ this.props.allowReply === "true" ? <li role="presentation"><a className="reply-link theme" href="#" onClick={this.props.handleCommentClick}>Reply</a></li>
: "" }
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 98491976f..573799a19 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -6,7 +6,6 @@ var ChannelStore = require('../stores/channel_store.jsx');
var UserStore = require('../stores/user_store.jsx');
var UserProfile = require( './user_profile.jsx' );
var AsyncClient = require('../utils/async_client.jsx');
-var CreatePost = require('./create_post.jsx');
var Post = require('./post.jsx');
var LoadingScreen = require('./loading_screen.jsx');
var SocketStore = require('../stores/socket_store.jsx');
@@ -341,7 +340,7 @@ module.exports = React.createClass({
}
}
- if (channel.name === Constants.DEFAULT_CHANNEL) {
+ if (ChannelStore.isDefault(channel)) {
more_messages = (
<div className="channel-intro">
<h4 className="channel-intro-title">Welcome</h4>
diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx
index 408fbf83a..dca05051d 100644
--- a/web/react/components/post_right.jsx
+++ b/web/react/components/post_right.jsx
@@ -43,7 +43,7 @@ RhsHeaderPost = React.createClass({
});
},
render: function() {
- var back = this.props.fromSearch ? <a href="#" onClick={this.handleBack} style={{color:"black"}}>{"< "}</a> : "";
+ var back = this.props.fromSearch ? <a href="#" onClick={this.handleBack} className="sidebar--right__back"><i className="fa fa-chevron-left"></i></a> : "";
return (
<div className="sidebar--right__header">
diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index ab7e99d60..f21f0cd58 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -92,7 +92,7 @@ module.exports = React.createClass({
render: function() {
return (
<div>
- <div className="sidebar__collapse" onClick={this.handleClose}></div>
+ <div className="sidebar__collapse" onClick={this.handleClose}>Cancel</div>
<span className="glyphicon glyphicon-search sidebar__search-icon"></span>
<form role="form" className="search__form relative-div" onSubmit={this.handleSubmit}>
<input
diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx
index 54858a04d..45c9ca629 100644
--- a/web/react/components/sidebar_header.jsx
+++ b/web/react/components/sidebar_header.jsx
@@ -37,17 +37,13 @@ var NavbarDropdown = React.createClass({
var invite_link = "";
var manage_link = "";
var rename_link = "";
- var currentUser = UserStore.getCurrentUser()
+ var currentUser = UserStore.getCurrentUser();
var isAdmin = false;
if (currentUser != null) {
isAdmin = currentUser.roles.indexOf("admin") > -1;
- invite_link = (
- <li>
- <a href="#" data-toggle="modal" data-target="#invite_member">Invite New Member</a>
- </li>
- );
+ invite_link = ( <li> <a href="#" data-toggle="modal" data-target="#invite_member">Invite New Member</a> </li>);
if (this.props.teamType == "O") {
team_link = (
@@ -59,16 +55,8 @@ var NavbarDropdown = React.createClass({
}
if (isAdmin) {
- manage_link = (
- <li>
- <a href="#" data-toggle="modal" data-target="#team_members">Manage Team</a>
- </li>
- );
- rename_link = (
- <li>
- <a href="#" data-toggle="modal" data-target="#rename_team_link">Rename</a>
- </li>
- );
+ manage_link = ( <li> <a href="#" data-toggle="modal" data-target="#team_members">Manage Team</a> </li>);
+ rename_link = ( <li> <a href="#" data-toggle="modal" data-target="#rename_team_link">Rename</a> </li>);
}
var teams = [];
@@ -91,11 +79,11 @@ var NavbarDropdown = React.createClass({
<ul className="nav navbar-nav navbar-right">
<li className="dropdown">
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
- <i className="dropdown__icon"></i>
+ <span className="dropdown__icon" dangerouslySetInnerHTML={{__html: " <svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>"}} />
</a>
<ul className="dropdown-menu" role="menu">
<li><a href="#" data-toggle="modal" data-target="#user_settings1">Account Settings</a></li>
- { isAdmin ? <li><a href="#" data-toggle="modal" data-target="#team_settings">Team Settings</a></li> : "" }
+ { isAdmin ? <li><a href="#" data-toggle="modal" data-target="#team_settings">Team Settings</a></li> : null }
{ invite_link }
{ team_link }
{ manage_link }
@@ -113,28 +101,30 @@ var NavbarDropdown = React.createClass({
});
module.exports = React.createClass({
- handleSubmit: function(e) {
- e.preventDefault();
- },
- getInitialState: function() {
- return { };
+ displayName: 'SidebarHeader',
+
+ getDefaultProps: function() {
+ return {
+ teamName: config.SiteName
+ };
},
+
render: function() {
- var teamName = this.props.teamName ? this.props.teamName : config.SiteName;
- var me = UserStore.getCurrentUser()
+ var me = UserStore.getCurrentUser();
+
+ if (!me) {
+ return null;
+ }
return (
<div className="team__header theme">
<img className="user__picture" src={"/api/v1/users/" + me.id + "/image?time=" + me.update_at} />
<div className="header__info">
- <div className="user__name">@{me.username}</div>
- <a className="team__name" href="/channels/town-square">{ teamName }</a>
+ <div className="user__name">{'@' + me.username}</div>
+ <a className="team__name" href="/channels/town-square">{this.props.teamName}</a>
</div>
<NavbarDropdown teamType={this.props.teamType} />
</div>
);
}
});
-
-
-
diff --git a/web/react/components/user_profile.jsx b/web/react/components/user_profile.jsx
index 89d0a80ff..65f025919 100644
--- a/web/react/components/user_profile.jsx
+++ b/web/react/components/user_profile.jsx
@@ -53,7 +53,7 @@ module.exports = React.createClass({
var name = this.props.overwriteName ? this.props.overwriteName : this.state.profile.username;
- var data_content = "<img style='margin: 10px' src='/api/v1/users/" + this.state.profile.id + "/image?time=" + this.state.profile.update_at + "' height='128' width='128' />";
+ var data_content = "<img class='user-popover__image' src='/api/v1/users/" + this.state.profile.id + "/image?time=" + this.state.profile.update_at + "' height='128' width='128' />";
if (!config.ShowEmail) {
data_content += "<div class='text-nowrap'>Email not shared</div>";
} else {
@@ -61,7 +61,7 @@ module.exports = React.createClass({
}
return (
- <div style={{"cursor" : "pointer", "display" : "inline-block"}} className="user-popover" id={"profile_" + this.uniqueId} data-toggle="popover" data-content={data_content} data-original-title={this.state.profile.username} >
+ <div className="user-popover" id={"profile_" + this.uniqueId} data-toggle="popover" data-content={data_content} data-original-title={this.state.profile.username} >
{ name }
</div>
);
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index 06d8d0208..38e4b1aea 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -560,7 +560,7 @@ var AuditTab = React.createClass({
<div className="user-settings">
<h3 className="tab-header">Activity Log</h3>
<div className="divider-dark first"/>
- <div className="table-responsive" style={{ maxWidth: "560px", maxHeight: "300px" }}>
+ <div className="table-responsive">
<table className="table-condensed small">
<thead>
<tr>
@@ -576,11 +576,11 @@ var AuditTab = React.createClass({
this.state.audits.map(function(value, index) {
return (
<tr key={ "" + index }>
- <td style={{ whiteSpace: "nowrap" }}>{ new Date(value.create_at).toLocaleString() }</td>
- <td style={{ whiteSpace: "nowrap" }}>{ value.action.replace("/api/v1", "") }</td>
- <td style={{ whiteSpace: "nowrap" }}>{ value.ip_address }</td>
- <td style={{ whiteSpace: "nowrap" }}>{ value.session_id }</td>
- <td style={{ whiteSpace: "nowrap" }}>{ value.extra_info }</td>
+ <td className="text-nowrap">{ new Date(value.create_at).toLocaleString() }</td>
+ <td className="text-nowrap">{ value.action.replace("/api/v1", "") }</td>
+ <td className="text-nowrap">{ value.ip_address }</td>
+ <td className="text-nowrap">{ value.session_id }</td>
+ <td className="text-nowrap">{ value.extra_info }</td>
</tr>
);
}, this)
@@ -820,6 +820,7 @@ var GeneralTab = React.createClass({
client.uploadProfileImage(formData,
function(data) {
this.submitActive = false;
+ AsyncClient.getMe();
window.location.reload();
}.bind(this),
function(err) {
@@ -989,7 +990,7 @@ var GeneralTab = React.createClass({
<SettingPicture
title="Profile Picture"
submit={this.submitPicture}
- src={"/api/v1/users/" + user.id + "/image"}
+ src={"/api/v1/users/" + user.id + "/image?time=" + user.last_picture_update}
server_error={server_error}
client_error={client_error}
updateSection={function(e){self.updateSection("");e.preventDefault();}}
@@ -1000,10 +1001,14 @@ var GeneralTab = React.createClass({
);
} else {
+ var minMessage = "Click Edit to upload an image.";
+ if (user.last_picture_update) {
+ minMessage = "Image last updated " + utils.displayDate(user.last_picture_update)
+ }
pictureSection = (
<SettingItemMin
title="Profile Picture"
- describe="Picture inside."
+ describe={minMessage}
updateSection={function(){self.updateSection("picture");}}
/>
);
diff --git a/web/react/stores/channel_store.jsx b/web/react/stores/channel_store.jsx
index 4a27e5f17..a97f13391 100644
--- a/web/react/stores/channel_store.jsx
+++ b/web/react/stores/channel_store.jsx
@@ -44,40 +44,24 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
removeExtraInfoChangeListener: function(callback) {
this.removeListener(EXTRA_INFO_EVENT, callback);
},
- get: function(id) {
- var current = null;
- var c = this._getChannels();
-
- c.some(function(channel) {
- if (channel.id == id) {
- current = channel;
- return true;
+ findFirstBy: function(field, value) {
+ var channels = this._getChannels();
+ for (var i = 0; i < channels.length; i++) {
+ if (channels[i][field] == value) {
+ return channels[i];
}
- return false;
- });
+ }
- return current;
+ return null;
+ },
+ get: function(id) {
+ return this.findFirstBy('id', id);
},
getMember: function(id) {
- var current = null;
return this.getAllMembers()[id];
},
getByName: function(name) {
- var current = null;
- var c = this._getChannels();
-
- c.some(function(channel) {
- if (channel.name == name) {
- current = channel;
- return true;
- }
-
- return false;
-
- });
-
- return current;
-
+ return this.findFirstBy('name', name);
},
getAll: function() {
return this._getChannels();
@@ -120,7 +104,7 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
getCurrent: function() {
var currentId = this.getCurrentId();
- if (currentId != null)
+ if (currentId)
return this.get(currentId);
else
return null;
@@ -128,7 +112,7 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
getCurrentMember: function() {
var currentId = ChannelStore.getCurrentId();
- if (currentId != null)
+ if (currentId)
return this.getAllMembers()[currentId];
else
return null;
@@ -143,7 +127,7 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
var currentId = ChannelStore.getCurrentId();
var extra = null;
- if (currentId != null)
+ if (currentId)
extra = this._getExtraInfos()[currentId];
if (extra == null)
@@ -154,7 +138,7 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
getExtraInfo: function(channel_id) {
var extra = null;
- if (channel_id != null)
+ if (channel_id)
extra = this._getExtraInfos()[channel_id];
if (extra == null)
@@ -192,7 +176,10 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
},
_getExtraInfos: function() {
return BrowserStore.getItem("extra_infos", {});
- }
+ },
+ isDefault: function(channel) {
+ return channel.name == Constants.DEFAULT_CHANNEL;
+ }
});
ChannelStore.dispatchToken = AppDispatcher.register(function(payload) {
@@ -231,4 +218,4 @@ ChannelStore.dispatchToken = AppDispatcher.register(function(payload) {
}
});
-module.exports = ChannelStore;
+module.exports = ChannelStore; \ No newline at end of file
diff --git a/web/react/stores/user_store.jsx b/web/react/stores/user_store.jsx
index 93ddfec70..dd207ca80 100644
--- a/web/react/stores/user_store.jsx
+++ b/web/react/stores/user_store.jsx
@@ -177,7 +177,7 @@ var UserStore = assign({}, EventEmitter.prototype, {
},
getCurrentMentionKeys: function() {
var user = this.getCurrentUser();
- if (user.notify_props && user.notify_props.mention_keys) {
+ if (user && user.notify_props && user.notify_props.mention_keys) {
var keys = user.notify_props.mention_keys.split(',');
if (user.full_name.length > 0 && user.notify_props.first_name === "true") {
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 19c074606..7186251e7 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -198,7 +198,13 @@ module.exports.getTimestamp = function() {
}
var testUrlMatch = function(text) {
- var urlMatcher = new Autolinker.matchParser.MatchParser;
+ var urlMatcher = new Autolinker.matchParser.MatchParser({
+ urls: true,
+ emails: false,
+ twitter: false,
+ phone: false,
+ hashtag: false,
+ });
var result = [];
var replaceFn = function(match) {
var linkData = {};
@@ -303,18 +309,25 @@ var getYoutubeEmbed = function(link) {
};
var success = function(data) {
- $('.video-uploader.'+youtubeId).html(data.data.uploader);
- $('.video-title.'+youtubeId).find('a').html(data.data.title);
+ if(!data.items.length || !data.items[0].snippet) {
+ return;
+ }
+ var metadata = data.items[0].snippet;
+ $('.video-uploader.'+youtubeId).html(metadata.channelTitle);
+ $('.video-title.'+youtubeId).find('a').html(metadata.title);
$(".post-list-holder-by-time").scrollTop($(".post-list-holder-by-time")[0].scrollHeight);
$(".post-list-holder-by-time").perfectScrollbar('update');
};
- $.ajax({
- async: true,
- url: 'https://gdata.youtube.com/feeds/api/videos/'+youtubeId+'?v=2&alt=jsonc',
- type: 'GET',
- success: success
- });
+ if(config.GoogleDeveloperKey) {
+ $.ajax({
+ async: true,
+ url: "https://www.googleapis.com/youtube/v3/videos",
+ type: 'GET',
+ data: {part:"snippet", id:youtubeId, key:config.GoogleDeveloperKey},
+ success: success
+ });
+ }
return (
<div className="post-comment">