Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions client/ChatterApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ import getChatHTML from "./template-helpers/getChatHTML.jsx";
import router from "./template-helpers/router.jsx";
import Widget from "./components/Widget.jsx";

const latestRooms = function (limit, withIds, archived) {
import {
CHATTER_CACHE_LIMIT,
CHATTER_EXPIRE_IN
} from "./global-variables.js";

const latestRooms = function (limit, withIds) {
return {
find: {"_id": {$in: withIds}, "archived": archived},
find: {"_id": {$in: withIds}},
options: {sort: {lastActive: -1}, limit: limit}
};
};

const chatterSubs = new SubsManager();

const chatterSubs = new SubsManager({
cacheLimit: CHATTER_CACHE_LIMIT,
expireIn: CHATTER_EXPIRE_IN
});

const ChatterApp = React.createClass({
mixins: [ReactMeteorData],
Expand Down Expand Up @@ -46,10 +55,15 @@ const ChatterApp = React.createClass({
const {activeRoomLimit, archivedRoomLimit} = this.state;

if (userId) {
const userRooms = Chatter.UserRoom.find({userId}).fetch();
const roomIds = _.pluck(userRooms, "roomId");
const activeRoomQuery = latestRooms(activeRoomLimit, roomIds, false);
const archivedRoomQuery = latestRooms(archivedRoomLimit, roomIds, true);
const archivedUserRooms = Chatter.UserRoom.find({userId, archived: true}).fetch();
const unarchivedUserRooms = Chatter.UserRoom.find({userId, archived: false}).fetch();

const archivedRoomIds = _.pluck(archivedUserRooms, "roomId");
const unarchivedRoomIds = _.pluck(unarchivedUserRooms, "roomId");

const activeRoomQuery = latestRooms(activeRoomLimit, unarchivedRoomIds);
const archivedRoomQuery = latestRooms(archivedRoomLimit, archivedRoomIds);

activeRooms = Chatter.Room.find(activeRoomQuery.find, activeRoomQuery.options).fetch();
archivedRooms = Chatter.Room.find(archivedRoomQuery.find, archivedRoomQuery.options).fetch();
}
Expand Down
177 changes: 100 additions & 77 deletions client/components/MainSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,113 +2,136 @@ import React from 'react';
import Loader from "../components/Loader.jsx"

const MainSettings = React.createClass({
mixins: [ReactMeteorData],

getInitialState: function() {
return {
roomUsers: [],
archived: this.props.room.archived
roomUsers: []
};
},

getMeteorData () {
const userId = Meteor.userId();
const userRoomsHandle = Meteor.subscribe("chatterUserRooms");
const subsReady = userRoomsHandle.ready();
let room = this.props.room;
let user = null;

if (subsReady) {
const ur = Chatter.UserRoom.findOne({roomId: this.props.room._id, userId});
user = Meteor.user();
room.archived = ur.archived;
}

return {
subsReady,
room,
user
}
},

componentDidMount() {
$(".ui.toggle.checkbox").checkbox();
if (this.state.archived) {
$(".ui.toggle.checkbox").checkbox('check');
}
Meteor.call("room.users", this.props.room._id, (error, result) => {
this.setState({roomUsers: result});
});
},

toggleArchivedState() {
const params = {
archived: !this.state.archived,
roomId: this.props.room._id
archived: !this.data.room.archived,
roomId: this.props.room._id,
userId: Meteor.userId()
};

Meteor.call("room.archive", params);
this.setState({archived: !this.state.archived});
},

render() {
const user = Meteor.user();

const addUsersHTML = (
<div className="item addUserItem" onClick={ () => this.props.setView("addUsers")}>
<i className="add user icon"></i>
<div className="content">
<a className="header">
Add or remove users...
</a>
</div>
</div>
);

const roomUsers = this.state.roomUsers;
const roomUsersHTML = roomUsers.map(function(user) {
const statusClass = user.profile.online ? "user-status online" : "user-status offline";
return (
<div className="item room-user" key={user._id}>
<div className={statusClass}></div>
<img
className="ui avatar image"
src={user.profile.chatterAvatar}
/>
if (this.data.subsReady) {
const user = this.data.user;
$(".ui.toggle.checkbox").checkbox();
if (this.data.room.archived) {
$(".ui.toggle.checkbox").checkbox('check');
}
const addUsersHTML = (
<div className="item addUserItem" onClick={ () => this.props.setView("addUsers")}>
<i className="add user icon"></i>
<div className="content">
<a className="header nickname">
{user.profile.chatterNickname}
<a className="header">
Add or remove users...
</a>
<div className="description last-active">
Last logged in just now.
</div>
</div>
</div>
);
});

const roomUsers = this.state.roomUsers;
const roomUsersHTML = roomUsers.map(function(user) {
const statusClass = user.profile.online ? "user-status online" : "user-status offline";
return (
<div className="item room-user" key={user._id}>
<div className={statusClass}></div>
<img
className="ui avatar image"
src={user.profile.chatterAvatar}
/>
<div className="content">
<a className="header nickname">
{user.profile.chatterNickname}
</a>
<div className="description last-active">
Last logged in just now.
</div>
</div>
</div>
);
});

return (
<div className="padded settings scrollable">
<div className="ui header">
Channel description
</div>
<p className="room-description">
{this.props.room.description}
</p>
<p className="gray-text">
This channel was created by {this.props.room.createdBy} on the {this.props.room.createdAt.toISOString()}.
</p>
<div className="ui toggle checkbox" onClick={this.toggleArchivedState} >
<label>
<span className="ui header">Archive Chat</span>
</label>
<input
type="checkbox"
value={this.props.archived}
name="public"
tabIndex="0"
className="hidden"
/>
</div>
<p>
Archived chats will store the conversation and stop notifications from bothering you in the future.
</p>
<div className="ui accordion room-users">
<div className="title active">
<i className="dropdown icon"></i>
<span className="ui header">
Channel members ({roomUsers.length})
</span>
return (
<div className="padded settings scrollable">
<div className="ui header">
Channel description
</div>
<p className="room-description">
{this.props.room.description}
</p>
<p className="gray-text">
This channel was created by {this.props.room.createdBy} on the {this.props.room.createdAt.toISOString()}.
</p>
<div className="ui toggle checkbox" onClick={this.toggleArchivedState} >
<label>
<span className="ui header">Archive Chat</span>
</label>
<input
type="checkbox"
value={this.data.room.archived}
name="public"
tabIndex="0"
className="hidden"
/>
</div>
<div className="content active">
<div className="ui list relaxed">
{user.profile.isChatterAdmin ? addUsersHTML : null}
<div className="ui divider"></div>
{roomUsers.length > 0 ? roomUsersHTML : <Loader/>}
<p>
Archived chats will store the conversation and stop notifications from bothering you in the future.
</p>
<div className="ui accordion room-users">
<div className="title active">
<i className="dropdown icon"></i>
<span className="ui header">
Channel members ({roomUsers.length})
</span>
</div>
<div className="content active">
<div className="ui list relaxed">
{user.profile.isChatterAdmin ? addUsersHTML : null}
<div className="ui divider"></div>
{roomUsersHTML}
</div>
</div>
</div>
</div>
</div>
);
);
} else {
return <Loader/>
}
}
});

Expand Down
70 changes: 43 additions & 27 deletions client/components/Profile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import React from 'react';
import ReactDOM from 'react-dom';
import Loader from "../components/Loader.jsx"

const profileSubs = new SubsManager();
import {
PROFILE_CACHE_LIMIT,
PROFILE_EXPIRE_IN
} from "../global-variables.js";

const profileSubs = new SubsManager({
cacheLimit: PROFILE_CACHE_LIMIT,
expireIn: PROFILE_EXPIRE_IN
});

const Profile = React.createClass({
mixins: [ReactMeteorData],
Expand All @@ -15,33 +23,24 @@ const Profile = React.createClass({

getMeteorData () {
const usersHandle = profileSubs.subscribe("users");
let user = {};
const subsReady = usersHandle.ready();
let user = null;

if (usersHandle.ready()) {
if (subsReady) {
user = Meteor.users.findOne(this.props.userProfile);
}
return {
usersHandle,
user
user,
subsReady
}
},

handleSubmit(e) {
e.preventDefault();
const nickname = ReactDOM.findDOMNode(this.refs.nickname).value.trim();
if (nickname.length === 0) return;
Meteor.call("user.changeNickname", nickname, (error, result) => {
if (!error) {
this.setState({nicknameChanged: true})
}
});
},

componentDidMount() {
if (this.data.usersHandle.ready() && this.props.userProfile == Meteor.userId()) {
ReactDOM.findDOMNode(this.refs.nickname).focus();
$('.ui.form')
.form({
initializeInput(input) {
if (input) {
this.nicknameInput = input;
input.focus();
$('.ui.form').form(
{
fields: {
nickname: {
identifier: 'nickname',
Expand All @@ -53,25 +52,44 @@ const Profile = React.createClass({
]
}
}
});
}
);
}
},

handleSubmit(e) {
e.preventDefault();
const nickname = this.nicknameInput.value.trim();
if (nickname.length === 0) return;
Meteor.call("user.changeNickname", nickname, (error, result) => {
if (!error) {
this.setState({nicknameChanged: true})
}
});
},

render() {
if (!this.data.usersHandle.ready()) {
if (!this.data.subsReady) {
return <Loader/>;
}

const userId = this.data.user._id;
const user = this.data.user.profile;
const headerText = `${user.chatterNickname}'s Profile`;

const form = (
<div>
<form className={this.state.nicknameChanged ? "hidden" : "ui form"} onSubmit={this.handleSubmit} ref="form">
<div className="field">
<label>
Nickname
</label>
<input type="text" name="nickname" placeholder={user.chatterNickname} ref="nickname"></input>
<input
type="text"
name="nickname"
placeholder={user.chatterNickname}
ref={this.initializeInput}
/>
</div>
<button className="ui button primary centered" type="submit" >
Change nickname
Expand All @@ -84,8 +102,6 @@ const Profile = React.createClass({
</div>
);



return (
<div className="padded profile scrollable">
<img className="ui small circular centered image" src={user.chatterAvatar}/>
Expand All @@ -98,7 +114,7 @@ const Profile = React.createClass({
<p className={user.online ? "success-msg" : "failure-msg"}>
<span>{user.chatterNickname}</span> is currently {user.online ? "online" : "offline"}.
</p>
{this.props.userProfile == Meteor.userId() ? form : null}
{this.props.userProfile === userId ? form : null}
</div>
);
}
Expand Down
Loading