Этот коммит содержится в:
Asaad Mahmood
2015-07-09 21:00:29 +05:00
родитель a533ff4d71 b6fb6ea3be
Коммит b61f653626
21 изменённых файлов: 342 добавлений и 232 удалений

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

@@ -456,6 +456,15 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
user = result.Data.(*model.User) user = result.Data.(*model.User)
} }
var invNum int64 = 0
for i, invite := range invites.Invites {
if result := <-Srv.Store.User().GetByEmail(c.Session.TeamId, invite["email"]); result.Err == nil || result.Err.Message != "We couldn't find the existing account" {
invNum = int64(i)
c.Err = model.NewAppError("invite_members", "This person is already on your team", strconv.FormatInt(invNum, 10))
return
}
}
ia := make([]string, len(invites.Invites)) ia := make([]string, len(invites.Invites))
for _, invite := range invites.Invites { for _, invite := range invites.Invites {
ia = append(ia, invite["email"]) ia = append(ia, invite["email"])

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

@@ -17,6 +17,7 @@ import (
) )
const ( const (
// Also change web/react/stores/browser_store.jsx BROWSER_STORE_VERSION
ETAG_ROOT_VERSION = "11" ETAG_ROOT_VERSION = "11"
) )

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

@@ -10,111 +10,95 @@ var AsyncClient = require('../utils/async_client.jsx');
function getStateFromStores() { function getStateFromStores() {
var users = UserStore.getActiveOnlyProfiles(); var users = UserStore.getActiveOnlyProfiles();
var member_list = ChannelStore.getCurrentExtraInfo().members; var memberIds = ChannelStore.getCurrentExtraInfo().members.map(function(user) { return user.id; });
var nonmember_list = []; var nonmembers = [];
for (var id in users) { for (var id in users) {
var found = false; if (memberIds.indexOf(id) == -1) {
for (var i = 0; i < member_list.length; i++) { nonmembers.push(users[id]);
if (member_list[i].id === id) {
found = true;
break;
}
}
if (!found) {
nonmember_list.push(users[id]);
} }
} }
member_list.sort(function(a,b) { nonmembers.sort(function(a,b) {
if (a.username < b.username) return -1; return a.username.localeCompare(b.username);
if (a.username > b.username) return 1;
return 0;
});
nonmember_list.sort(function(a,b) {
if (a.username < b.username) return -1;
if (a.username > b.username) return 1;
return 0;
}); });
var channel_name = ChannelStore.getCurrent() ? ChannelStore.getCurrent().display_name : ""; var channel_name = ChannelStore.getCurrent() ? ChannelStore.getCurrent().display_name : "";
return { return {
nonmember_list: nonmember_list, nonmembers: nonmembers,
member_list: member_list, memberIds: memberIds,
channel_name: channel_name channel_name: channel_name
}; };
} }
module.exports = React.createClass({ module.exports = React.createClass({
displayName: "ChannelInviteModal",
isShown: false,
getInitialState: function() {
return {};
},
componentDidMount: function() { componentDidMount: function() {
$(React.findDOMNode(this))
.on('hidden.bs.modal', this._onHide)
.on('show.bs.modal', this._onShow);
},
_onShow: function() {
ChannelStore.addExtraInfoChangeListener(this._onChange); ChannelStore.addExtraInfoChangeListener(this._onChange);
ChannelStore.addChangeListener(this._onChange); ChannelStore.addChangeListener(this._onChange);
this.isShown = true;
var self = this; this._onChange();
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
self.setState({ render_members: false });
});
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
self.setState({ render_members: true });
});
}, },
componentWillUnmount: function() {
_onHide: function() {
ChannelStore.removeExtraInfoChangeListener(this._onChange); ChannelStore.removeExtraInfoChangeListener(this._onChange);
ChannelStore.removeChangeListener(this._onChange); ChannelStore.removeChangeListener(this._onChange);
this.isShown = false;
}, },
_onChange: function() { _onChange: function() {
var new_state = getStateFromStores(); this.setState(getStateFromStores());
if (!utils.areStatesEqual(this.state, new_state)) {
this.setState(new_state);
}
}, },
handleInvite: function(user_id) { handleInvite: function(user_id) {
// Make sure the user isn't already a member of the channel // Make sure the user isn't already a member of the channel
var member_list = this.state.member_list; if (this.state.memberIds.indexOf(user_id) > -1) {
for (var i = 0; i < member_list; i++) {
if (member_list[i].id === user_id) {
return; return;
} }
}
var data = {}; var data = {};
data['user_id'] = user_id; data.user_id = user_id;
client.addChannelMember(ChannelStore.getCurrentId(), data, client.addChannelMember(ChannelStore.getCurrentId(), data,
function(data) { function() {
var nonmember_list = this.state.nonmember_list; var nonmembers = this.state.nonmembers;
var new_member; var memberIds = this.state.memberIds;
for (var i = 0; i < nonmember_list.length; i++) {
if (user_id === nonmember_list[i].id) { for (var i = 0; i < nonmembers.length; i++) {
nonmember_list[i].invited = true; if (user_id === nonmembers[i].id) {
new_member = nonmember_list[i]; nonmembers[i].invited = true;
memberIds.push(user_id);
break; break;
} }
} }
if (new_member) { this.setState({ invite_error: null, memberIds: memberIds, nonmembers: nonmembers });
member_list.push(new_member);
member_list.sort(function(a,b) {
if (a.username < b.username) return -1;
if (a.username > b.username) return 1;
return 0;
});
}
this.setState({ invite_error: null, member_list: member_list, nonmember_list: nonmember_list });
AsyncClient.getChannelExtraInfo(true); AsyncClient.getChannelExtraInfo(true);
}.bind(this), }.bind(this),
function(err) { function(err) {
this.setState({ invite_error: err.message }); this.setState({ invite_error: err.message });
}.bind(this) }.bind(this)
); );
}, },
getInitialState: function() {
return getStateFromStores(); shouldComponentUpdate: function(nextProps, nextState) {
return this.isShown && !utils.areStatesEqual(this.state, nextState);
}, },
render: function() { render: function() {
var invite_error = this.state.invite_error ? <label className='has-error control-label'>{this.state.invite_error}</label> : null; var invite_error = this.state.invite_error ? <label className='has-error control-label'>{this.state.invite_error}</label> : null;
@@ -125,22 +109,19 @@ module.exports = React.createClass({
} }
return ( return (
<div className="modal fade" ref="modal" id="channel_invite" role="dialog" aria-hidden="true"> <div className="modal fade" id="channel_invite" tabIndex="-1" role="dialog" aria-hidden="true">
<div className="modal-dialog"> <div className="modal-dialog" role="document">
<div className="modal-content"> <div className="modal-content">
<div className="modal-header"> <div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 className="modal-title">Add New Members to {this.state.channel_name}</h4> <h4 className="modal-title">Add New Members to {this.state.channel_name}</h4>
</div> </div>
<div className="modal-body"> <div className="modal-body">
{ invite_error } { invite_error }
{ this.state.render_members ?
<MemberList <MemberList
memberList={this.state.nonmember_list} memberList={this.state.nonmembers}
isAdmin={isAdmin} isAdmin={isAdmin}
handleInvite={this.handleInvite} handleInvite={this.handleInvite} />
/>
: "" }
</div> </div>
<div className="modal-footer"> <div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button> <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
@@ -151,7 +132,3 @@ module.exports = React.createClass({
); );
} }
}); });

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

