diff options
Diffstat (limited to 'web/react')
-rw-r--r-- | web/react/components/channel_header.jsx | 11 | ||||
-rw-r--r-- | web/react/components/edit_channel_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/get_link_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/member_list_item.jsx | 2 | ||||
-rw-r--r-- | web/react/components/member_list_team.jsx | 2 | ||||
-rw-r--r-- | web/react/components/mention.jsx | 10 | ||||
-rw-r--r-- | web/react/components/mention_list.jsx | 100 | ||||
-rw-r--r-- | web/react/components/new_channel.jsx | 2 | ||||
-rw-r--r-- | web/react/components/post_right.jsx | 2 | ||||
-rw-r--r-- | web/react/components/sidebar_header.jsx | 2 | ||||
-rw-r--r-- | web/react/components/user_profile.jsx | 4 | ||||
-rw-r--r-- | web/react/components/user_settings.jsx | 12 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 23 |
13 files changed, 135 insertions, 39 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index fe381a59e..836454b46 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> @@ -200,11 +200,10 @@ module.exports = React.createClass({ <th><PopoverListMembers members={this.state.users} channelId={this.state.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/mention.jsx b/web/react/components/mention.jsx index 520b81cbb..114dc183f 100644 --- a/web/react/components/mention.jsx +++ b/web/react/components/mention.jsx @@ -6,16 +6,22 @@ module.exports = React.createClass({ handleClick: function() { this.props.handleClick(this.props.username); }, + getInitialState: function() { + return null; + }, render: function() { + var self = this; var icon; var timestamp = UserStore.getCurrentUser().update_at; - if (this.props.id != null) { + if (this.props.id === "allmention" || this.props.id === "channelmention") { + icon = <span><i className="mention-img fa fa-users fa-2x"></i></span>; + } else if (this.props.id != null) { icon = <span><img className="mention-img" src={"/api/v1/users/" + this.props.id + "/image?time=" + timestamp}/></span>; } else { icon = <span><i className="mention-img fa fa-users fa-2x"></i></span>; } return ( - <div className="mentions-name" onClick={this.handleClick}> + <div className={"mentions-name " + this.props.isFocused} id={this.props.id + "_mentions"} onClick={this.handleClick} onMouseEnter={this.props.handleMouseEnter}> <div className="pull-left">{icon}</div> <div className="pull-left mention-align"><span>@{this.props.username}</span><span className="mention-fullname">{this.props.secondary_text}</span></div> </div> diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx index 103ff29bb..c5ff82346 100644 --- a/web/react/components/mention_list.jsx +++ b/web/react/components/mention_list.jsx @@ -17,14 +17,37 @@ module.exports = React.createClass({ displayName: "MentionList", componentDidMount: function() { PostStore.addMentionDataChangeListener(this._onChange); - var self = this; - $('body').on('keypress.mentionlist', '#'+this.props.id, + + $('body').on('keydown.mentionlist', '#'+this.props.id, function(e) { - if (!self.isEmpty() && self.state.mentionText != '-1' && e.which === 13) { + if (!self.isEmpty() && self.state.mentionText != '-1' && (e.which === 13 || e.which === 9)) { + e.stopPropagation(); + e.preventDefault(); + self.addCurrentMention(); + } + else if (!self.isEmpty() && self.state.mentionText != '-1' && (e.which === 38 || e.which === 40)) { e.stopPropagation(); e.preventDefault(); - self.addFirstMention(); + + var tempSelectedMention = -1; + if (e.which === 38) { + if (self.getSelection(self.state.selectedMention - 1)) + self.setState({ selectedMention: self.state.selectedMention - 1, selectedUsername: self.refs['mention' + (self.state.selectedMention - 1)].props.username }); + else { + while (self.getSelection(++tempSelectedMention)) + ; //Need to find the top of the list + self.setState({ selectedMention: tempSelectedMention - 1, selectedUsername: self.refs['mention' + (tempSelectedMention - 1)].props.username }); + } + } + else if (e.which === 40) { + if (self.getSelection(self.state.selectedMention + 1)) + self.setState({ selectedMention: self.state.selectedMention + 1, selectedUsername: self.refs['mention' + (self.state.selectedMention + 1)].props.username }); + else + self.setState({ selectedMention: 0, selectedUsername: self.refs.mention0.props.username }); + } + + self.scrollToMention(e.which, tempSelectedMention); } } ); @@ -37,7 +60,28 @@ module.exports = React.createClass({ }, componentWillUnmount: function() { PostStore.removeMentionDataChangeListener(this._onChange); - $('body').off('keypress.mentionlist', '#'+this.props.id); + $('body').off('keydown.mentionlist', '#'+this.props.id); + }, + componentDidUpdate: function() { + if (this.state.mentionText != "-1") { + if (this.state.selectedUsername !== "" && (!this.getSelection(this.state.selectedMention) || this.state.selectedUsername !== this.refs['mention' + this.state.selectedMention].props.username)) { + var tempSelectedMention = -1; + var foundMatch = false; + while (tempSelectedMention < this.state.selectedMention && this.getSelection(++tempSelectedMention)) { + if (this.state.selectedUsername === this.refs['mention' + tempSelectedMention].props.username) { + this.setState({ selectedMention: tempSelectedMention }); + foundMatch = true; + break; + } + } + if (this.getSelection(0) && !foundMatch) { + this.setState({ selectedMention: 0, selectedUsername: this.refs.mention0.props.username }); + } + } + } + else if (this.state.selectedMention !== 0) { + this.setState({ selectedMention: 0, selectedUsername: "" }); + } }, _onChange: function(id, mentionText, excludeList) { if (id !== this.props.id) return; @@ -45,6 +89,7 @@ module.exports = React.createClass({ var newState = this.state; if (mentionText != null) newState.mentionText = mentionText; if (excludeList != null) newState.excludeUsers = excludeList; + this.setState(newState); }, handleClick: function(name) { @@ -56,6 +101,21 @@ module.exports = React.createClass({ this.setState({ mentionText: '-1' }); }, + handleMouseEnter: function(listId) { + this.setState({ selectedMention: listId, selectedUsername: this.refs['mention' + listId].props.username }); + }, + getSelection: function(listId) { + if (!this.refs['mention' + listId]) + return false; + else + return true; + }, + addCurrentMention: function() { + if (!this.getSelection(this.state.selectedMention)) + this.addFirstMention(); + else + this.refs['mention' + this.state.selectedMention].handleClick(); + }, addFirstMention: function() { if (!this.refs.mention0) return; this.refs.mention0.handleClick(); @@ -63,6 +123,23 @@ module.exports = React.createClass({ isEmpty: function() { return (!this.refs.mention0); }, + scrollToMention: function(keyPressed, ifLoopUp) { + var direction = keyPressed === 38 ? "up" : "down"; + var scrollAmount = 0; + + if (direction === "up" && ifLoopUp !== -1) + scrollAmount = $("#mentionsbox").height() * 100; //Makes sure that it scrolls all the way to the bottom + else if (direction === "down" && this.state.selectedMention === 0) + scrollAmount = 0; + else if (direction === "up") + scrollAmount = "-=" + ($('#'+this.refs['mention' + this.state.selectedMention].props.id +"_mentions").innerHeight() - 5); + else if (direction === "down") + scrollAmount = "+=" + ($('#'+this.refs['mention' + this.state.selectedMention].props.id +"_mentions").innerHeight() - 5); + + $("#mentionsbox").animate({ + scrollTop: scrollAmount + }, 75); + }, alreadyMentioned: function(username) { var excludeUsers = this.state.excludeUsers; for (var i = 0; i < excludeUsers.length; i++) { @@ -73,9 +150,10 @@ module.exports = React.createClass({ return false; }, getInitialState: function() { - return { excludeUsers: [], mentionText: "-1" }; + return { excludeUsers: [], mentionText: "-1", selectedMention: 0, selectedUsername: "" }; }, render: function() { + var self = this; var mentionText = this.state.mentionText; if (mentionText === '-1') return null; @@ -89,12 +167,14 @@ module.exports = React.createClass({ all.username = "all"; all.full_name = ""; all.secondary_text = "Notifies everyone in the team"; + all.id = "allmention"; users.push(all); var channel = {}; channel.username = "channel"; channel.full_name = ""; channel.secondary_text = "Notifies everyone in the channel"; + channel.id = "channelmention"; users.push(channel); users.sort(function(a,b) { @@ -118,17 +198,21 @@ module.exports = React.createClass({ if (firstName.lastIndexOf(mentionText,0) === 0 || lastName.lastIndexOf(mentionText,0) === 0 || users[i].username.lastIndexOf(mentionText,0) === 0) { - mentions[i+1] = ( + mentions[index] = ( <Mention ref={'mention' + index} username={users[i].username} secondary_text={users[i].secondary_text} id={users[i].id} + listId={index} + isFocused={this.state.selectedMention === index ? "mentions-focus" : ""} + handleMouseEnter={function(value) { return function() { self.handleMouseEnter(value); } }(index)} handleClick={this.handleClick} /> ); index++; } } + var numMentions = Object.keys(mentions).length; if (numMentions < 1) return null; @@ -144,7 +228,7 @@ module.exports = React.createClass({ return ( <div className="mentions--top" style={style}> - <div ref="mentionlist" className="mentions-box"> + <div ref="mentionlist" className="mentions-box" id="mentionsbox"> { mentions } </div> </div> 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_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/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index 54858a04d..83ad4470e 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -91,7 +91,7 @@ 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> 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 b1ccd125a..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) diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 19c074606..6cae7fe89 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -303,18 +303,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"> |