Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 691 hangout participant count #719

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c815d9b
Merge pull request #664 from codebuddiesdotorg/staging
lpatmo Oct 15, 2017
9e0ce10
Merge pull request #689 from codebuddiesdotorg/staging
lpatmo Oct 23, 2017
d02daf8
fix for bug 690: admins should be able to access 24/7 hangout (#693) …
lpatmo Oct 24, 2017
f127b41
Merge branch 'master' of github.com:codebuddiesdotorg/codebuddies int…
distalx Nov 8, 2017
6b375c0
Merge branch 'staging' of github.com:codebuddiesdotorg/codebuddies in…
distalx Nov 17, 2017
e8ae787
Issue-691. Show number of participants in 24/7 hangout
railsstudent Nov 18, 2017
f19f835
Remove unique index comment
railsstudent Nov 18, 2017
c4c591e
Merge branch 'issue-691-hangout-participant-count' of git://github.co…
distalx Nov 18, 2017
14821c7
fix 'participants_count' of undefined console err
distalx Nov 18, 2017
6ff72f2
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 19, 2017
e52a2e4
Merge branch 'staging' into issue-691-hangout-participant-count
railsstudent Nov 19, 2017
02f01bb
Get rid of session variable
railsstudent Nov 19, 2017
b2e11f9
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 19, 2017
f6b6d27
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 20, 2017
24da525
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 22, 2017
91e7c24
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 24, 2017
03eeba4
Merge branch 'staging' into issue-691-hangout-participant-count
railsstudent Nov 24, 2017
6f52d47
Move server-side logic to new files
railsstudent Nov 24, 2017
d45ea41
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 26, 2017
9c5aeec
Merge remote-tracking branch 'upstream/staging' into staging
railsstudent Nov 26, 2017
c4dfcb5
Merge branch 'staging' into issue-691-hangout-participant-count
railsstudent Nov 26, 2017
5809d32
Enable seed data
railsstudent Nov 26, 2017
ddbd1c5
minor improvements
distalx Dec 3, 2017
2c760ad
Merge remote-tracking branch 'origin/issue-691-hangout-participant-co…
railsstudent Dec 9, 2017
2a2b206
Show laptop icon when people join 24/7 hangout
railsstudent Dec 17, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions client/css/_fonts.scss
Expand Up @@ -6,6 +6,7 @@ $open-sans: 'Open Sans', sans-serif;
.fa-microphone-slash { color: $icon-silent; }
.fa-user { color: $icon-teaching; }
.fa-users { color: $icon-collab; }
.fa-laptop { color: $icon-collab; }

a { color: $dodgerblue; }

Expand Down
2 changes: 1 addition & 1 deletion client/css/_post.scss
Expand Up @@ -108,7 +108,7 @@


.btn-danger {
background: $danger-red;
background: $end-hangout-color;
}

.google-hangout {
Expand Down
7 changes: 6 additions & 1 deletion client/templates/hangout/hangout-frame.html
Expand Up @@ -8,9 +8,14 @@
</div>

<div class="alert alert-info margin-top-1 margin-bottom-1">
<p class="align-center">If you're seeing a blank screen, <a href="https://meet.jit.si/cb{{_id}}" target="_blank">join here.</a> (New to Jitsi? Check out <a href="/images/codebuddies_jitsi_diagram.jpg" target="_blank">this diagram</a>.)</p>
<p class="align-center">If you're seeing a blank screen, <a href="https://meet.jit.si/cb{{_id}}" target="_blank" id="joinHere">join here.</a> (New to Jitsi? Check out <a href="/images/codebuddies_jitsi_diagram.jpg" target="_blank">this diagram</a>.)</p>
</div>
<div id="hangout-container"></div>
{{#if numParticipants}}
<div class="margin-top-1 margin-bottom-1">
<p class="align-center well">{{_ "hangout_participant" count=numParticipants }}</p>
</div>
{{/if}}
<span id="post_id" class="hide">{{_id}}</span>

</template>
47 changes: 45 additions & 2 deletions client/templates/hangout/hangout-frame.js
@@ -1,5 +1,11 @@
Template.hangoutFrame.onCreated(function() {
let instance = this;
instance.joinedHangout = false;
instance.room = new ReactiveVar(`cb${instance.data._id}`);

instance.autorun(() => {
instance.subscribe('hangoutParticipants', instance.room.get());
});

/**
* Initialize Jitsi
Expand All @@ -22,7 +28,6 @@ Template.hangoutFrame.onCreated(function() {

instance.api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);


instance.api.executeCommand('displayName', data.username);
instance.api.executeCommand('toggleChat');
instance.api.executeCommand('avatarUrl', data.avatar);
Expand All @@ -31,7 +36,7 @@ Template.hangoutFrame.onCreated(function() {
$("[id^=" + 'jitsiConference' + "]").css('width', '100%');
//only show the launch hangout button if Jitsi is not loaded
$("[id^=" + 'jitsiConference' + "]").length == 1 ? $('.load-hangout').hide() : $('#load-hangout').show();

instance.api.on('readyToClose', () => {
Bert.alert({
type: 'success',
Expand All @@ -40,6 +45,14 @@ Template.hangoutFrame.onCreated(function() {
});
FlowRouter.go('all study groups');
});

Meteor.call('joinParticipant', instance.room.get(),function(error, result) {
if (error) {
return Bert.alert(error.reason, 'danger', 'growl-top-right');
} else {
instance.joinedHangout = true;
}
});
}

/**
Expand Down Expand Up @@ -81,11 +94,41 @@ Template.hangoutFrame.events({
avatar: Meteor.user().profile.avatar.default
}
return template.loadJitsi(data);
},
'click #joinHere': function(event, template){
const hangout_id = `cb${this._id}`;

Meteor.call('joinParticipant', hangout_id,function(error, result) {
if (error) {
return Bert.alert(error.reason, 'danger', 'growl-top-right');
}
});

}

});


Template.hangoutFrame.onDestroyed(function () {
//Template.instance().disposeJitsi();
//Remove for now (see: issue 461)
const joinedHangout = Template.instance().joinedHangout;
if (joinedHangout && joinedHangout === true) {
Meteor.call('leaveParticipant', Template.instance().room.get(),
function(error, result) {
if (error) {
return Bert.alert(error.reason, 'danger', 'growl-top-right' );
}
});
}
});

Template.hangoutFrame.helpers({
numParticipants: function() {
const appState = AppStats.findOne({ _id: Template.instance().room.get() });
if (appState && appState.participants ) {
return appState.participants.length
}
return 0;
}
});
4 changes: 3 additions & 1 deletion client/templates/hangout/hangout.js
Expand Up @@ -7,10 +7,12 @@ Meteor.startup(function() {


Template.hangout.onCreated(function() {
let instance = this;
var title = "CodeBuddies | Hangout";
DocHead.setTitle(title);

this.subscribe("hangoutById", FlowRouter.getParam('hangoutId'));
instance.subscribe("hangoutById", FlowRouter.getParam('hangoutId'));

});

Template.hangout.rendered = function() {
Expand Down
3 changes: 3 additions & 0 deletions client/templates/study_groups/all_study_groups.html
Expand Up @@ -34,6 +34,9 @@ <h2>Study Groups</h2>
<h4>
<a href="{{pathFor 'study group' studyGroupSlug=slug studyGroupId=_id}}"> {{title}} </a>
<br> <small>{{tagline}}</small> <small><i class="fa fa-users fa-fw"></i>{{members.length}}</small>
{{#if numParticipants _id}}
<small><i class="fa fa-laptop fa-fw"></i>{{ numParticipants _id }}</small>
{{/if}}
{{#if isInRole 'owner' _id}}
<span class="label label-primary pull-right">Owner</span>
{{/if}}
Expand Down
11 changes: 11 additions & 0 deletions client/templates/study_groups/all_study_groups.js
Expand Up @@ -18,6 +18,9 @@ Template.allStudyGroups.onCreated(function() {
let limit = instance.limit.get();
let studyGroupsFilter = instance.studyGroupsFilter.get()
instance.subscribe('allStudyGroups', limit, studyGroupsFilter);

const hangoutIds = StudyGroups.find({}, { fields: { _id: 1 } }).map(x => `cb${x._id}`);
instance.subscribe('allHangoutParticipants', hangoutIds);
});

instance.loadStudyGroups = function() {
Expand Down Expand Up @@ -68,6 +71,14 @@ Template.allStudyGroups.helpers({
},
sgSearchMode: function(){
return Session.get('sgSearchMode');
},
numParticipants: function(studyGroupId) {
const hangoutId = `cb${studyGroupId}`;
const appState = AppStats.findOne({ _id: hangoutId });
if (appState && appState.participants ) {
return appState.participants.length
}
return 0;
}
});

Expand Down
5 changes: 4 additions & 1 deletion client/templates/study_groups/my_study_groups.html
Expand Up @@ -20,6 +20,9 @@ <h2>My Study Groups</h2>
<h4>
<a href="{{pathFor 'study group' studyGroupSlug=slug studyGroupId=_id}}"> {{title}} </a>
<br> <small>{{tagline}}</small> <small><i class="fa fa-users fa-fw"></i>{{members.length}}</small>
{{#if numParticipants _id}}
<small><i class="fa fa-laptop fa-fw"></i>{{ numParticipants _id }}</small>
{{/if}}
{{#if isInRole 'owner' _id}}
<span class="label label-primary pull-right">Owner</span>
{{/if}}
Expand Down Expand Up @@ -67,4 +70,4 @@ <h5 class="text-center">You've reached the end of the page.</h5>
</div>

</div><!-- #study-groups -->
</template>
</template>
11 changes: 11 additions & 0 deletions client/templates/study_groups/my_study_groups.js
Expand Up @@ -16,6 +16,9 @@ Template.myStudyGroups.onCreated(function() {
instance.autorun(function () {
let limit = instance.limit.get();
instance.subscribe('myStudyGroups', limit);

const hangoutIds = StudyGroups.find({}, { fields: { _id: 1 } }).map(x => `cb${x._id}`);
instance.subscribe('allHangoutParticipants', hangoutIds);
});

instance.loadStudyGroups = function() {
Expand Down Expand Up @@ -58,6 +61,14 @@ Template.myStudyGroups.helpers({
status:function(){
return Template.instance().flag.get();
},
numParticipants: function(studyGroupId) {
const hangoutId = `cb${studyGroupId}`;
const appState = AppStats.findOne({ _id: hangoutId });
if (appState && appState.participants ) {
return appState.participants.length
}
return 0;
}
});

Template.myStudyGroups.events({
Expand Down
2 changes: 1 addition & 1 deletion client/templates/study_groups/single_study_group.html
Expand Up @@ -76,7 +76,7 @@ <h5><i class="fa fa-map-pin" aria-hidden="true"></i> {{tagline}}</h5>
<div class="col-md-9 study-group-body">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#description" aria-controls="description" role="tab" data-toggle="tab">{{_ 'description'}}</a></li>
<li role="presentation"><a href="#247hangout" aria-controls="247hangout" role="tab" data-toggle="tab">{{_ 'twentyforseven'}}</a></li>
<li role="presentation"><a href="#247hangout" aria-controls="247hangout" role="tab" data-toggle="tab">{{_ 'twentyforseven'}} {{#if numParticipants}}<span class="badge">{{numParticipants}}</span>{{/if}}</a></li>
<li role="presentation"><a href="#hangouts" aria-controls="hangouts" role="tab" data-toggle="tab">{{_ 'hangouts'}}</a></li>
<li role="presentation"><a href="#members" aria-controls="members" role="tab" data-toggle="tab">{{_ 'members'}} ({{ members.length }})</a></li>
<li role="presentation"><a href="#learnings" aria-controls="learnings" role="tab" data-toggle="tab">{{_ 'learnings'}} ({{ learningsCount }})</a></li>
Expand Down
9 changes: 9 additions & 0 deletions client/templates/study_groups/single_study_group.js
@@ -1,8 +1,10 @@
Template.singleStudyGroup.onCreated(function() {
let instance = this;
instance.studyGroupId = FlowRouter.getParam('studyGroupId');
instance.hangoutId = `cb${instance.studyGroupId}`;
instance.autorun(() => {
instance.subscribe('studyGroupById', instance.studyGroupId);
instance.subscribe('hangoutParticipants', instance.hangoutId);
});

});
Expand Down Expand Up @@ -31,6 +33,13 @@ Template.singleStudyGroup.helpers({
},
learningsCount: function() {
return Learnings.find().count();
},
numParticipants: function() {
const appState = AppStats.findOne({ _id: Template.instance().hangoutId });
if (appState && appState.participants ) {
return appState.participants.length
}
return 0;
}
});

Expand Down
3 changes: 3 additions & 0 deletions i18n/en.i18n.json
Expand Up @@ -68,6 +68,8 @@
"transfer_study_group": "Transferring study group cannot be undone",
"yes_transfer_group": "Yes, transfer it!",
"no_transfer_group": "No, I was just kidding",
"hangout_participant": "1 person is currently in the 24/7 hangout.",
"hangout_participant_plural": "__count__ people are currently in the 24/7 hangout.",

// hangout
"what_is_a_hangout": "What is a Hangout?",
Expand All @@ -81,6 +83,7 @@
"click_to_load_hangout": "Click to load the hangout",
"upcoming_events": "Live and upcoming events",
"past_events": "Past events",

// popup messages
"you_are_almost_there": "You are almost there!",
"login_join_hangout": "Please sign in to codebuddies.slack.com to join a hangout",
Expand Down
1 change: 1 addition & 0 deletions lib/collections.js
Expand Up @@ -9,3 +9,4 @@ Resources = new Mongo.Collection("resources");
Activities = new Mongo.Collection("activities");
Migrations = new Mongo.Collection("migrations");
Availabilities = new Mongo.Collection("availabilities");
AppStats = new Mongo.Collection('app_stats');
55 changes: 55 additions & 0 deletions server/app_stats/methods.js
@@ -0,0 +1,55 @@

Meteor.methods({
joinParticipant: function(hangoutId) {
check(hangoutId, String);

const actor = Meteor.user()
if (!actor) {
throw new Meteor.Error(403, "Access denied")
}

const participant = {
id: actor._id,
username: actor.username,
avatar: actor.profile.avatar.default
}

AppStats.upsert({
_id: hangoutId
},
{
$setOnInsert: {
hangout_id: hangoutId,
type: "PARTICIPANT_COUNT"
},
$addToSet: {
participants: {
$each: [ participant ]
}
}
});
}
});

Meteor.methods({
leaveParticipant: function(hangoutId) {
check(hangoutId, String);

const actor = Meteor.user()
if (!actor) {
throw new Meteor.Error(403, "Access denied")
}

// Decrement count when participant count is positive
AppStats.update({
_id: hangoutId
},
{
$pull: {
participants: {
id : actor._id
}
}
});
}
});
17 changes: 17 additions & 0 deletions server/app_stats/publications.js
@@ -0,0 +1,17 @@
Meteor.publish('hangoutParticipants', function(hangoutId) {
check(hangoutId, String);
if (hangoutId) {
return AppStats.find({ _id: hangoutId });
}
this.ready();
});

Meteor.publish('allHangoutParticipants', function(hangoutIds) {
check(hangoutIds, Match.Maybe([String]));

if (hangoutIds && hangoutIds.length > 0 ){
return AppStats.find({_id: { $in: hangoutIds } });
}
this.ready();

});
18 changes: 18 additions & 0 deletions server/main.js
Expand Up @@ -130,3 +130,21 @@ Accounts.onCreateUser(function(options, user) {
}

});

// global users observer for app_stats
Meteor.users.find({ "status.online": true }).observe({
removed: function(user) {
//remove participants from active list
AppStats.update({"participants.id":user._id},
{
$pull: {
participants: {
id : user._id
}
},

},
{multi: true});

}
});
2 changes: 1 addition & 1 deletion settings-development.json
Expand Up @@ -15,7 +15,7 @@
}
},
"isModeProduction": false,
"seeder": false,
"seeder": true,
"slack_clientid": "4364220508.48656557590",
"slack_clientsecret": "33e0c6dda98e994f194efdc9b6d35c46",
"slack": "https://hooks.slack.com/services/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",
Expand Down