@@ -5,12 +5,16 @@
to the server on page load. This is to prevent other React controls from spamming to the server on page load. This is to prevent other React controls from spamming
AsyncClient with requests. */ AsyncClient with requests. */
var BrowserStore = require('../stores/browser_store.jsx');
var AsyncClient = require('../utils/async_client.jsx'); var AsyncClient = require('../utils/async_client.jsx');
var SocketStore = require('../stores/socket_store.jsx'); var SocketStore = require('../stores/socket_store.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
module.exports = React.createClass({ module.exports = React.createClass({
componentDidMount: function() { componentDidMount: function() {
// Initalize stores
BrowserStore.initalize();
/* Start initial aysnc loads */ /* Start initial aysnc loads */
AsyncClient.getMe(); AsyncClient.getMe();
AsyncClient.getPosts(true); AsyncClient.getPosts(true);

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

@@ -3,6 +3,7 @@
var Client = require('../utils/client.jsx'); var Client = require('../utils/client.jsx');
var PostStore = require('../stores/post_store.jsx'); var PostStore = require('../stores/post_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var utils = require('../utils/utils.jsx'); var utils = require('../utils/utils.jsx');
var AsyncClient = require('../utils/async_client.jsx'); var AsyncClient = require('../utils/async_client.jsx');
var AppDispatcher = require('../dispatcher/app_dispatcher.jsx'); var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
@@ -54,9 +55,9 @@ module.exports = React.createClass({
var self = this; var self = this;
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
var newState = {}; var newState = {};
if(sessionStorage.getItem('edit_state_transfer')) { if(BrowserStore.getItem('edit_state_transfer')) {
newState = JSON.parse(sessionStorage.getItem('edit_state_transfer')); newState = JSON.parse(BrowserStore.getItem('edit_state_transfer'));
sessionStorage.removeItem('edit_state_transfer'); BrowserStore.removeItem('edit_state_transfer');
} else { } else {
var button = e.relatedTarget; var button = e.relatedTarget;
newState = { title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments') }; newState = { title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments') };

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

@@ -13,7 +13,7 @@ module.exports = React.createClass({
if (updatedPost.message.length === 0) { if (updatedPost.message.length === 0) {
var tempState = this.state; var tempState = this.state;
delete tempState.editText; delete tempState.editText;
sessionStorage.setItem('edit_state_transfer', JSON.stringify(tempState)); BrowserStore.setItem('edit_state_transfer', JSON.stringify(tempState));
$("#edit_post").modal('hide'); $("#edit_post").modal('hide');
$("#delete_post").modal('show'); $("#delete_post").modal('show');
return; return;

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

@@ -89,7 +89,12 @@ module.exports = React.createClass({
$(this.refs.modal.getDOMNode()).modal('hide'); $(this.refs.modal.getDOMNode()).modal('hide');
}.bind(this), }.bind(this),
function(err) { function(err) {
this.setState({ server_error: err }); if (err.message === "This person is already on your team") {
email_errors[err.detailed_error] = err.message;
this.setState({ email_errors: email_errors });
}
else
this.setState({ server_error: err.message});
}.bind(this) }.bind(this)
); );

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

@@ -7,6 +7,7 @@
var utils = require('../utils/utils.jsx'); var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx'); var client = require('../utils/client.jsx');
var UserStore = require('../stores/user_store.jsx'); var UserStore = require('../stores/user_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var FindTeamDomain = React.createClass({ var FindTeamDomain = React.createClass({
@@ -21,7 +22,7 @@ var FindTeamDomain = React.createClass({
return; return;
} }
if (!utils.isLocalStorageSupported()) { if (!BrowserStore.isLocalStorageSupported()) {
state.server_error = "This service requires local storage to be enabled. Please enable it or exit private browsing."; state.server_error = "This service requires local storage to be enabled. Please enable it or exit private browsing.";
this.setState(state); this.setState(state);
return; return;
@@ -114,7 +115,7 @@ module.exports = React.createClass({
return; return;
} }
if (!utils.isLocalStorageSupported()) { if (!BrowserStore.isLocalStorageSupported()) {
state.server_error = "This service requires local storage to be enabled. Please enable it or exit private browsing."; state.server_error = "This service requires local storage to be enabled. Please enable it or exit private browsing.";
this.setState(state); this.setState(state);
return; return;

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

@@ -5,13 +5,17 @@ var ChannelStore = require('../stores/channel_store.jsx');
var UserStore = require('../stores/user_store.jsx'); var UserStore = require('../stores/user_store.jsx');
module.exports = React.createClass({ module.exports = React.createClass({
handleInvite: function() { displayName: 'MemberListItem',
handleInvite: function(e) {
e.preventDefault();
this.props.handleInvite(this.props.member.id); this.props.handleInvite(this.props.member.id);
}, },
handleRemove: function() { handleRemove: function(e) {
e.preventDefault();
this.props.handleRemove(this.props.member.id); this.props.handleRemove(this.props.member.id);
}, },
handleMakeAdmin: function() { handleMakeAdmin: function(e) {
e.preventDefault();
this.props.handleMakeAdmin(this.props.member.id); this.props.handleMakeAdmin(this.props.member.id);
}, },
render: function() { render: function() {
@@ -20,12 +24,6 @@ module.exports = React.createClass({
var isAdmin = this.props.isAdmin; var isAdmin = this.props.isAdmin;
var isMemberAdmin = member.roles.indexOf("admin") > -1; var isMemberAdmin = member.roles.indexOf("admin") > -1;
if (member.roles === '') {
member.roles = 'Member';
} else {
member.roles = member.roles.charAt(0).toUpperCase() + member.roles.slice(1);
}
var invite; var invite;
if (member.invited && this.props.handleInvite) { if (member.invited && this.props.handleInvite) {
invite = <span className="member-role">Added</span>; invite = <span className="member-role">Added</span>;
@@ -36,30 +34,28 @@ module.exports = React.createClass({
invite = ( invite = (
<div className="dropdown member-drop"> <div className="dropdown member-drop">
<a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true"> <a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
<span>{member.roles} </span> <span className="text-capitalize">{member.roles || 'Member'} </span>
<span className="caret"></span> <span className="caret"></span>
</a> </a>
<ul className="dropdown-menu member-menu" role="menu" aria-labelledby="channel_header_dropdown"> <ul className="dropdown-menu member-menu" role="menu" aria-labelledby="channel_header_dropdown">
{ this.props.handleMakeAdmin ? { this.props.handleMakeAdmin ?
<li role="presentation"><a role="menuitem" onClick={self.handleMakeAdmin}>Make Admin</a></li> <li role="presentation"><a href="" role="menuitem" onClick={self.handleMakeAdmin}>Make Admin</a></li>
: "" } : null }
{ this.props.handleRemove ? { this.props.handleRemove ?
<li role="presentation"><a role="menuitem" onClick={self.handleRemove}>Remove Member</a></li> <li role="presentation"><a href="" role="menuitem" onClick={self.handleRemove}>Remove Member</a></li>
: "" } : null }
</ul> </ul>
</div> </div>
); );
} else { } else {
invite = <div className="member-drop"><span>{member.roles} </span><span className="caret invisible"></span></div>; invite = <div className="member-role text-capitalize" style={{marginRight: 15}}>{member.roles || 'Member'}</div>;
} }
var email = member.email.length > 0 ? member.email : "";
return ( return (
<div className="row member-div"> <div className="row member-div">
<img className="post-profile-img pull-left" src={"/api/v1/users/" + member.id + "/image"} height="36" width="36" /> <img className="post-profile-img pull-left" src={"/api/v1/users/" + member.id + "/image"} height="36" width="36" />
<span className="member-name">{member.username}</span> <span className="member-name">{member.username}</span>
<span className="member-email">{email}</span> <span className="member-email">{member.email}</span>
{ invite } { invite }
</div> </div>
); );

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

@@ -5,11 +5,12 @@
var utils = require('../utils/utils.jsx'); var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx'); var client = require('../utils/client.jsx');
var UserStore = require('../stores/user_store.jsx'); var UserStore = require('../stores/user_store.jsx');
var constants = require('../utils/constants.jsx') var BrowserStore = require('../stores/browser_store.jsx');
var constants = require('../utils/constants.jsx');
WelcomePage = React.createClass({ WelcomePage = React.createClass({
submitNext: function (e) { submitNext: function (e) {
if (!utils.isLocalStorageSupported()) { if (!BrowserStore.isLocalStorageSupported()) {
this.setState({ storage_error: "This service requires local storage to be enabled. Please enable it or exit private browsing."} ); this.setState({ storage_error: "This service requires local storage to be enabled. Please enable it or exit private browsing."} );
return; return;
} }
@@ -32,7 +33,7 @@ WelcomePage = React.createClass({
this.setState(state); this.setState(state);
return; return;
} }
else if (!utils.isLocalStorageSupported()) { else if (!BrowserStore.isLocalStorageSupported()) {
state.email_error = "This service requires local storage to be enabled. Please enable it or exit private browsing."; state.email_error = "This service requires local storage to be enabled. Please enable it or exit private browsing.";
this.setState(state); this.setState(state);
return; return;
@@ -595,7 +596,7 @@ PasswordPage = React.createClass({
module.exports = React.createClass({ module.exports = React.createClass({
updateParent: function(state, skipSet) { updateParent: function(state, skipSet) {
localStorage.setItem(this.props.hash, JSON.stringify(state)); BrowserStore.setGlobalItem(this.props.hash, JSON.stringify(state));
if (!skipSet) { if (!skipSet) {
this.setState(state); this.setState(state);
@@ -604,7 +605,7 @@ module.exports = React.createClass({
getInitialState: function() { getInitialState: function() {
var props = null; var props = null;
try { try {
props = JSON.parse(localStorage.getItem(this.props.hash)); props = JSON.parse(BrowserStore.getGlobalItem(this.props.hash));
} }
catch(parse_error) { catch(parse_error) {
} }

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

@@ -5,7 +5,7 @@
var utils = require('../utils/utils.jsx'); var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx'); var client = require('../utils/client.jsx');
var UserStore = require('../stores/user_store.jsx'); var UserStore = require('../stores/user_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
module.exports = React.createClass({ module.exports = React.createClass({
handleSubmit: function(e) { handleSubmit: function(e) {
@@ -53,7 +53,7 @@ module.exports = React.createClass({
UserStore.setLastEmail(this.state.user.email); UserStore.setLastEmail(this.state.user.email);
UserStore.setCurrentUser(data); UserStore.setCurrentUser(data);
if (this.props.hash > 0) if (this.props.hash > 0)
localStorage.setItem(this.props.hash, JSON.stringify({wizard: "finished"})); BrowserStore.setGlobalItem(this.props.hash, JSON.stringify({wizard: "finished"}));
window.location.href = '/channels/town-square'; window.location.href = '/channels/town-square';
}.bind(this), }.bind(this),
function(err) { function(err) {
@@ -75,7 +75,7 @@ module.exports = React.createClass({
getInitialState: function() { getInitialState: function() {
var props = null; var props = null;
try { try {
props = JSON.parse(localStorage.getItem(this.props.hash)); props = JSON.parse(BrowserStore.getGlobalItem(this.props.hash));
} }
catch(parse_error) { catch(parse_error) {
} }

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

@@ -8,7 +8,6 @@
"object-assign": "^1.0.0", "object-assign": "^1.0.0",
"react": "^0.12.0", "react": "^0.12.0",
"autolinker": "^0.15.2", "autolinker": "^0.15.2",
"linkify-it": "^1.1.0",
"react-zeroclipboard-mixin": "^0.1.0" "react-zeroclipboard-mixin": "^0.1.0"
}, },
"devDependencies": { "devDependencies": {

77
web/react/stores/browser_store.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,77 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var UserStore = require('../stores/user_store.jsx');
// Also change model/utils.go ETAG_ROOT_VERSION
var BROWSER_STORE_VERSION = '.1';
module.exports.initalize = function() {
var currentVersion = localStorage.getItem("local_storage_version");
if (currentVersion !== BROWSER_STORE_VERSION) {
localStorage.clear();
sessionStorage.clear();
localStorage.setItem("local_storage_version", BROWSER_STORE_VERSION);
}
}
module.exports.setItem = function(name, value) {
var user_id = UserStore.getCurrentId();
localStorage.setItem(user_id + "_" + name, value);
};
module.exports.getItem = function(name) {
var user_id = UserStore.getCurrentId();
return localStorage.getItem(user_id + "_" + name);
};
module.exports.removeItem = function(name) {
var user_id = UserStore.getCurrentId();
localStorage.removeItem(user_id + "_" + name);
};
module.exports.setGlobalItem = function(name, value) {
localStorage.setItem(name, value);
};
module.exports.getGlobalItem = function(name) {
return localStorage.getItem(name);
};
module.exports.removeGlobalItem = function(name) {
localStorage.removeItem(name);
};
module.exports.clear = function() {
localStorage.clear();
sessionStorage.clear();
};
// Preforms the given action on each item that has the given prefix
// Signiture for action is action(key, value)
module.exports.actionOnItemsWithPrefix = function (prefix, action) {
var user_id = UserStore.getCurrentId();
var id_len = user_id.length;
var prefix_len = prefix.length;
for (key in localStorage) {
if (key.substring(id_len, id_len + prefix_len) === prefix) {
var userkey = key.substring(id_len);
action(userkey, BrowserStore.getItem(key));
}
}
};
module.exports.isLocalStorageSupported = function() {
try {
sessionStorage.setItem("testSession", '1');
sessionStorage.removeItem("testSession");
localStorage.setItem("testLocal", '1');
localStorage.removeItem("testLocal", '1');
return true;
}
catch (e) {
return false;
}
}

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

@@ -8,6 +8,8 @@ var assign = require('object-assign');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var BrowserStore = require('../stores/browser_store.jsx');
var CHANGE_EVENT = 'change'; var CHANGE_EVENT = 'change';
var MORE_CHANGE_EVENT = 'change'; var MORE_CHANGE_EVENT = 'change';
@@ -87,18 +89,18 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
}, },
setCurrentId: function(id) { setCurrentId: function(id) {
if (id == null) if (id == null)
sessionStorage.removeItem("current_channel_id"); BrowserStore.removeItem("current_channel_id");
else else
sessionStorage.setItem("current_channel_id", id); BrowserStore.setItem("current_channel_id", id);
}, },
setLastVisitedName: function(name) { setLastVisitedName: function(name) {
if (name == null) if (name == null)
localStorage.removeItem("last_visited_name"); BrowserStore.removeItem("last_visited_name");
else else
localStorage.setItem("last_visited_name", name); BrowserStore.setItem("last_visited_name", name);
}, },
getLastVisitedName: function() { getLastVisitedName: function() {
return localStorage.getItem("last_visited_name"); return BrowserStore.getItem("last_visited_name");
}, },
resetCounts: function(id) { resetCounts: function(id) {
var cm = this._getChannelMembers(); var cm = this._getChannelMembers();
@@ -115,7 +117,7 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
this._storeChannelMembers(cm); this._storeChannelMembers(cm);
}, },
getCurrentId: function() { getCurrentId: function() {
return sessionStorage.getItem("current_channel_id"); return BrowserStore.getItem("current_channel_id");
}, },
getCurrent: function() { getCurrent: function() {
var currentId = ChannelStore.getCurrentId(); var currentId = ChannelStore.getCurrentId();
@@ -163,55 +165,71 @@ var ChannelStore = assign({}, EventEmitter.prototype, {
return extra; return extra;
}, },
_storeChannels: function(channels) { _storeChannels: function(channels) {
sessionStorage.setItem("channels", JSON.stringify(channels)); BrowserStore.setItem("channels", JSON.stringify(channels));
}, },
_getChannels: function() { _getChannels: function() {
var channels = []; var channels = [];
try { try {
channels = JSON.parse(sessionStorage.channels); channels = JSON.parse(BrowserStore.getItem("channels"));
} }
catch (err) { catch (err) {
} }
if (channels == null) {
channels = [];
}
return channels; return channels;
}, },
_storeChannelMembers: function(channelMembers) { _storeChannelMembers: function(channelMembers) {
sessionStorage.setItem("channel_members", JSON.stringify(channelMembers)); BrowserStore.setItem("channel_members", JSON.stringify(channelMembers));
}, },
_getChannelMembers: function() { _getChannelMembers: function() {
var members = {}; var members = {};
try { try {
members = JSON.parse(sessionStorage.channel_members); members = JSON.parse(BrowserStore.getItem("channel_members"));
} }
catch (err) { catch (err) {
} }
if (members == null) {
members = {};
}
return members; return members;
}, },
_storeMoreChannels: function(channels) { _storeMoreChannels: function(channels) {
sessionStorage.setItem("more_channels", JSON.stringify(channels)); BrowserStore.setItem("more_channels", JSON.stringify(channels));
}, },
_getMoreChannels: function() { _getMoreChannels: function() {
var channels; var channels;
try { try {
channels = JSON.parse(sessionStorage.more_channels); channels = JSON.parse(BrowserStore.getItem("more_channels"));
} }
catch (err) { catch (err) {
} }
if (channels == null) {
channels = [];
}
return channels; return channels;
}, },
_storeExtraInfos: function(extraInfos) { _storeExtraInfos: function(extraInfos) {
sessionStorage.setItem("extra_infos", JSON.stringify(extraInfos)); BrowserStore.setItem("extra_infos", JSON.stringify(extraInfos));
}, },
_getExtraInfos: function() { _getExtraInfos: function() {
var members = {}; var members = {};
try { try {
members = JSON.parse(sessionStorage.extra_infos); members = JSON.parse(BrowserStore.getItem("extra_infos"));
} }
catch (err) { catch (err) {
} }
if (members == null) {
members = {};
}
return members; return members;
} }
}); });

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

@@ -8,6 +8,8 @@ var assign = require('object-assign');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var BrowserStore = require('../stores/browser_store.jsx');
var CHANGE_EVENT = 'change'; var CHANGE_EVENT = 'change';
var ErrorStore = assign({}, EventEmitter.prototype, { var ErrorStore = assign({}, EventEmitter.prototype, {
@@ -24,12 +26,12 @@ var ErrorStore = assign({}, EventEmitter.prototype, {
this.removeListener(CHANGE_EVENT, callback); this.removeListener(CHANGE_EVENT, callback);
}, },
handledError: function() { handledError: function() {
sessionStorage.removeItem("last_error"); BrowserStore.removeItem("last_error");
}, },
getLastError: function() { getLastError: function() {
var error = null; var error = null;
try { try {
error = JSON.parse(sessionStorage.last_error); error = JSON.parse(BrowserStore.last_error);
} }
catch (err) { catch (err) {
} }
@@ -38,7 +40,7 @@ var ErrorStore = assign({}, EventEmitter.prototype, {
}, },
_storeLastError: function(error) { _storeLastError: function(error) {
sessionStorage.setItem("last_error", JSON.stringify(error)); BrowserStore.setItem("last_error", JSON.stringify(error));
}, },
}); });

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

@@ -7,6 +7,7 @@ var assign = require('object-assign');
var ChannelStore = require('../stores/channel_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx');
var UserStore = require('../stores/user_store.jsx'); var UserStore = require('../stores/user_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
@@ -105,12 +106,12 @@ var PostStore = assign({}, EventEmitter.prototype, {
this.emitChange(); this.emitChange();
}, },
_storePosts: function(channelId, posts) { _storePosts: function(channelId, posts) {
sessionStorage.setItem("posts_" + channelId, JSON.stringify(posts)); BrowserStore.setItem("posts_" + channelId, JSON.stringify(posts));
}, },
getPosts: function(channelId) { getPosts: function(channelId) {
var posts = null; var posts = null;
try { try {
posts = JSON.parse(sessionStorage.getItem("posts_" + channelId)); posts = JSON.parse(BrowserStore.getItem("posts_" + channelId));
} }
catch (err) { catch (err) {
} }
@@ -118,14 +119,14 @@ var PostStore = assign({}, EventEmitter.prototype, {
return posts; return posts;
}, },
storeSearchResults: function(results, is_mention_search) { storeSearchResults: function(results, is_mention_search) {
sessionStorage.setItem("search_results", JSON.stringify(results)); BrowserStore.setItem("search_results", JSON.stringify(results));
is_mention_search = is_mention_search ? true : false; // force to bool is_mention_search = is_mention_search ? true : false; // force to bool
sessionStorage.setItem("is_mention_search", JSON.stringify(is_mention_search)); BrowserStore.setItem("is_mention_search", JSON.stringify(is_mention_search));
}, },
getSearchResults: function() { getSearchResults: function() {
var results = null; var results = null;
try { try {
results = JSON.parse(sessionStorage.getItem("search_results")); results = JSON.parse(BrowserStore.getItem("search_results"));
} }
catch (err) { catch (err) {
} }
@@ -135,7 +136,7 @@ var PostStore = assign({}, EventEmitter.prototype, {
getIsMentionSearch: function() { getIsMentionSearch: function() {
var result = false; var result = false;
try { try {
result = JSON.parse(sessionStorage.getItem("is_mention_search")); result = JSON.parse(BrowserStore.getItem("is_mention_search"));
} }
catch (err) { catch (err) {
} }
@@ -143,12 +144,12 @@ var PostStore = assign({}, EventEmitter.prototype, {
return result; return result;
}, },
storeSelectedPost: function(post_list) { storeSelectedPost: function(post_list) {
sessionStorage.setItem("select_post", JSON.stringify(post_list)); BrowserStore.setItem("select_post", JSON.stringify(post_list));
}, },
getSelectedPost: function() { getSelectedPost: function() {
var post_list = null; var post_list = null;
try { try {
post_list = JSON.parse(sessionStorage.getItem("select_post")); post_list = JSON.parse(BrowserStore.getItem("select_post"));
} }
catch (err) { catch (err) {
} }
@@ -156,37 +157,35 @@ var PostStore = assign({}, EventEmitter.prototype, {
return post_list; return post_list;
}, },
storeSearchTerm: function(term) { storeSearchTerm: function(term) {
sessionStorage.setItem("search_term", term); BrowserStore.setItem("search_term", term);
}, },
getSearchTerm: function() { getSearchTerm: function() {
return sessionStorage.getItem("search_term"); return BrowserStore.getItem("search_term");
}, },
storeCurrentDraft: function(draft) { storeCurrentDraft: function(draft) {
var channel_id = ChannelStore.getCurrentId(); var channel_id = ChannelStore.getCurrentId();
var user_id = UserStore.getCurrentId(); var user_id = UserStore.getCurrentId();
localStorage.setItem("draft_" + channel_id + "_" + user_id, JSON.stringify(draft)); BrowserStore.setItem("draft_" + channel_id + "_" + user_id, JSON.stringify(draft));
}, },
getCurrentDraft: function() { getCurrentDraft: function() {
var channel_id = ChannelStore.getCurrentId(); var channel_id = ChannelStore.getCurrentId();
var user_id = UserStore.getCurrentId(); var user_id = UserStore.getCurrentId();
return JSON.parse(localStorage.getItem("draft_" + channel_id + "_" + user_id)); return JSON.parse(BrowserStore.getItem("draft_" + channel_id + "_" + user_id));
}, },
storeDraft: function(channel_id, user_id, draft) { storeDraft: function(channel_id, user_id, draft) {
localStorage.setItem("draft_" + channel_id + "_" + user_id, JSON.stringify(draft)); BrowserStore.setItem("draft_" + channel_id + "_" + user_id, JSON.stringify(draft));
}, },
getDraft: function(channel_id, user_id) { getDraft: function(channel_id, user_id) {
return JSON.parse(localStorage.getItem("draft_" + channel_id + "_" + user_id)); return JSON.parse(BrowserStore.getItem("draft_" + channel_id + "_" + user_id));
}, },
clearDraftUploads: function() { clearDraftUploads: function() {
for (key in localStorage) { BrowserStore.actionOnItemsWithPrefix("draft_", function (key, value) {
if (key.substring(0,6) === "draft_") { var d = JSON.parse(value);
var d = JSON.parse(localStorage.getItem(key));
if (d) { if (d) {
d['uploadsInProgress'] = 0; d['uploadsInProgress'] = 0;
localStorage.setItem(key, JSON.stringify(d)); BrowserStore.setItem(key, JSON.stringify(d));
}
}
} }
});
} }
}); });

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

@@ -10,6 +10,8 @@ var client = require('../utils/client.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var BrowserStore = require('../stores/browser_store.jsx');
var CHANGE_EVENT = 'change'; var CHANGE_EVENT = 'change';
var conn; var conn;

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

@@ -7,7 +7,7 @@ var assign = require('object-assign');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var BrowserStore = require('../stores/browser_store.jsx');
var CHANGE_EVENT = 'change'; var CHANGE_EVENT = 'change';
@@ -42,12 +42,12 @@ var TeamStore = assign({}, EventEmitter.prototype, {
}, },
setCurrentId: function(id) { setCurrentId: function(id) {
if (id == null) if (id == null)
sessionStorage.removeItem("current_team_id"); BrowserStore.removeItem("current_team_id");
else else
sessionStorage.setItem("current_team_id", id); BrowserStore.setItem("current_team_id", id);
}, },
getCurrentId: function() { getCurrentId: function() {
return sessionStorage.getItem("current_team_id"); return BrowserStore.getItem("current_team_id");
}, },
getCurrent: function() { getCurrent: function() {
var currentId = TeamStore.getCurrentId(); var currentId = TeamStore.getCurrentId();
@@ -63,17 +63,21 @@ var TeamStore = assign({}, EventEmitter.prototype, {
this._storeTeams(teams); this._storeTeams(teams);
}, },
_storeTeams: function(teams) { _storeTeams: function(teams) {
sessionStorage.setItem("user_teams", JSON.stringify(teams)); BrowserStore.setItem("user_teams", JSON.stringify(teams));
}, },
_getTeams: function() { _getTeams: function() {
var teams = {}; var teams = {};
try { try {
teams = JSON.parse(sessionStorage.user_teams); teams = JSON.parse(BrowserStore.getItem("user_teams"));
} }
catch (err) { catch (err) {
} }
if (teams == null) {
teams = {};
}
return teams; return teams;
} }
}); });

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

@@ -8,6 +8,7 @@ var client = require('../utils/client.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var BrowserStore = require('../stores/browser_store.jsx');
var CHANGE_EVENT = 'change'; var CHANGE_EVENT = 'change';
var CHANGE_EVENT_SESSIONS = 'change_sessions'; var CHANGE_EVENT_SESSIONS = 'change_sessions';
@@ -64,12 +65,12 @@ var UserStore = assign({}, EventEmitter.prototype, {
}, },
setCurrentId: function(id) { setCurrentId: function(id) {
if (id == null) if (id == null)
sessionStorage.removeItem("current_user_id"); BrowserStore.removeGlobalItem("current_user_id");
else else
sessionStorage.setItem("current_user_id", id); BrowserStore.setGlobalItem("current_user_id", id);
}, },
getCurrentId: function(skipFetch) { getCurrentId: function(skipFetch) {
var current_id = sessionStorage.current_user_id; var current_id = BrowserStore.getGlobalItem("current_user_id");
// this is a speical case to force fetch the // this is a speical case to force fetch the
// current user if it's missing // current user if it's missing
@@ -96,16 +97,24 @@ var UserStore = assign({}, EventEmitter.prototype, {
this.setCurrentId(user.id); this.setCurrentId(user.id);
}, },
getLastDomain: function() { getLastDomain: function() {
return localStorage.last_domain; var last_domain = BrowserStore.getItem("last_domain");
if (last_domain == null) {
last_domain = "";
}
return last_domain;
}, },
setLastDomain: function(domain) { setLastDomain: function(domain) {
localStorage.setItem("last_domain", domain); BrowserStore.setItem("last_domain", domain);
}, },
getLastEmail: function() { getLastEmail: function() {
return localStorage.last_email; var last_email = BrowserStore.getItem("last_email");
if (last_email == null) {
last_email = "";
}
return last_email;
}, },
setLastEmail: function(email) { setLastEmail: function(email) {
localStorage.setItem("last_email", email); BrowserStore.setItem("last_email", email);
}, },
removeCurrentUser: function() { removeCurrentUser: function() {
this.setCurrentId(null); this.setCurrentId(null);
@@ -144,89 +153,89 @@ var UserStore = assign({}, EventEmitter.prototype, {
this._storeProfiles(ps); this._storeProfiles(ps);
}, },
_storeProfiles: function(profiles) { _storeProfiles: function(profiles) {
sessionStorage.setItem("profiles", JSON.stringify(profiles)); BrowserStore.setGlobalItem("profiles", JSON.stringify(profiles));
var profileUsernameMap = {}; var profileUsernameMap = {};
for (var id in profiles) { for (var id in profiles) {
profileUsernameMap[profiles[id].username] = profiles[id]; profileUsernameMap[profiles[id].username] = profiles[id];
} }
sessionStorage.setItem("profileUsernameMap", JSON.stringify(profileUsernameMap)); BrowserStore.setGlobalItem("profileUsernameMap", JSON.stringify(profileUsernameMap));
}, },
_getProfiles: function() { _getProfiles: function() {
var profiles = {}; var profiles = {};
try { try {
profiles = JSON.parse(sessionStorage.getItem("profiles")); profiles = JSON.parse(BrowserStore.getGlobalItem("profiles"));
}
catch (err) {
}
if (profiles == null) { if (profiles == null) {
profiles = {}; profiles = {};
} }
}
catch (err) {
}
return profiles; return profiles;
}, },
_getProfilesUsernameMap: function() { _getProfilesUsernameMap: function() {
var profileUsernameMap = {}; var profileUsernameMap = {};
try { try {
profileUsernameMap = JSON.parse(sessionStorage.getItem("profileUsernameMap")); profileUsernameMap = JSON.parse(BrowserStore.getGlobalItem("profileUsernameMap"));
}
catch (err) {
}
if (profileUsernameMap == null) { if (profileUsernameMap == null) {
profileUsernameMap = {}; profileUsernameMap = {};
} }
}
catch (err) {
}
return profileUsernameMap; return profileUsernameMap;
}, },
setSessions: function(sessions) { setSessions: function(sessions) {
sessionStorage.setItem("sessions", JSON.stringify(sessions)); BrowserStore.setItem("sessions", JSON.stringify(sessions));
}, },
getSessions: function() { getSessions: function() {
var sessions = []; var sessions = [];
try { try {
sessions = JSON.parse(sessionStorage.getItem("sessions")); sessions = JSON.parse(BrowserStore.getItem("sessions"));
if (sessions == null) {
sessions = [];
}
} }
catch (err) { catch (err) {
} }
if (sessions == null) {
sessions = [];
}
return sessions; return sessions;
}, },
setAudits: function(audits) { setAudits: function(audits) {
sessionStorage.setItem("audits", JSON.stringify(audits)); BrowserStore.setItem("audits", JSON.stringify(audits));
}, },
getAudits: function() { getAudits: function() {
var audits = []; var audits = [];
try { try {
audits = JSON.parse(sessionStorage.getItem("audits")); audits = JSON.parse(BrowserStore.getItem("audits"));
}
catch (err) {
}
if (audits == null) { if (audits == null) {
audits = []; audits = [];
} }
}
catch (err) {
}
return audits; return audits;
}, },
setTeams: function(teams) { setTeams: function(teams) {
sessionStorage.setItem("teams", JSON.stringify(teams)); BrowserStore.setItem("teams", JSON.stringify(teams));
}, },
getTeams: function() { getTeams: function() {
var teams = []; var teams = [];
try { try {
teams = JSON.parse(sessionStorage.getItem("teams")); teams = JSON.parse(BrowserStore.getItem("teams"));
}
catch (err) {
}
if (teams == null) { if (teams == null) {
teams = []; teams = [];
} }
}
catch (err) {
}
return teams; return teams;
}, },
@@ -249,17 +258,21 @@ var UserStore = assign({}, EventEmitter.prototype, {
} }
}, },
getLastVersion: function() { getLastVersion: function() {
return sessionStorage.last_version; var last_version = BrowserStore.getItem("last_version");
if (last_version == null) {
last_version = "";
}
return last_version;
}, },
setLastVersion: function(version) { setLastVersion: function(version) {
sessionStorage.setItem("last_version", version); BrowserStore.setItem("last_version", version);
}, },
setStatuses: function(statuses) { setStatuses: function(statuses) {
this._setStatuses(statuses); this._setStatuses(statuses);
this.emitStatusesChange(); this.emitStatusesChange();
}, },
_setStatuses: function(statuses) { _setStatuses: function(statuses) {
sessionStorage.setItem("statuses", JSON.stringify(statuses)); BrowserStore.setItem("statuses", JSON.stringify(statuses));
}, },
setStatus: function(user_id, status) { setStatus: function(user_id, status) {
var statuses = this.getStatuses(); var statuses = this.getStatuses();
@@ -270,14 +283,14 @@ var UserStore = assign({}, EventEmitter.prototype, {
getStatuses: function() { getStatuses: function() {
var statuses = {}; var statuses = {};
try { try {
statuses = JSON.parse(sessionStorage.getItem("statuses")); statuses = JSON.parse(BrowserStore.getItem("statuses"));
}
catch (err) {
}
if (statuses == null) { if (statuses == null) {
statuses = {}; statuses = {};
} }
}
catch (err) {
}
return statuses; return statuses;
}, },

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

@@ -1,6 +1,7 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
var BrowserStore = require('../stores/browser_store.jsx');
module.exports.track = function(category, action, label, prop, val) { module.exports.track = function(category, action, label, prop, val) {
global.window.snowplow('trackStructEvent', category, action, label, prop, val); global.window.snowplow('trackStructEvent', category, action, label, prop, val);
@@ -204,7 +205,7 @@ module.exports.resetPassword = function(data, success, error) {
module.exports.logout = function() { module.exports.logout = function() {
module.exports.track('api', 'api_users_logout'); module.exports.track('api', 'api_users_logout');
sessionStorage.clear(); BrowserStore.clear();
window.location.href = "/logout"; window.location.href = "/logout";
}; };

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

@@ -8,7 +8,7 @@ var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes; var ActionTypes = Constants.ActionTypes;
var AsyncClient = require('./async_client.jsx'); var AsyncClient = require('./async_client.jsx');
var client = require('./client.jsx'); var client = require('./client.jsx');
var LinkifyIt = require('linkify-it'); var Autolinker = require('autolinker');
module.exports.isEmail = function(email) { module.exports.isEmail = function(email) {
var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
@@ -97,20 +97,6 @@ module.exports.getCookie = function(name) {
if (parts.length == 2) return parts.pop().split(";").shift(); if (parts.length == 2) return parts.pop().split(";").shift();
} }
module.exports.isLocalStorageSupported = function() {
try {
sessionStorage.setItem("testSession", '1');
sessionStorage.removeItem("testSession");
localStorage.setItem("testLocal", '1');
localStorage.removeItem("testLocal", '1');
return true;
}
catch (e) {
return false;
}
}
module.exports.notifyMe = function(title, body, channel) { module.exports.notifyMe = function(title, body, channel) {
if ("Notification" in window && Notification.permission !== 'denied') { if ("Notification" in window && Notification.permission !== 'denied') {
@@ -211,16 +197,31 @@ module.exports.getTimestamp = function() {
return Date.now(); return Date.now();
} }
var testUrlMatch = function(text) {
var urlMatcher = new Autolinker.matchParser.MatchParser;
var result = [];
var replaceFn = function(match) {
var linkData = {};
var matchText = match.getMatchedText();
linkData.text = matchText;
linkData.link = matchText.trim().indexOf("http") !== 0 ? "http://" + matchText : matchText;
result.push(linkData);
}
urlMatcher.replace(text,replaceFn,this);
return result;
}
module.exports.extractLinks = function(text) { module.exports.extractLinks = function(text) {
var repRegex = new RegExp("<br>", "g"); var repRegex = new RegExp("<br>", "g");
var linkMatcher = new LinkifyIt(); var matches = testUrlMatch(text.replace(repRegex, "\n"));
var matches = linkMatcher.match(text.replace(repRegex, "\n"));
if (!matches) return { "links": null, "text": text }; if (!matches.length) return { "links": null, "text": text };
var links = [] var links = [];
for (var i = 0; i < matches.length; i++) { for (var i = 0; i < matches.length; i++) {
links.push(matches[i].url) links.push(matches[i].link);
} }
return { "links": links, "text": text }; return { "links": links, "text": text };
@@ -402,7 +403,6 @@ module.exports.textToJsx = function(text, options) {
var implicitKeywords = UserStore.getCurrentMentionKeys(); var implicitKeywords = UserStore.getCurrentMentionKeys();
var lines = text.split("\n"); var lines = text.split("\n");
var urlMatcher = new LinkifyIt();
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
var line = lines[i]; var line = lines[i];
var words = line.split(" "); var words = line.split(" ");
@@ -434,14 +434,14 @@ module.exports.textToJsx = function(text, options) {
} }
inner.push(<span key={name+i+z+"_span"}>{prefix}<a className={mClass + highlightSearchClass + " mention-link"} key={name+i+z+"_link"} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(name)}>@{name}</a>{suffix} </span>); inner.push(<span key={name+i+z+"_span"}>{prefix}<a className={mClass + highlightSearchClass + " mention-link"} key={name+i+z+"_link"} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(name)}>@{name}</a>{suffix} </span>);
} else if (urlMatcher.test(word)) { } else if (testUrlMatch(word).length) {
var match = urlMatcher.match(word)[0]; var match = testUrlMatch(word)[0];
var link = match.url; var link = match.link;
var prefix = word.substring(0,word.indexOf(match.raw)) var prefix = word.substring(0,word.indexOf(match.text));
var suffix = word.substring(word.indexOf(match.raw)+match.raw.length); var suffix = word.substring(word.indexOf(match.text)+match.text.length);
inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_link"} className={"theme" + highlightSearchClass} target="_blank" href={link}>{match.raw}</a>{suffix} </span>); inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_link"} className={"theme" + highlightSearchClass} target="_blank" href={link}>{match.text}</a>{suffix} </span>);
} else if (trimWord.match(hashRegex)) { } else if (trimWord.match(hashRegex)) {
var suffix = word.match(puncEndRegex); var suffix = word.match(puncEndRegex);