virtualcommons-svn Mailing List for Virtual Commons Experiment Software (Page 10)
Status: Beta
Brought to you by:
alllee
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(21) |
Aug
(31) |
Sep
(6) |
Oct
(15) |
Nov
(2) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(4) |
Feb
(6) |
Mar
(12) |
Apr
(52) |
May
(14) |
Jun
(19) |
Jul
(81) |
Aug
(115) |
Sep
(36) |
Oct
(88) |
Nov
(46) |
Dec
(58) |
2010 |
Jan
(52) |
Feb
(55) |
Mar
(48) |
Apr
(15) |
May
(5) |
Jun
(38) |
Jul
(27) |
Aug
(24) |
Sep
(28) |
Oct
(1) |
Nov
(2) |
Dec
(29) |
2011 |
Jan
(87) |
Feb
(39) |
Mar
(63) |
Apr
(42) |
May
(26) |
Jun
(53) |
Jul
(23) |
Aug
(43) |
Sep
(37) |
Oct
(25) |
Nov
(4) |
Dec
(7) |
2012 |
Jan
(73) |
Feb
(79) |
Mar
(62) |
Apr
(28) |
May
(12) |
Jun
(2) |
Jul
(9) |
Aug
(1) |
Sep
(8) |
Oct
|
Nov
(3) |
Dec
(3) |
2013 |
Jan
(8) |
Feb
(16) |
Mar
(38) |
Apr
(74) |
May
(62) |
Jun
(15) |
Jul
(49) |
Aug
(19) |
Sep
(9) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(25) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <com...@bi...> - 2013-04-06 00:10:21
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/67ff21bb249d/ Changeset: 67ff21bb249d User: alllee Date: 2013-04-06 02:10:02 Summary: adding img alts Affected #: 2 files diff -r 227bc37636c2bceb83d0a6c54ffc198fc0372d50 -r 67ff21bb249d6169a1997898d342756ae6964188 vcweb/core/templates/forms/base.html --- a/vcweb/core/templates/forms/base.html +++ b/vcweb/core/templates/forms/base.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block page %} -<form id='vcweb-form' action='' method='post' class='form-horizontal'> +<form id='vcweb-form' method='post' class='form-horizontal'> {% csrf_token %} {% block form %} {% endblock form %} diff -r 227bc37636c2bceb83d0a6c54ffc198fc0372d50 -r 67ff21bb249d6169a1997898d342756ae6964188 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -66,10 +66,10 @@ <h5 id='current-level' ><span class='lighterprints-scoreboard-uppercase'>Current Level</span></h5><div class='dashboard-content'><div data-bind='if: experimentCompleted'> - <img class='group-level' width='120' height='70' src='{% static "images/lighterprints/experiment-completed.png"%}'> + <img alt='Experiment Completed' class='group-level' width='120' height='70' src='{% static "images/lighterprints/experiment-completed.png"%}'></div><div data-bind='ifnot: experimentCompleted'> - <img class='group-level' width="104" height="65" data-bind="attr: { src: '{% static "images/lighterprints/rank"%}' + groupLevel() + '.png' }"> + <img alt='Group Level' class='group-level' width="104" height="65" data-bind="attr: { src: '{% static "images/lighterprints/rank"%}' + groupLevel() + '.png' }"></div></div></div> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 23:24:44
|
3 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/d6aa1bf4418c/ Changeset: d6aa1bf4418c User: alllee Date: 2013-04-06 01:02:41 Summary: moving postComment and like functionality into model.js itself though there are a few unruly dependencies on the popover that probably won't be useful in the mobile app version. refining the tutorial a bit more, closing it out when a tab is activated and offering the ability to restart it in the help page. Affected #: 3 files diff -r 7218553f7357311837352f370e3cc77fecb3c9f9 -r d6aa1bf4418ca89eaaaac3fa15e3f073d1aa2507 vcweb/lighterprints/static/js/lighterprints/model.js --- a/vcweb/lighterprints/static/js/lighterprints/model.js +++ b/vcweb/lighterprints/static/js/lighterprints/model.js @@ -55,6 +55,28 @@ $('#chatText').val(''); return false; }; + model.postComment = function(targetModel) { + var formData = $('#commentForm' + targetModel.pk()).serialize(); + $('.comment-popover').popover('hide'); + $.post('/lighterprints/api/comment', formData, function(response) { + if (response.success) { + ko.mapping.fromJSON(response.viewModel, model); + } + }); + }; + model.like = function(targetModel) { + // FIXME: if targetModel.likes already contains this participant's pgr.pk, don't allow for this again + if (targetModel.liked()) { + console.debug("target model: " + targetModel + " is already well-liked"); + return; + } + targetModel.liked(true); + $.post('/lighterprints/api/like', {participant_group_id: model.participantGroupId(), target_id: targetModel.pk()}, + function(data) { + targetModel.liked(data.success); + }); + }; + model.lockedChallenges = ko.computed(function() { return ko.utils.arrayFilter(model.activities(), function(activity) { return activity.locked() }); }); diff -r 7218553f7357311837352f370e3cc77fecb3c9f9 -r d6aa1bf4418ca89eaaaac3fa15e3f073d1aa2507 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -8,10 +8,10 @@ {% block headerlinks %} <ul class='nav nav-tabs' id='lfp-navtabs'><li><a class='brand'><img alt='footprint logo' src='{% static "images/lighterprints/logo.png"%}' width="25" height="25"> lighter<strong class='lighterprints-green'>footprints</strong></a></li> - <li class='active'><a href='#dashboard' data-toggle='tab'><i class='icon-dashboard'></i> Dashboard</a></li> - <li><a href='#challenges' data-toggle='tab'><i class='icon-star-empty'></i> Challenges</a></li> - <li><a href='#group' data-toggle='tab'><i class='icon-comments-alt'></i> My Group</a></li> - <li><a href='#help' data-toggle='tab'><i class='icon-question-sign'></i> Help</a></li> + <li class='active'><a href='#dashboard' data-bind='click: activateDashboardTab'><i class='icon-dashboard'></i> Dashboard</a></li> + <li><a href='#challenges' data-bind='click:activateChallengesTab'><i class='icon-star-empty'></i> Challenges</a></li> + <li><a href='#group' data-bind='click: activateGroupTab'><i class='icon-comments-alt'></i> My Group</a></li> + <li><a href='#help' data-bind='click: activateHelpTab'><i class='icon-question-sign'></i> Help</a></li></ul> {% endblock %} {% block logo %} @@ -163,7 +163,10 @@ To participate, simply click on the <a href='#challenges' data-bind='click: activateChallengesTab'>Challenges tab</a>, and select a challenge you'd like to perform. You can leave messages for the other members n your group via the <a href='#group' data-bind='click: activateGroupTab'>My Group tab</a> or use the <a href='#dashboard' data-bind='click:activateDashboardTab'>Dashboard</a> to view your group's progress. + <br> + You can also <a href='#dashboard' data-bind='click: restartTour'>restart the tutorial</a>. </p> + <h3 id='faq' class='underline'>Frequently Asked Questions</h3><div class='well alert-white'><h4>I performed an activity worth 15 points but only 3 points were added to Today's Progress and Today's Score. Why?</h4> @@ -331,16 +334,21 @@ var viewModelData = $.parseJSON("{{ view_model_json|escapejs }}"); var viewModel = new LighterFootprintsModel(viewModelData); // custom view model methods, some of these may be lifted into the model itself - viewModel.activateChallengesTab = activateTabFunctor('#challenges', '#lfp-navtabs'); - viewModel.activateDashboardTab = activateTabFunctor('#dashboard', '#lfp-navtabs'); - viewModel.activateHelpTab = activateTabFunctor('#help', '#lfp-navtabs'); - viewModel.activateGroupTab = activateTabFunctor('#group', '#lfp-navtabs'); + viewModel.tutorialTour = ko.observable(new Tour()); viewModel.setup = function() { viewModel.initializeChart(); viewModel.setupTour(); }; + viewModel.endTour = function() { + var tour = viewModel.tutorialTour(); + if (tour.ended()) { + return; + } + console.debug("ending tour"); + tour.end(); + } viewModel.setupTour = function() { - var tour = new Tour(); + var tour = viewModel.tutorialTour(); tour.addStep({ element: "#todays-score", title: "Today's Score", @@ -375,6 +383,10 @@ } tour.start(); } + viewModel.restartTour = function() { + viewModel.activateDashboardTab(); + viewModel.tutorialTour().restart(); + } viewModel.initializeChart = function() { var todaysProgressContext = document.getElementById("todaysProgressChart").getContext("2d"); var progressChart = new Chart(todaysProgressContext).Doughnut(viewModel.todaysProgressChartData()); @@ -389,28 +401,10 @@ } return data; }); - viewModel.postComment = function(targetModel) { - var formData = $('#commentForm' + targetModel.pk()).serialize(); - $('.comment-popover').popover('hide'); - $.post('/lighterprints/api/comment', formData, function(response) { - if (response.success) { - ko.mapping.fromJSON(response.viewModel, viewModel); - } - }); - }; - viewModel.like = function(targetModel) { - // FIXME: if targetModel.likes already contains this participant's pgr.pk, don't allow for this again - if (targetModel.liked()) { - console.debug("this is already liked"); - return; - } - targetModel.liked(true); - $.post('/lighterprints/api/like', - {participant_group_id: {{ participant_group_relationship.pk }}, target_id: targetModel.pk()}, - function(data) { - targetModel.liked(data.success); - }); - }; + viewModel.activateChallengesTab = activateTabFunctor('#challenges', '#lfp-navtabs', viewModel.endTour); + viewModel.activateDashboardTab = activateTabFunctor('#dashboard', '#lfp-navtabs', viewModel.endTour); + viewModel.activateHelpTab = activateTabFunctor('#help', '#lfp-navtabs', viewModel.endTour); + viewModel.activateGroupTab = activateTabFunctor('#group', '#lfp-navtabs', viewModel.endTour); // FIXME: manually manipulating DOM elements via JQuery feels a bit hacky mixed in with KO's data binding viewModel.showActivityPerformedModal = function() { $('#activityPerformedModal .progress').removeClass('hide'); diff -r 7218553f7357311837352f370e3cc77fecb3c9f9 -r d6aa1bf4418ca89eaaaac3fa15e3f073d1aa2507 vcweb/static/js/common.js --- a/vcweb/static/js/common.js +++ b/vcweb/static/js/common.js @@ -18,12 +18,15 @@ // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } -function activateTabFunctor(tabHref, parentId) { +function activateTabFunctor(tabHref, parentId, callback) { if (! parentId) { parentId = ".nav-tabs"; } return function() { $(parentId + ' a[href="' + tabHref + '"]').tab('show'); + if (callback && typeof(callback) === 'function') { + callback(); + } } } var csrftoken = $.cookie('csrftoken'); https://bitbucket.org/virtualcommons/vcweb/commits/6afac94cf9d2/ Changeset: 6afac94cf9d2 User: alllee Date: 2013-04-06 01:20:07 Summary: updating tour labels Affected #: 1 file diff -r d6aa1bf4418ca89eaaaac3fa15e3f073d1aa2507 -r 6afac94cf9d29ea995c6e5cc53276f7f225fad52 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -334,13 +334,13 @@ var viewModelData = $.parseJSON("{{ view_model_json|escapejs }}"); var viewModel = new LighterFootprintsModel(viewModelData); // custom view model methods, some of these may be lifted into the model itself - viewModel.tutorialTour = ko.observable(new Tour()); + viewModel.tutorialTour = new Tour({ name: "lfpTutorial", labels: { end: "End tutorial", next: 'Next »', prev: '« Back' }}); viewModel.setup = function() { viewModel.initializeChart(); viewModel.setupTour(); }; viewModel.endTour = function() { - var tour = viewModel.tutorialTour(); + var tour = viewModel.tutorialTour; if (tour.ended()) { return; } @@ -348,7 +348,7 @@ tour.end(); } viewModel.setupTour = function() { - var tour = viewModel.tutorialTour(); + var tour = viewModel.tutorialTour; tour.addStep({ element: "#todays-score", title: "Today's Score", @@ -385,7 +385,7 @@ } viewModel.restartTour = function() { viewModel.activateDashboardTab(); - viewModel.tutorialTour().restart(); + viewModel.tutorialTour.restart(); } viewModel.initializeChart = function() { var todaysProgressContext = document.getElementById("todaysProgressChart").getContext("2d"); https://bitbucket.org/virtualcommons/vcweb/commits/227bc37636c2/ Changeset: 227bc37636c2 User: alllee Date: 2013-04-06 01:24:25 Summary: removing rel="popover" from inappropriate elements, running HTML validator check Affected #: 1 file diff -r 6afac94cf9d29ea995c6e5cc53276f7f225fad52 -r 227bc37636c2bceb83d0a6c54ffc198fc0372d50 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -53,7 +53,7 @@ <div class='row lighterprints-scoreboard'><div class='span2'><h5 id='todays-score'><span class='lighterprints-scoreboard-uppercase'>Today's Score</span> - <i id='score-info' style='margin:8px 0 0 0;' rel='popover' data-trigger='hover' data-placement='top' + <i id='score-info' style='margin:8px 0 0 0;' data-trigger='hover' data-placement='top' data-content="This is your group's average score for the day. Complete high-value challenges to rank your group up." class='pull-right icon-info-sign'></i></h5><table><tr> @@ -75,12 +75,12 @@ </div><div class='span2 left-divider'><h5 id='todays-progress'><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span> - <i id='progress-info' style='padding: 0px 0px 0px 0px; margin: -1px 0px 0px -1px;' rel='popover' data-trigger='hover' + <i id='progress-info' style='padding: 0px 0px 0px 0px; margin: -1px 0px 0px -1px;' data-trigger='hover' data-placement='top' data-content='This chart shows your average group score (green) in relation to the average group score needed to advance to the next level (gray).' class='icon-info-sign'></i></h5><div data-bind='popover: { content: "#todaysProgressChartPopoverContent", id: "todays-progress-chart-popover"}' class='chart'> - <canvas rel='popover' id='todaysProgressChart' width="87" height="87"></canvas> + <canvas id='todaysProgressChart' width="87" height="87"></canvas></div></div><div class='span2 left-divider'> @@ -115,7 +115,7 @@ </div></div><div class='tab-pane' id='challenges'> - <h1 class='header'><i class='icon-star'></i> Challenges</h2> + <h1 class='header'><i class='icon-star'></i> Challenges</h1><div class='alert alert-block alert-white'><button type="button" class="close" data-dismiss="alert"><i class='icon-remove-sign'></i></button><h2>Complete challenges to earn green points.</h2> @@ -267,7 +267,7 @@ </div><div id='activityPerformedModalText' data-bind='with: lastPerformedActivity' class='hide'><div class='row-fluid pagination-centered'> - <img data-bind='attr: {src: "{% static 'images/lighterprints/badges/'%}" + name() + ".png" }'> + <img alt='Lighterprints Activity Badge' data-bind='attr: {src: "{% static 'images/lighterprints/badges/'%}" + name() + ".png" }'></div><h3>You completed a challenge!</h3><p> @@ -444,8 +444,8 @@ }); }; ko.applyBindings(viewModel); - // FIXME: use $('.popover').popover() if we end up having a lot more of these. viewModel.setup(); + // FIXME: more efficient way to select these? $('[data-content]').popover(); }); </script> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 21:55:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/7218553f7357/ Changeset: 7218553f7357 User: alllee Date: 2013-04-05 23:55:33 Summary: refactoring Activity.objects.currently_available and upcoming to return lists of ids instead of full entities Affected #: 1 file diff -r 4ceaed6294a4eb88f4cebe1445f12658244ce9cd -r 7218553f7357311837352f370e3cc77fecb3c9f9 vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -121,14 +121,19 @@ return self._filter_by_availability(level, start_time__gte=current_time) def _filter_by_availability(self, level=1, **kwargs): - return [aa.activity for aa in ActivityAvailability.objects.select_related('activity').filter(models.Q(**kwargs)) if aa.activity.level <= level] + return ActivityAvailability.objects.select_related('activity').filter(models.Q(activity__level__lte=level, **kwargs)).values_list('activity', flat=True) - def currently_available(self, level=1, **kwargs): - current_time = datetime.now().time() - activities = self._filter_by_availability(level, start_time__lte=current_time, end_time__gte=current_time) + def currently_available(self, level=1, current_time=None, fetch_models=False, **kwargs): + ''' returns a list of available activity pks ''' + if current_time is None: + current_time = datetime.now().time() + activity_ids = list(self._filter_by_availability(level, start_time__lte=current_time, end_time__gte=current_time)) # add available all day activities - activities.extend(Activity.objects.filter(available_all_day=True, level__lte=level)) - return activities + activity_ids.extend(Activity.objects.filter(available_all_day=True, level__lte=level).values_list('pk', flat=True)) + if fetch_models: + return Activity.objects.filter(pk__in=activity_ids) + else: + return activity_ids def get_by_natural_key(self, name): return self.get(name=name) @@ -286,17 +291,16 @@ def get_activity_status_dict(participant_group_relationship, activities, group_level=1): today = datetime.combine(date.today(), time()) - available_activities = Activity.objects.currently_available(participant_group_relationship=participant_group_relationship, level=group_level) + available_activity_ids = Activity.objects.currently_available(participant_group_relationship=participant_group_relationship, level=group_level) # filter out all activities that have already been performed today (activities may only be performed once a day) performed_activity_data_values = participant_group_relationship.participant_data_value_set.filter(parameter=get_activity_performed_parameter(), - int_value__in=[activity.id for activity in available_activities], + int_value__in=available_activity_ids, date_created__gte=today) - upcoming_activities = Activity.objects.upcoming(level=group_level) + upcoming_activity_ids = Activity.objects.upcoming(level=group_level) # XXX: data value's int_value stores the fk directly, using .value does a fk lookup to restore the full entity # which we don't need performed_activity_ids = performed_activity_data_values.values_list('int_value', flat=True) - available_activity_ids = [activity.pk for activity in available_activities if activity.pk not in performed_activity_ids] - upcoming_activity_ids = [activity.pk for activity in upcoming_activities] + available_activity_ids = filter(lambda pk: pk not in performed_activity_ids, available_activity_ids) status_dict = {} for activity in activities: if activity.pk in performed_activity_ids: @@ -383,15 +387,15 @@ return Activity.objects.at_level(group_level) today = datetime.combine(date.today(), time()) - available_activities = Activity.objects.currently_available(participant_group_relationship=participant_group_relationship, level=group_level) + available_activity_ids = Activity.objects.currently_available(participant_group_relationship=participant_group_relationship, level=group_level) # filter out all activities that have already been performed today (activities may only be performed once a day) performed_activity_data_values = participant_group_relationship.participant_data_value_set.filter(parameter=get_activity_performed_parameter(), - int_value__in=[activity.id for activity in available_activities], + int_value__in=available_activity_ids, date_created__gte=today) # XXX: data value's int_value stores the fk directly, using .value does a fk lookup to restore the full entity # which we don't need - performed_activity_ids = [padv.int_value for padv in performed_activity_data_values] - return [activity for activity in available_activities if activity.id not in performed_activity_ids] + performed_activity_ids = performed_activity_data_values.values_list('int_value', flat=True) + return filter(lambda pk: pk not in performed_activity_ids, available_activity_ids) def check_already_performed_today(activity, participant_group_relationship): today = datetime.combine(date.today(), time()) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 08:28:37
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/4ceaed6294a4/ Changeset: 4ceaed6294a4 User: alllee Date: 2013-04-05 10:28:20 Summary: adding group rank information to nightly summary emails Affected #: 3 files diff -r 292fd44b8e84d4db60aa6eb2b97e1a47e47c0eaf -r 4ceaed6294a4eb88f4cebe1445f12658244ce9cd vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -36,7 +36,22 @@ for experiment in active_experiments: # calculate total carbon savings and decide if they move on to the next level round_data = experiment.current_round_data - for group in experiment.groups: + show_rankings = can_view_other_groups(round_data.round_configuration) + groups = list(experiment.groups) + number_of_groups = len(groups) + group_rankings = [] + group_rank = 0 + if show_rankings: + (group_scores_dict, total_participant_points) = get_group_scores(experiment, round_data, start=start) + sorted_group_scores = sorted(group_scores_dict.items(), key=lambda x: x[1]['average_group_points'], reverse=True) + group_rankings = [ g[0] for g in sorted_group_scores ] + logger.debug("sorted group scores %s - group rankings: %s", sorted_group_scores, group_rankings) + for group in groups: + experiment_completed_dv = get_experiment_completed_dv(group, round_data=round_data) + already_completed = experiment_completed_dv.boolean_value + if already_completed: + # skip this group if it's already completed the experiment. + continue promoted = False completed = False footprint_level_grdv = get_footprint_level_dv(group, round_data=round_data) @@ -49,15 +64,15 @@ footprint_level_grdv.save() if current_level == 3: completed = True -# FIXME: store another group data parameter that says they've completed the experiment? - experiment_completed_dv = get_experiment_completed_dv(group, round_data=round_data) - already_completed = experiment_completed_dv.boolean_value - if not already_completed: - group_summary_emails = create_group_summary_emails(group, footprint_level_grdv.value, promoted=promoted, completed=completed, round_data=round_data) - messages.extend(group_summary_emails) - if completed: - experiment_completed_dv.boolean_value = True - experiment_completed_dv.save() + if show_rankings: + group_rank = group_rankings.index(group) + 1 + group_summary_emails = create_group_summary_emails(group, footprint_level_grdv.value, promoted=promoted, completed=completed, round_data=round_data, + group_rank=group_rank, show_rankings=show_rankings, number_of_groups=number_of_groups) + messages.extend(group_summary_emails) + if completed: +# store the completed flag + experiment_completed_dv.boolean_value = True + experiment_completed_dv.save() logger.debug("about to send nightly summary emails (%s): %s", send_emails, messages) if send_emails: mail.get_connection().send_messages(messages) @@ -456,7 +471,6 @@ def get_group_scores(experiment, round_data, participant_group_relationship=None, start=None, end=None): activity_points_cache = get_activity_points_cache() # establish date range - # grab all of yesterday's participant data values, starting at 00:00:00 (midnight) total_participant_points = 0 if start is None: start = date.today() @@ -487,7 +501,6 @@ # cache activity points activity_points_cache = get_activity_points_cache() # establish date range - # grab all of yesterday's participant data values, starting at 00:00:00 (midnight) total_group_points = 0 total_participant_points = 0 if start is None: @@ -599,7 +612,7 @@ s = re.sub(r'\smonths?', 'mo', s) return s.replace(',', '') -def create_group_summary_emails(group, level, promoted=False, completed=False, round_data=None): +def create_group_summary_emails(group, level, promoted=False, completed=False, round_data=None, **kwargs): logger.debug("creating group summary email for group %s", group) # FIXME: need some logic to select an email template based on the treatment type, or push into the template itself plaintext_template = select_template(['lighterprints/email/group-summary-email.txt']) @@ -610,7 +623,7 @@ number_of_chat_messages = ChatMessage.objects.filter(participant_group_relationship__group=group, date_created__gte=yesterday).count() messages = [] for pgr in group.participant_group_relationship_set.all(): - c = Context({ + c = Context(dict({ 'experiment': experiment, 'group_name': group.name, 'summary_date': yesterday, @@ -621,7 +634,7 @@ 'average_group_points': average_points_per_person(group, start=yesterday), 'number_of_chat_messages': number_of_chat_messages, 'individual_points': get_individual_points(pgr), - }) + }, **kwargs)) plaintext_content = plaintext_template.render(c) html_content = html_template.render(c) subject = 'Lighter Footprints Summary for %s' % yesterday diff -r 292fd44b8e84d4db60aa6eb2b97e1a47e47c0eaf -r 4ceaed6294a4eb88f4cebe1445f12658244ce9cd vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html --- a/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html +++ b/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html @@ -1,10 +1,13 @@ <h3>Lighter Footprints Summary for {{ summary_date }}</h3><p> -You are a member of {{ group_name }}. To participate in this experiment, visit <a href='{{experiment.participant_url}}'>{{experiment.participant_url}}</a>. +You are a member of {{ group_name }}. To participate in this experiment, visit <a href='https://vcweb.asu.edu{{experiment.participant_url}}'>https://vcweb.asu.edu{{experiment.participant_url}}</a>. </p><ul><li>You earned {{ individual_points }} points while the average in your group was {{ average_group_points }} point(s).</li><li>{{ number_of_chat_messages }} chat messages were posted by your group.</li> + {% if show_rankings %} + <li>Your group was ranked {{ group_rank}} out of {{ number_of_groups }}</li> + {% endif %} </ul><hr><p> diff -r 292fd44b8e84d4db60aa6eb2b97e1a47e47c0eaf -r 4ceaed6294a4eb88f4cebe1445f12658244ce9cd vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt --- a/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt +++ b/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt @@ -1,10 +1,13 @@ Lighter Footprints Summary for {{ summary_date }} -You are a member of {{ group_name }}. To participate in this experiment, visit {{experiment.participant_url}}. +You are a member of {{ group_name }}. To participate in this experiment, visit https://vcweb.asu.edu{{experiment.participant_url}}. * You earned {{ individual_points }} points. The average number of points earned per person in your group was {{ average_group_points }} point(s). * {{ number_of_chat_messages }} chat messages were posted by your group. +{% if show_rankings %} +* Your group was ranked {{ group_rank}} out of {{ number_of_groups }} +{% endif %} {% if completed %} Congratulations! Your group has finished Level 3 and completed the experiment. Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 06:56:30
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/292fd44b8e84/ Changeset: 292fd44b8e84 User: alllee Date: 2013-04-05 08:56:16 Summary: guard for points past the points needed Affected #: 1 file diff -r ebe513573e64954d75905b2eac3e7479a63e2514 -r 292fd44b8e84d4db60aa6eb2b97e1a47e47c0eaf vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -382,11 +382,12 @@ viewModel.todaysProgressChartData = ko.computed(function() { var avgPoints = viewModel.averagePoints(); var pointsToNextLevel = viewModel.pointsToNextLevel(); - console.debug(avgPoints + " / " + pointsToNextLevel) - return [ - { value: avgPoints, color: "#95CB29" }, - { value: pointsToNextLevel - avgPoints, color: "#D0D0D0" }, - ] + var data = [ { value: avgPoints, color: "#95CB29" } ] + var pointsNeeded = Math.max(0, pointsToNextLevel - avgPoints); + if (pointsNeeded > 0) { + data.push({ value: pointsNeeded, color: "#D0D0D0" }); + } + return data; }); viewModel.postComment = function(targetModel) { var formData = $('#commentForm' + targetModel.pk()).serialize(); Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 06:25:39
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/ebe513573e64/ Changeset: ebe513573e64 User: alllee Date: 2013-04-05 08:25:24 Summary: fixing doughnut chart values which are additive, not measured against an absolute scale Affected #: 2 files diff -r d496ec5a43fdec5ccf2c1aba0edf1aacef9e633f -r ebe513573e64954d75905b2eac3e7479a63e2514 vcweb/lighterprints/static/js/lighterprints/model.js --- a/vcweb/lighterprints/static/js/lighterprints/model.js +++ b/vcweb/lighterprints/static/js/lighterprints/model.js @@ -76,11 +76,14 @@ init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var attribute = ko.utils.unwrapObservable(valueAccessor()); var cssSelectorForPopoverTemplate = attribute.content; + var placement = attribute.placement || "top"; + var trigger = attribute.trigger || "manual"; var popOverTemplate = "<div id='"+attribute.id+"-popover'>" + $(cssSelectorForPopoverTemplate).html() + "</div>"; $(element).popover({ content: popOverTemplate, html: true, - trigger: 'manual' + trigger: trigger, + placement: placement }); var popoverId = "comment-popover" + attribute.id; $(element).attr('id', popoverId); diff -r d496ec5a43fdec5ccf2c1aba0edf1aacef9e633f -r ebe513573e64954d75905b2eac3e7479a63e2514 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -79,8 +79,8 @@ data-placement='top' data-content='This chart shows your average group score (green) in relation to the average group score needed to advance to the next level (gray).' class='icon-info-sign'></i></h5> - <div class='chart'> - <canvas id='todaysProgressChart' width="87" height="87"></canvas> + <div data-bind='popover: { content: "#todaysProgressChartPopoverContent", id: "todays-progress-chart-popover"}' class='chart'> + <canvas rel='popover' id='todaysProgressChart' width="87" height="87"></canvas></div></div><div class='span2 left-divider'> @@ -380,9 +380,12 @@ var progressChart = new Chart(todaysProgressContext).Doughnut(viewModel.todaysProgressChartData()); }; viewModel.todaysProgressChartData = ko.computed(function() { - return [ - { value: viewModel.averagePoints(), color: "#95CB29" }, - { value: viewModel.pointsToNextLevel(), color: "#D0D0D0" }, + var avgPoints = viewModel.averagePoints(); + var pointsToNextLevel = viewModel.pointsToNextLevel(); + console.debug(avgPoints + " / " + pointsToNextLevel) + return [ + { value: avgPoints, color: "#95CB29" }, + { value: pointsToNextLevel - avgPoints, color: "#D0D0D0" }, ] }); viewModel.postComment = function(targetModel) { @@ -452,6 +455,9 @@ }); </script><!-- bootstrap popover templates --> +<script type='text/html' id='todaysProgressChartPopoverContent'> + Your group progress: <span data-bind='text: averagePoints'></span> / <span data-bind='text:pointsToNextLevel'></span> +</script><script type='text/html' id='commentPopoverForm'><form data-bind='attr: { id: "commentForm" + pk() }'><textarea name='message' rows='3'></textarea> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-05 00:00:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/d496ec5a43fd/ Changeset: d496ec5a43fd User: alllee Date: 2013-04-05 02:00:34 Summary: group indexing is now zero-based instead of 1-based< changing group.name accordingly Affected #: 2 files diff -r 5afab4e9f7b9627acc175de034a696113e2d785e -r d496ec5a43fdec5ccf2c1aba0edf1aacef9e633f vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1447,7 +1447,7 @@ @property def name(self): - return u"Group %s" % string.ascii_uppercase[max(self.number - 1, 0)] + return u"Group %s" % string.ascii_uppercase[self.number] @property def channel(self): diff -r 5afab4e9f7b9627acc175de034a696113e2d785e -r d496ec5a43fdec5ccf2c1aba0edf1aacef9e633f vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -70,13 +70,13 @@ </div><div data-bind='ifnot: experimentCompleted'><img class='group-level' width="104" height="65" data-bind="attr: { src: '{% static "images/lighterprints/rank"%}' + groupLevel() + '.png' }"> - </div> + </div></div></div><div class='span2 left-divider'><h5 id='todays-progress'><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span><i id='progress-info' style='padding: 0px 0px 0px 0px; margin: -1px 0px 0px -1px;' rel='popover' data-trigger='hover' - data-placement='top' data-content='This chart shows the average group score needed to advance to the next level.' + data-placement='top' data-content='This chart shows your average group score (green) in relation to the average group score needed to advance to the next level (gray).' class='icon-info-sign'></i></h5><div class='chart'> @@ -213,7 +213,7 @@ <i class='lighterprints-gray icon-user icon-2x'></i></div><div class='span6'> - <strong data-bind='text: participant_name'></strong> + <strong>Participant <span data-bind='text: participant_number'></span></strong><p><span data-bind='text: message'></span></p> @@ -357,7 +357,7 @@ element: "#todays-progress", placement: "top", title: "Today's Progress", - content: "This chart displays your average group score in green and the total points needed to advance to the next level in gray. To advance to level 2 your group average score needs to reach 50." + content: "This chart displays your average group score in green and the average group score needed to advance to the next level in gray. To advance to level 2 your group average score needs to reach 50." }); tour.addStep({ element: "#time-remaining", @@ -485,7 +485,7 @@ <tr data-bind='if: $root.participantGroupId() != participant_group_id()'><td class='group-activity-icon'><i class='icon-comment lighterprints-blue'></i></td><td class='group-activity'> - <strong data-bind='text: participant_name'></strong> + Participant <strong data-bind='text: participant_number'></strong><small class='pull-right muted'><span data-bind='text: date_created'></span></small><div><span data-bind='if: target_parameter_name() === "activity_performed"'> @@ -508,7 +508,7 @@ <tr data-bind='if: $root.participantGroupId() != participant_group_id()'><td class='group-activity-icon'><i class='icon-heart lighterprints-red'></i></td><td class='group-activity'> - <strong data-bind='text: participant_name'></strong> + Participant <strong data-bind='text: participant_number'></strong><small class='pull-right muted'><span data-bind='text: date_created'></span></small><div>liked your <span data-bind='if: target_parameter_name() === "activity_performed"'> @@ -525,7 +525,7 @@ <tr><td class='group-activity-icon'><i class='icon-comment lighterprints-blue'></i></td><td class='group-activity'> - <strong data-bind='text: participant_name'></strong> + <strong>Participant <span data-bind='text: participant_number'></span></strong><small class='pull-right muted'><span data-bind='text: date_created'></span></small><div><small><i class='icon-quote-left'></i></small> @@ -540,7 +540,7 @@ <tr><td class='group-activity-icon'><i class='icon-star text-gold'></i></td><td class='group-activity'> - <strong data-bind='text: participant_name'></strong> + <strong>Participant <span data-bind='text: participant_number'></span></strong><small class='pull-right muted'><span data-bind='text: date_created'></span></small><div>earned <span class='lighterprints-green' data-bind='text:points'></span><i class='icon-leaf lighterprints-green'></i> for <span data-bind='text: $root.groupName'></span> by completing <em><span data-bind='text: display_name'></span></em>. Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-04 21:32:26
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/5afab4e9f7b9/ Changeset: 5afab4e9f7b9 User: alllee Date: 2013-04-04 23:32:13 Summary: fixing email participant URLs Affected #: 2 files diff -r e03d22dea28284c33b90585bd4731273a208dcc0 -r 5afab4e9f7b9627acc175de034a696113e2d785e vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html --- a/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html +++ b/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html @@ -7,7 +7,8 @@ actions within the experiment to reduce your virtual carbon footprint. </p><p> -To access the experiment visit <a href='{{experiment.participant_url}}'>{{experiment.participant_url}}</a> and login with the following +{% comment %} FIXME: hard coded server root {% endcomment %} +To access the experiment visit <a href='https://vcweb.asu.edu{{experiment.participant_url}}'>https://vcweb.asu.edu{{experiment.participant_url}}</a> and login with the following credentials: </p><table cellspacing="3" cellpadding="3"> diff -r e03d22dea28284c33b90585bd4731273a208dcc0 -r 5afab4e9f7b9627acc175de034a696113e2d785e vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt --- a/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt +++ b/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt @@ -4,7 +4,7 @@ with four other participants who have also signed up for this experiment. You have a chance to earn $100 by performing actions within the experiment to reduce your virtual carbon footprint. -To access the experiment visit {{experiment.participant_url}} and login with the following credentials: +To access the experiment visit https://vcweb.asu.edu{{experiment.participant_url}} and login with the following credentials: Email: {{ participant.email }} Password: {{ password }} Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-04 21:28:57
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/e03d22dea282/ Changeset: e03d22dea282 User: alllee Date: 2013-04-04 23:28:40 Summary: adding email as separate column in experimenter interface Affected #: 2 files diff -r 7e2143b407e54f8d2ea7175ce749fc640112dd5b -r e03d22dea28284c33b90585bd4731273a208dcc0 vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html +++ b/vcweb/core/templates/experimenter/monitor.html @@ -83,12 +83,13 @@ {% for group in group_list %} <table class='table table-compact table-striped table-bordered'><caption class='text-info'><b>{{ group.grouper }} (PK: {{group.grouper.pk}})</b></caption> - <thead><tr><th>PGR PK</th><th>Participant</th></tr></thead> + <thead><tr><th>PGR PK</th><th>Participant</th><th>Email</th></tr></thead><tbody> {% for item in group.list %} <tr><td>{{ item.participant_group_relationship.pk }}</td> - <td>{{ item.participant_group_relationship.participant_handle}} <i class='icon-resize-horizontal'></i> {{ item.participant_group_relationship.participant }}</td> + <td>{{ item.participant_group_relationship.participant_handle}}</td> + <td>{{ item.participant_group_relationship.participant.email }}</td></tr> {% endfor %} </tbody> diff -r 7e2143b407e54f8d2ea7175ce749fc640112dd5b -r e03d22dea28284c33b90585bd4731273a208dcc0 vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -348,8 +348,9 @@ def process(self): e = self.experiment + logger.debug("clearing all participants for experiment %s", e) + ParticipantExperimentRelationship.objects.filter(experiment=e).delete() e.deactivate() - ParticipantExperimentRelationship.objects.filter(experiment=e).delete() ParticipantGroupRelationship.objects.filter(group__experiment=e).delete() return e Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-04 21:15:01
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/7e2143b407e5/ Changeset: 7e2143b407e5 User: alllee Date: 2013-04-04 23:09:39 Summary: fixing clear participants logic, was deleting all the way to the Participant object Affected #: 3 files diff -r f02780c2031292693698d453715d78cbc36a12c5 -r 7e2143b407e54f8d2ea7175ce749fc640112dd5b vcweb/core/ajax.py --- a/vcweb/core/ajax.py +++ b/vcweb/core/ajax.py @@ -109,10 +109,11 @@ @experimenter_required @dajaxice_register def experiment_controller(request, pk, action=None): + experimenter = request.user.experimenter experiment = _get_experiment(request, pk) try: - response_tuples = experiment.invoke(action) - logger.debug("invoking action %s, results: %s", action, str(response_tuples)) + response_tuples = experiment.invoke(action, experimenter) + logger.debug("invoking action %s results: %s", action, str(response_tuples)) return experiment.to_json() except AttributeError as e: logger.warning("no attribute %s on experiment %s (%s)", action, experiment.status_line, e) diff -r f02780c2031292693698d453715d78cbc36a12c5 -r 7e2143b407e54f8d2ea7175ce749fc640112dd5b vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -834,9 +834,11 @@ ACCEPTABLE_ACTIONS = ('advance_to_next_round', 'end_round', 'start_round', 'move_to_previous_round', 'activate', 'deactivate', 'complete', 'restart_round', 'restart') - def invoke(self, action_name): + def invoke(self, action_name, experimenter=None): if action_name in Experiment.ACCEPTABLE_ACTIONS: - return getattr(self, action_name)() + logger.debug("experimenter %s invoking action %s", experimenter, action_name) + action = getattr(self, action_name) + return action() else: raise AttributeError("Invalid experiment action %s requested of experiment %s" % (action_name, self)) diff -r f02780c2031292693698d453715d78cbc36a12c5 -r 7e2143b407e54f8d2ea7175ce749fc640112dd5b vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -345,9 +345,14 @@ return redirect('core:monitor_experiment', pk=self.experiment.pk) class ClearParticipantsExperimentView(ExperimenterSingleExperimentView): + def process(self): - self.experiment.participant_set.all().delete() - return self.experiment + e = self.experiment + e.deactivate() + ParticipantExperimentRelationship.objects.filter(experiment=e).delete() + ParticipantGroupRelationship.objects.filter(group__experiment=e).delete() + return e + def render_to_response(self, context): return redirect('core:dashboard') Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-04 20:17:21
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/f02780c20312/ Changeset: f02780c20312 User: alllee Date: 2013-04-04 22:17:07 Summary: wording changes on experiment invitations, should parameterize frequently modified sections via ExperimentConfiguration.invitation_text and/or additional fields on Experiment/ExperimentConfiguration candidates: - start_date / end_date - earnings_text - reward_text Affected #: 2 files diff -r e910100e1061e15d4a355dfa7d5babe5a86cd310 -r f02780c2031292693698d453715d78cbc36a12c5 vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html --- a/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html +++ b/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.html @@ -2,12 +2,12 @@ Hello, </p><p> -Thanks in advance for participating in this experiment pretest. You have been randomly allocated to a group of 5, along -with four other students who are also in ASB 328. You can earn extra credit points for the course by performing actions -within the app to reduce your virtual carbon footprint. +Thanks in advance for participating in this experiment. You have been randomly allocated to a group of 5 along +with four other participants who have also signed up for this experiment. You have a chance to earn $100 by performing +actions within the experiment to reduce your virtual carbon footprint. </p><p> -To access the experiment visit <a href='https://vcweb.asu.edu/accounts/login'>https://vcweb.asu.edu/accounts/login</a> and login with the following +To access the experiment visit <a href='{{experiment.participant_url}}'>{{experiment.participant_url}}</a> and login with the following credentials: </p><table cellspacing="3" cellpadding="3"> @@ -20,16 +20,17 @@ You can reset your password at any time at <a href='https://vcweb.asu.edu/accounts/password/reset?email={{ participant.email }}'>https://vcweb.asu.edu/accounts/password/reset</a></p><p> -The experiment will run starting Monday, February 25th until midnight on Friday, March 1st. There are three levels to +The experiment will run from Monday, April 8th until midnight on Friday, April 12th. There are three levels to this experiment, and your group must reach specific average carbon footprint savings in order to advance to the next -level. This will be explained in more detail when you visit the app. +level. This will be explained in more detail when you visit the website. </p><p> -The extra credit points you can earn is based on the performance of your group: +The probability of earning $100 is based on the performance of your group: <ul> - <li> If your group completes level 3 by midnight on Wednesday, February 27th each member of your group will earn 10 points</li> - <li> If your group completes level 3 by midnight on Thursday, February 28th each member of your group will earn 8 points</li> - <li> If your group completes level 3 by midnight on Friday, March 1st, each member of your group will earn 6 points</li> - <li> If your group completes level 2 by midnight on Friday, March 1st, each member of your group will earn 4 points</li> - <li> If your group completes level 1 by midnight on Friday, March 1st, each member of your group will earn 2 points</li> + <li> If your group completes level 3 by midnight on Wednesday, April 10th, your group has a 20% chance to earn $100</li> + <li> If your group completes level 3 by midnight on Thursday, April 11th, your group has a 14% chance to earn $100</li> + <li> If your group completes level 3 by midnight on Friday, April 12th, your group has a 8% chance to earn $100</li> + <li> If your group completes level 2 by midnight on Friday, April 12th, your group has a 4% chance to earn $100</li> + <li> If your group completes level 1 by midnight on Friday, April 12th, your group has a 2% chance to earn $100</li> + <li> If your group does not complete level 1 by midnight on Friday, April 12th, your group will still have a 1% chance to earn $100</li></ul> diff -r e910100e1061e15d4a355dfa7d5babe5a86cd310 -r f02780c2031292693698d453715d78cbc36a12c5 vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt --- a/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt +++ b/vcweb/lighterprints/templates/lighterprints/email/experiment-registration.txt @@ -1,10 +1,10 @@ Hello, -Thanks in advance for participating in this experiment pretest. You have been randomly allocated to a group of 5, along -with four other students who are also in ASB 328. You can earn extra credit points for the course by performing actions -within the app to reduce your virtual carbon footprint. +Thanks in advance for participating in this experiment. You have been randomly allocated to a group of 5 along +with four other participants who have also signed up for this experiment. You have a chance to earn $100 by performing +actions within the experiment to reduce your virtual carbon footprint. -To access the experiment visit https://vcweb.asu.edu/accounts/login and login with the following credentials: +To access the experiment visit {{experiment.participant_url}} and login with the following credentials: Email: {{ participant.email }} Password: {{ password }} @@ -13,16 +13,16 @@ https://vcweb.asu.edu/accounts/password/reset?email={{ participant.email }} -The experiment will run starting Monday, February 25th until midnight on Friday, March 1st. There are three levels to + +The experiment will run from Monday, April 8th until midnight on Friday, April 12th. There are three levels to this experiment, and your group must reach specific average carbon footprint savings in order to advance to the next -level. This will be explained in more detail when you visit the app. +level. This will be explained in more detail when you visit the website. -You can earn extra credit points based on the performance of your group: +The probability of earning $100 is based on the performance of your group: -* If your group completes level 3 by midnight on Wednesday, February 27th each member of your group will earn 10 points -* If your group completes level 3 by midnight on Thursday, February 28th each member of your group will earn 8 points -* If your group completes level 3 by midnight on Friday, March 1st, each member of your group will earn 6 points -* If your group completes level 2 by midnight on Friday, March 1st, each member of your group will earn 4 points -* If your group completes level 1 by midnight on Friday, March 1st, each member of your group will earn 2 points - - + * If your group completes level 3 by midnight on Wednesday, April 10th, your group has a 20% chance to earn $100 + * If your group completes level 3 by midnight on Thursday, April 11th, your group has a 14% chance to earn $100 + * If your group completes level 3 by midnight on Friday, April 12th, your group has a 8% chance to earn $100 + * If your group completes level 2 by midnight on Friday, April 12th, your group has a 4% chance to earn $100 + * If your group completes level 1 by midnight on Friday, April 12th, your group has a 2% chance to earn $100 + * If your group does not complete level 1 by midnight on Friday, April 12th, your group will still have a 1% chance to earn $100 Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-04 04:19:18
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/e887f7713ef9/ Changeset: e887f7713ef9 User: alllee Date: 2013-04-04 06:04:58 Summary: creating initial bootstrap tour Affected #: 1 file diff -r 6a05666be5a59b5bc812866e41ca6ef02457478b -r e887f7713ef9a207597fb19e3f60d7bcec545710 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -37,7 +37,8 @@ </p><p><i class='lighterprints-green icon-leaf'></i> Earn <span class='badge badge-lighterprints-green'>green points</span> by - completing challenges. Rank up by <b>increasing your group's average score.</b>. + completing challenges. Rank up by <b>increasing your group's average score, shown in the + Today"s Progress Chart.</b>. </p><p><i class='icon-star text-gold'></i> Some challenges are unlocked all day, and others are only @@ -51,7 +52,7 @@ </div><div class='row lighterprints-scoreboard'><div class='span2'> - <h5><span class='lighterprints-scoreboard-uppercase'>Today's Score</span> + <h5 id='todays-score'><span class='lighterprints-scoreboard-uppercase'>Today's Score</span><i id='score-info' style='margin:8px 0 0 0;' rel='popover' data-trigger='hover' data-placement='top' data-content="This is your group's average score for the day. Complete high-value challenges to rank your group up." class='pull-right icon-info-sign'></i></h5><table> @@ -62,7 +63,7 @@ </table></div><div class='span2 left-divider'> - <h5><span class='lighterprints-scoreboard-uppercase'>Current Level</span></h5> + <h5 id='current-level' ><span class='lighterprints-scoreboard-uppercase'>Current Level</span></h5><div class='dashboard-content'><div data-bind='if: experimentCompleted'><img class='group-level' width='120' height='70' src='{% static "images/lighterprints/experiment-completed.png"%}'> @@ -73,7 +74,7 @@ </div></div><div class='span2 left-divider'> - <h5><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span> + <h5 id='todays-progress'><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span><i id='progress-info' style='padding: 0px 0px 0px 0px; margin: -1px 0px 0px -1px;' rel='popover' data-trigger='hover' data-placement='top' data-content='This chart shows the average group score needed to advance to the next level.' class='icon-info-sign'></i> @@ -83,7 +84,7 @@ </div></div><div class='span2 left-divider'> - <h5><span class='lighterprints-scoreboard-uppercase'>Time Remaining</span></h5> + <h5 id='time-remaining'><span class='lighterprints-scoreboard-uppercase'>Time Remaining</span></h5><table><tr><td class='lighterprints-scoreboard-xlarge'><span data-bind='text: hoursLeft'></span>h</td> @@ -95,7 +96,7 @@ <h3 class='underline'>Challenges</h3><div class='tabbable challenge-tabs'><ul class='nav nav-tabs'> - <li class='active'><a href='#unlocked-challenges' data-toggle='tab'><span class='text-gold'><i class='icon-star'></i> Unlocked</span></a></li> + <li id='unlocked-challenge-tab' class='active'><a href='#unlocked-challenges' data-toggle='tab'><span class='text-gold'><i class='icon-star'></i> Unlocked</span></a></li><li><a href='#locked-challenges' data-toggle='tab'><i class='icon-lock'></i> Locked</a></li></ul><div class='tab-content challenges'> @@ -306,6 +307,7 @@ <script src="//fast.fonts.com/jsapi/e86344be-530a-495b-be28-7a22a9cda219.js"></script><script src='{% static "js/lighterprints/model.js" %}'></script><script src='{% static "js/Chart.min.js" %}'></script> +<script src='{% static "js/bootstrap-tour.js" %}'></script><script> $(function() { // XXX: set up bootstrap nav-tabs to be semi-refresh friendly, remove in production @@ -326,6 +328,46 @@ viewModel.activateDashboardTab = activateTabFunctor('#dashboard', '#lfp-navtabs'); viewModel.activateHelpTab = activateTabFunctor('#help', '#lfp-navtabs'); viewModel.activateGroupTab = activateTabFunctor('#group', '#lfp-navtabs'); + viewModel.setup = function() { + viewModel.initializeChart(); + viewModel.setupTour(); + }; + viewModel.setupTour = function() { + var tour = new Tour(); + tour.addStep({ + element: "#todays-score", + title: "Today's Score", + placement: "top", + content: "This is your group's average score for the day. Complete high-value challenges to help your group advance to the next level." + }); + tour.addStep({ + element: "#current-level", + title: "Current Level", + placement: "top", + content: "This is your group's current level. Each level unlocks 5 new challenges. You are currently level " + viewModel.groupLevel() + "." + }); + tour.addStep({ + element: "#todays-progress", + placement: "top", + title: "Today's Progress", + content: "This chart displays your average group score in green and the total points needed to advance to the next level in gray. To advance to level 2 your group average score needs to reach 50." + }); + tour.addStep({ + element: "#time-remaining", + placement: "top", + title: "Time Remaining", + content: "The time remaining before your group progress resets at midnight. If your group doesn't earn enough points to advance to the next level by midnight, your point totals reset for the next day and you stay at the same level." + }); + tour.addStep({ + element: "#unlocked-challenge-tab", + title: "Perform Challenges", + content: "You can perform challenges by clicking on the green Perform button. The points each challenge is worth is listed on the right." + }); + if (viewModel.firstVisit()) { + tour.start(true); + } + tour.start(); + } viewModel.initializeChart = function() { var todaysProgressContext = document.getElementById("todaysProgressChart").getContext("2d"); var progressChart = new Chart(todaysProgressContext).Doughnut(viewModel.todaysProgressChartData()); @@ -398,7 +440,7 @@ }; ko.applyBindings(viewModel); // FIXME: use $('.popover').popover() if we end up having a lot more of these. - viewModel.initializeChart(); + viewModel.setup(); $('[data-content]').popover(); }); </script> https://bitbucket.org/virtualcommons/vcweb/commits/e910100e1061/ Changeset: e910100e1061 User: alllee Date: 2013-04-04 06:19:00 Summary: adding FAQ question clarifying group average. Affected #: 1 file diff -r e887f7713ef9a207597fb19e3f60d7bcec545710 -r e910100e1061e15d4a355dfa7d5babe5a86cd310 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -164,7 +164,14 @@ You can leave messages for the other members n your group via the <a href='#group' data-bind='click: activateGroupTab'>My Group tab</a> or use the <a href='#dashboard' data-bind='click:activateDashboardTab'>Dashboard</a> to view your group's progress. </p> - <h3 class='underline'>Frequently Asked Questions</h3> + <h3 id='faq' class='underline'>Frequently Asked Questions</h3> + <div class='well alert-white'> + <h4>I performed an activity worth 15 points but only 3 points were added to Today's Progress and Today's Score. Why?</h4> + <p> + The numbers in Today's Score Today's Progress represent your group's <b>average number of earned green points</b>. If there are 5 + people in your group, performing a 15 point activity adds 3 points to the group average (15 / 5 = 3). + </p> + </div><div class='well alert-white'><h4>Why do the challenges performed in the previous day not count for today?</h4><p> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-03 21:37:06
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/6a05666be5a5/ Changeset: 6a05666be5a5 User: alllee Date: 2013-04-03 23:36:49 Summary: - still need get_group_score individually for API call - adding participant link to summary email Affected #: 3 files diff -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 -r 6a05666be5a59b5bc812866e41ca6ef02457478b vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html --- a/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html +++ b/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.html @@ -1,6 +1,6 @@ <h3>Lighter Footprints Summary for {{ summary_date }}</h3><p> -You are a member of {{ group_name }}. +You are a member of {{ group_name }}. To participate in this experiment, visit <a href='{{experiment.participant_url}}'>{{experiment.participant_url}}</a>. </p><ul><li>You earned {{ individual_points }} points while the average in your group was {{ average_group_points }} point(s).</li> diff -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 -r 6a05666be5a59b5bc812866e41ca6ef02457478b vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt --- a/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt +++ b/vcweb/lighterprints/templates/lighterprints/email/group-summary-email.txt @@ -1,6 +1,7 @@ Lighter Footprints Summary for {{ summary_date }} -You are a member of {{ group_name }}. +You are a member of {{ group_name }}. To participate in this experiment, visit {{experiment.participant_url}}. + * You earned {{ individual_points }} points. The average number of points earned per person in your group was {{ average_group_points }} point(s). * {{ number_of_chat_messages }} chat messages were posted by your group. diff -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 -r 6a05666be5a59b5bc812866e41ca6ef02457478b vcweb/lighterprints/views.py --- a/vcweb/lighterprints/views.py +++ b/vcweb/lighterprints/views.py @@ -19,7 +19,7 @@ from vcweb.lighterprints.forms import ActivityForm from vcweb.lighterprints.models import (Activity, get_all_activities_tuple, do_activity, get_group_activity, can_view_other_groups, get_lighterprints_experiment_metadata, is_experiment_completed, - get_activity_performed_parameter, get_points_to_next_level, get_group_scores, get_footprint_level, + get_activity_performed_parameter, get_points_to_next_level, get_group_scores, get_group_score, get_footprint_level, get_foursquare_category_ids, get_activity_performed_counts, get_time_remaining) from collections import defaultdict Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-03 10:47:09
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/42ad7efdc49f/ Changeset: 42ad7efdc49f User: alllee Date: 2013-04-03 12:46:54 Summary: using input-block-level to stretch out chat text box but its also making the input-prepend too big (matching the span1 for the user icon below for some reason in the my group page) Affected #: 5 files diff -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -162,7 +162,7 @@ cv = cache.get(ck) if cv is None: if self.available_all_day: - cv = 'available all day' + cv = 'all day' else: cv = ','.join([availability.time_slot for availability in self.availability_set.all()]) cache.set(ck, cv) @@ -453,7 +453,7 @@ return get_group_score(group, start=start, end=end, round_data=round_data)[0] # returns a tuple of (dict of group -> {average_group_points, total_group_points}, total_participant_points) -def get_group_scores(round_data, participant_group_relationship=None, start=None, end=None): +def get_group_scores(experiment, round_data, participant_group_relationship=None, start=None, end=None): activity_points_cache = get_activity_points_cache() # establish date range # grab all of yesterday's participant data values, starting at 00:00:00 (midnight) @@ -471,7 +471,8 @@ group_scores[activity_performed_dv.participant_group_relationship.group]['total_group_points'] += activity_points if participant_group_relationship and activity_performed_dv.participant_group_relationship == participant_group_relationship: total_participant_points += activity_points - for group, group_data_dict in group_scores.items(): + for group in experiment.groups: + group_data_dict = group_scores[group] group_size = group.size total_group_points = group_data_dict['total_group_points'] average = total_group_points / group_size @@ -480,8 +481,8 @@ return (group_scores, total_participant_points) -# returns a tuple of the average points per person and the total points for -# the given group +# FIXME: reduce code duplication here and get_group_scores +# returns a tuple of the average points per person and the total points for the given group def get_group_score(group, start=None, end=None, participant_group_relationship=None, round_data=None, **kwargs): # cache activity points activity_points_cache = get_activity_points_cache() diff -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 vcweb/lighterprints/static/css/lighterprints/style.css --- a/vcweb/lighterprints/static/css/lighterprints/style.css +++ b/vcweb/lighterprints/static/css/lighterprints/style.css @@ -1,174 +1,27 @@ body { background-color: #F7F7F7; } -/* navbar css from fervor -.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { - -webkit-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; - -moz-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; - box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; +h2.welcome-header { + font-weight: normal; + font-size: 1.3em; } -.navbar-fixed-top .navbar-inner, .navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - border-width: 0 0 0px; +.welcome-message { + border-radius: 0px; + -webkit-border-radius: 0px; + border: none; + border-bottom: 1px solid #e1e6e9 !important; } -.navbar-inner { - min-height: 64px; - padding-left: 20px; - padding-right: 20px; - background-color: #009fe1; - background-image: -moz-linear-gradient(top, #29afee, #009fe1); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#29afee), to(#009fe1)); - background-image: -webkit-linear-gradient(top, #29afee, #009fe1); - background-image: -o-linear-gradient(top, #29afee, #009fe1); - background-image: linear-gradient(to bottom, #29afee, #009fe1); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#29afee', endColorstr='#009fe1', GradientType=0); - border-bottom: 1px solid #0089bb; - border-top: 1px solid #87d7f7; +.leaderboard-group-name { + font-family:"Lucida Grande", "Open Sans"; + font-size: 1em; } -.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { - border-width: 0 0 0px; +h4.challenge-name { + font-size: 1.3em; } -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; - border: 0; +.challenge-tabs { + font-family: "Lucida Grande", sans-serif; + font-size: 1em; } -.navbar .nav > li > a { - float: none; - padding: 20px 27px 20px 25px; - color: #ffffff; - text-decoration: none; - -webkit-font-smoothing: antialiased; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-right: 1px solid rgb(5, 150, 204); - box-shadow: 1px 0 0 rgb(24, 193, 255); -} -.navbar .brand { - float: left; - display: block; - padding: 17px 25px 0px !important; - margin-left: -20px; - font-size: 22px; - font-weight: 200; - color: #777777; - text-shadow: 0 1px 1px #0196cd; - border: 0 !important; - box-shadow: none !important; -} -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 22px; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; - font-weight: bold; -} -.navbar .nav > li > a:focus, .navbar .nav > li > a:hover { - background-color: transparent; - color: #bee3f3; - text-decoration: none; - cursor: pointer; -} -.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus { - color: #b9ed2e; - text-decoration: none; - background-color: #42555e; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-top: 1px solid #42555e; - border-bottom: 1px solid #42555e; - text-shadow: 0 0 5px rgba(149, 203, 41, 0.25); -} -.nav-tabs > .active > a, .nav-tabs > .active > a:hover, .nav-tabs > .active > a:focus { - color: #555555; - background-color: #ffffff; - border-bottom: 1px solid #42555e; - border-bottom-color: transparent; - cursor: pointer; - border-top: 1px solid #42555e; -} -.navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #42555e; - color: #ffffff; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, .navbar .nav li.dropdown.active > .dropdown-toggle .caret, .navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} -.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:1em;font-size:1.3em}li [class^="icon-"],.nav li [class^="icon-"],li [class*=" icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 16px 10px; - margin: 25px 0 0; - list-style: none; - background-color: #ffffff; - -webkit-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.dropdown-menu > li > a { - display: block; - padding: 5px 20px; - clear: both; - font-weight: normal; - line-height: 20px; - color: #333333; - white-space: nowrap; - font-size: 12px; - font-family: 'Lucida Grande'; -} -.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { - text-decoration: none; - color: #13a6e7; -} -.icon-cog { - background-position: -432px 0; - font-size: 1.5em; - color: #bee3f3; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #bee3f3; - border-bottom-color: #bee3f3; -} -.dropdown .caret { - margin-top: 8px; - margin-left: 10px; -} -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 7px solid #000000; - border-right: 5px solid transparent; - border-left: 5px solid transparent; - content: ""; -} -*/ .challenge-tabs > .nav-tabs > .active > a, .challenge-tabs > .nav-tabs > .active > a:hover { border-top: 3px solid #DFB03D; border-bottom: none; @@ -256,13 +109,13 @@ } .lighterprints-scoreboard-large { font-size: 3em; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; - color: #666666; + font-family: 'TrumpGothicWestW01-Medi', sans-serif; + color: #42555e; } .lighterprints-scoreboard-xlarge { font-size: 4.6em; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; - color: #666666; + font-family: 'TrumpGothicWestW01-Medi', sans-serif; + color: #42555e; } div.lighterprints-scoreboard h1 { font-size: 5em; @@ -286,6 +139,9 @@ .dashboard-content { margin-top: -3px; } +.lighterprints-dark-gray { + color: #42555e; +} .lighterprints-gray { color: #D0D0D0; } @@ -311,9 +167,8 @@ color: #FFFFFF; } .btn-lighterprints-blue { - background-color: hsl(197, 89%, 37%) !important; + background-color: #13a6e7 !important; background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#39bef3", endColorstr="#0a82b2"); background-image: -khtml-gradient(linear, left top, left bottom, from(#39bef3), to(#0a82b2)); background-image: -moz-linear-gradient(top, #39bef3, #0a82b2); background-image: -ms-linear-gradient(top, #39bef3, #0a82b2); @@ -360,6 +215,11 @@ td.group-activity-icon { padding-right: 2px; } +.group-activity { + font-family: "Lucida Grande", sans-serif; + font-size: .9em; + +} td.group-activity { padding-left: 2px; } diff -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -27,9 +27,9 @@ </div></div><div style='display: none;' data-bind='visible: ! experimentCompleted()'> - <div class='alert alert-block alert-white'> + <div class='alert alert-block alert-white welcome-message'><button type="button" class="close" data-dismiss="alert"><i class='icon-remove-sign'></i></button> - <h2 class='muted'>Welcome to Lighter Footprints, <i class='lighterprints-blue'><span data-bind='text: groupName'></span>!</i></h2> + <h2 class='welcome-header lighterprints-dark-gray'>Welcome to Lighter Footprints, <i class='lighterprints-blue'><span data-bind='text: groupName'></span>!</i></h2><p> You have been randomly placed in a group of {{ participant_group_relationship.group.size }} participants. In this experiment you can perform virtual actions that represent green alternatives @@ -187,13 +187,12 @@ <div class='tab-pane' id='group'><h1 class='header'><i class='icon-comment'></i> My Group</h1><h3 class='underline'>Group Chat</h3> - <form class='form-inline' id='chat-form' data-bind='submit: submitChatMessage'> - <div style='width: 90%;' class='input-prepend'> + <form id='chat-form' data-bind='submit: submitChatMessage'> + <div class='input-prepend input-block-level'> + <input type='hidden' name='participant_group_id' value='{{participant_group_relationship.id}}'/><span class='add-on'><i class='icon-comment'></i></span> - <input style='width: 90%;' type='text' id='chatText' name='message' placeholder='Send a message to your group' /> + <input type='text' id='chatText' name='message' placeholder='Send a message to your group' /></div> - <button class='btn btn-lighterprints-blue' data-bind='click: submitChatMessage'>Send</button> - <input type='hidden' name='participant_group_id' value='{{participant_group_relationship.id}}'/></form><div class='well alert-white scrollable-messages'><div data-bind='ifnot: hasChatMessages() '> @@ -212,7 +211,7 @@ </p></div><div class='span1'> - <b class='pull-right'><span data-bind='text: date_created'></span> ago</b> + <span class='pull-right'><span data-bind='text: date_created'></span> ago</span></div></div></div> @@ -276,7 +275,7 @@ {% if compare_other_group %} <h3 class='lighterprints-sidebar-header'><i class='text-gold icon-trophy'></i> Leaderboard</h3><ul class='nav nav-list' data-bind='foreach: groupData'> - <li><strong>#<span data-bind='text:$index() + 1'></span></strong><span data-bind='css: { "bold lighterprints-blue": groupName() == $root.groupName()}'><span data-bind='text: groupName'></span></span><span class='pull-right badge badge-lighterprints-green' data-bind='text: averagePoints'></span></li> + <li class='leaderboard-group-name'><strong>#<span data-bind='text:$index() + 1'></span></strong><span data-bind='css: { "bold lighterprints-blue": groupName() == $root.groupName()}'><span data-bind='text: groupName'></span></span><span class='pull-right badge badge-lighterprints-green' data-bind='text: averagePoints'></span></li><li class='divider'></li></ul> {% endif %} @@ -284,7 +283,7 @@ <div data-bind='ifnot: hasGroupActivity()'><div data-bind='template: { name: "no-group-activity-template" }'></div></div> - <table class='table'> + <table class='table group-activity'><tbody data-bind='template: { name: groupActivityTemplate, foreach: groupActivity.slice(0, 6) }'></tbody></table> @@ -508,9 +507,9 @@ <img style='padding: 10px 0 0 20px;' data-bind='attr: {src: "{% static 'images/lighterprints/badges/' %}" + name() + ".png" }'></div><div class='span4'> - <h4 data-bind='css: status, text:display_name'></h4> + <h4 class='challenge-name' data-bind='css: status, text:display_name'></h4><p> - <span data-bind='css: status, text:summary'></span> + <span data-bind='css: status, text: summary'></span></p><form data-bind='attr: { id: "challengeForm" + pk() }' class='form-horizontal' method='post'><input data-bind='value: pk' type='hidden' name='activity_id' /> @@ -527,11 +526,14 @@ {% endcomment %} </form></div> - <div style='padding: 15px 0;' class='span2'> + <div style='margin-top: 10px; padding: 15px 0;' class='span2'><table> - <tr><td><span class='lighterprints-scoreboard-large' data-bind='text:points'></td><td style='text-align: center;'><i class='icon-leaf lighterprints-green'></i></td></tr> + <tr> + <td class='lighterprints-scoreboard-xlarge'><span data-bind='text: points'></span></td> + <td><i class='lighterprints-green icon-leaf icon-2x'></i></td> + </tr></table> - <div data-bind='css: status'><i class='icon-time'></i><strong><span data-bind='text: time_slots'></span></strong></div> + <div style='margin-top: 5px; padding: 5px 0;' data-bind='css: status'><i class='icon-time'></i><strong><span data-bind='text: time_slots'></span></strong></div></div></div></div> diff -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 vcweb/lighterprints/views.py --- a/vcweb/lighterprints/views.py +++ b/vcweb/lighterprints/views.py @@ -331,10 +331,10 @@ round_data = experiment.current_round_data compare_other_group = can_view_other_groups(round_configuration=round_configuration) group_data = [] - (group_scores, total_participant_points) = get_group_scores(round_data, participant_group_relationship=participant_group_relationship) + (group_scores, total_participant_points) = get_group_scores(experiment, round_data, participant_group_relationship=participant_group_relationship) for group, group_data_dict in group_scores.items(): - average_points = group_data_dict['average_points'] + average_points = group_data_dict['average_group_points'] total_points = group_data_dict['total_group_points'] group_level = get_footprint_level(group, round_data=round_data) points_to_next_level = get_points_to_next_level(group_level) diff -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb -r 42ad7efdc49fbad3867bacb8b46ce37e6ba2f0c8 vcweb/static/css/style.css --- a/vcweb/static/css/style.css +++ b/vcweb/static/css/style.css @@ -41,9 +41,6 @@ overflow: auto; margin-bottom: 10px; } -#chatText { - width: 65%; -} .chat-message { margin-bottom: 5px; } Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-03 09:39:43
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/8b493168a7f7/ Changeset: 8b493168a7f7 User: alllee Date: 2013-04-03 11:39:24 Summary: query optimization, replacing get_group_score with get_group_scores which iterates over all activity performed participant round data values for the given round Affected #: 5 files diff -r 70ad0836180c56cb3013e55118bdf8619ce23493 -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1973,6 +1973,14 @@ 'target_data_value__participant_group_relationship', ).filter(participant_group_relationship=participant_group_relationship, is_active=True, **kwargs).order_by('-date_created') + def for_round(self, round_data=None, **kwargs): + if round_data is None: + raise ValueError("Must specify a round data object in this query") + return self.select_related( + 'parameter', + 'participant_group_relationship__group' + ).filter(round_data=round_data, is_active=True, **kwargs) + def for_group(self, group=None, **kwargs): if group is None: raise ValueError("Must specify a group in this query") diff -r 70ad0836180c56cb3013e55118bdf8619ce23493 -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -13,7 +13,7 @@ from vcweb.core import signals, simplecache, enum from vcweb.core.models import (Experiment, ExperimentMetadata, GroupRoundDataValue, RoundParameterValue, ParticipantGroupRelationship, ParticipantRoundDataValue, Parameter, User, Comment, Like, ChatMessage) from vcweb.core.services import fetch_foursquare_categories -import collections +from collections import defaultdict from datetime import datetime, date, time, timedelta from mptt.models import MPTTModel, TreeForeignKey, TreeManager from lxml import etree @@ -279,7 +279,7 @@ upcoming_activities = Activity.objects.upcoming(level=group_level) # XXX: data value's int_value stores the fk directly, using .value does a fk lookup to restore the full entity # which we don't need - performed_activity_ids = [padv.int_value for padv in performed_activity_data_values] + performed_activity_ids = performed_activity_data_values.values_list('int_value', flat=True) available_activity_ids = [activity.pk for activity in available_activities if activity.pk not in performed_activity_ids] upcoming_activity_ids = [activity.pk for activity in upcoming_activities] status_dict = {} @@ -314,7 +314,7 @@ def get_activity_availability_cache(): aac = cache.get('activity_availability_cache') if aac is None: - aac = collections.defaultdict(list) + aac = defaultdict(list) for aa in ActivityAvailability.objects.select_related('activity').all(): aac[aa.activity.pk].append(aa) cache.set('activity_availability_cache', aac) @@ -452,10 +452,38 @@ def average_points_per_person(group, start=None, end=None, round_data=None): return get_group_score(group, start=start, end=end, round_data=round_data)[0] -# cache activity points +# returns a tuple of (dict of group -> {average_group_points, total_group_points}, total_participant_points) +def get_group_scores(round_data, participant_group_relationship=None, start=None, end=None): + activity_points_cache = get_activity_points_cache() + # establish date range + # grab all of yesterday's participant data values, starting at 00:00:00 (midnight) + total_participant_points = 0 + if start is None: + start = date.today() + if end is None: + end = start + timedelta(1) + if round_data is None: + round_data = group.current_round_data + group_scores = defaultdict(lambda: defaultdict(lambda: 0)) + activities_performed_qs = ParticipantRoundDataValue.objects.for_round(round_data=round_data, parameter=get_activity_performed_parameter(), date_created__range=(start, end)) + for activity_performed_dv in activities_performed_qs: + activity_points = activity_points_cache[activity_performed_dv.int_value] + group_scores[activity_performed_dv.participant_group_relationship.group]['total_group_points'] += activity_points + if participant_group_relationship and activity_performed_dv.participant_group_relationship == participant_group_relationship: + total_participant_points += activity_points + for group, group_data_dict in group_scores.items(): + group_size = group.size + total_group_points = group_data_dict['total_group_points'] + average = total_group_points / group_size + group_data_dict['average_group_points'] = average + logger.debug("total carbon savings: %s divided by %s members = %s per person", total_group_points, group_size, average) + return (group_scores, total_participant_points) + + # returns a tuple of the average points per person and the total points for # the given group def get_group_score(group, start=None, end=None, participant_group_relationship=None, round_data=None, **kwargs): + # cache activity points activity_points_cache = get_activity_points_cache() # establish date range # grab all of yesterday's participant data values, starting at 00:00:00 (midnight) @@ -470,7 +498,6 @@ activities_performed_qs = ParticipantRoundDataValue.objects.for_group(group, parameter=get_activity_performed_parameter(), round_data=round_data, date_created__range=(start, end)) for activity_performed_dv in activities_performed_qs: - logger.debug("checking activity performed: %s", activity_performed_dv) activity_points = activity_points_cache[activity_performed_dv.int_value] total_group_points += activity_points if activity_performed_dv.participant_group_relationship == participant_group_relationship: diff -r 70ad0836180c56cb3013e55118bdf8619ce23493 -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -323,16 +323,20 @@ var viewModelData = $.parseJSON("{{ view_model_json|escapejs }}"); var viewModel = new LighterFootprintsModel(viewModelData); // custom view model methods, some of these may be lifted into the model itself - var ctx = document.getElementById("todaysProgressChart").getContext("2d"); - var data = [ - { value: viewModel.averagePoints(), color: "#95CB29" }, - { value: viewModel.pointsToNextLevel(), color: "#D0D0D0" }, - ] - var progressChart = new Chart(ctx).Doughnut(data); viewModel.activateChallengesTab = activateTabFunctor('#challenges', '#lfp-navtabs'); viewModel.activateDashboardTab = activateTabFunctor('#dashboard', '#lfp-navtabs'); viewModel.activateHelpTab = activateTabFunctor('#help', '#lfp-navtabs'); viewModel.activateGroupTab = activateTabFunctor('#group', '#lfp-navtabs'); + viewModel.initializeChart = function() { + var todaysProgressContext = document.getElementById("todaysProgressChart").getContext("2d"); + var progressChart = new Chart(todaysProgressContext).Doughnut(viewModel.todaysProgressChartData()); + }; + viewModel.todaysProgressChartData = ko.computed(function() { + return [ + { value: viewModel.averagePoints(), color: "#95CB29" }, + { value: viewModel.pointsToNextLevel(), color: "#D0D0D0" }, + ] + }); viewModel.postComment = function(targetModel) { var formData = $('#commentForm' + targetModel.pk()).serialize(); $('.comment-popover').popover('hide'); @@ -355,28 +359,36 @@ targetModel.liked(data.success); }); }; + // FIXME: manually manipulating DOM elements via JQuery feels a bit hacky mixed in with KO's data binding + viewModel.showActivityPerformedModal = function() { + $('#activityPerformedModal .progress').removeClass('hide'); + $('#activityPerformedModalText').addClass('hide'); + $('#activityPerformedModal .btn').addClass('disabled'); + $('#activityPerformedModal').modal(); + }; + viewModel.hideActivityPerformedModal = function() { + $('#activityPerformedModal .progress').addClass('hide'); + $('#activityPerformedModalText').removeClass('hide'); + $('#activityPerformedModal .btn').removeClass('disabled'); + } viewModel.perform = function(challengeModel) { if (! challengeModel.availableNow()) { // FIXME: modal is slow, no feedback on this for now // model.errorMessage("The activity " + activityModel.display_name() + " is not currently available."); // $('#activityUnavailableModal').modal(); + console.debug("tried to perform an activity that's not available right now"); + console.debug(challengeModel); return; } - // FIXME: manually manipulating DOM elements via JQuery feels dirty when mixed in with KO's data binding - $('#activityPerformedModal .progress').removeClass('hide'); - $('#activityPerformedModalText').addClass('hide'); - $('#activityPerformedModal .btn').addClass('disabled'); - $('#activityPerformedModal').modal(); + viewModel.showActivityPerformedModal(); var id = challengeModel.pk(); var formData = $('#challengeForm' + id).serialize(); $.post('/lighterprints/api/do-activity', formData, function(data) { if (data.success) { ko.mapping.fromJSON(data.viewModel, viewModel); viewModel.lastPerformedActivity(challengeModel); - // FIXME: find a better way to handle this? - $('#activityPerformedModal .progress').addClass('hide'); - $('#activityPerformedModalText').removeClass('hide'); - $('#activityPerformedModal .btn').removeClass('disabled'); + viewModel.hideActivityPerformedModal(); + viewModel.initializeChart(); } else { console.debug("ERROR: " + data.message); @@ -387,6 +399,7 @@ }; ko.applyBindings(viewModel); // FIXME: use $('.popover').popover() if we end up having a lot more of these. + viewModel.initializeChart(); $('[data-content]').popover(); }); </script> diff -r 70ad0836180c56cb3013e55118bdf8619ce23493 -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb vcweb/lighterprints/views.py --- a/vcweb/lighterprints/views.py +++ b/vcweb/lighterprints/views.py @@ -19,7 +19,7 @@ from vcweb.lighterprints.forms import ActivityForm from vcweb.lighterprints.models import (Activity, get_all_activities_tuple, do_activity, get_group_activity, can_view_other_groups, get_lighterprints_experiment_metadata, is_experiment_completed, - get_activity_performed_parameter, get_points_to_next_level, get_group_score, get_footprint_level, + get_activity_performed_parameter, get_points_to_next_level, get_group_scores, get_footprint_level, get_foursquare_category_ids, get_activity_performed_counts, get_time_remaining) from collections import defaultdict @@ -331,11 +331,15 @@ round_data = experiment.current_round_data compare_other_group = can_view_other_groups(round_configuration=round_configuration) group_data = [] - for group in experiment.groups: - (average_points, total_points, total_participant_points) = get_group_score(group, participant_group_relationship=participant_group_relationship, round_data=round_data) + (group_scores, total_participant_points) = get_group_scores(round_data, participant_group_relationship=participant_group_relationship) + + for group, group_data_dict in group_scores.items(): + average_points = group_data_dict['average_points'] + total_points = group_data_dict['total_group_points'] group_level = get_footprint_level(group, round_data=round_data) points_to_next_level = get_points_to_next_level(group_level) if group == own_group: + # FIXME: hacky own_group_level = group_level own_average_points = average_points own_points_to_next_level = points_to_next_level @@ -345,7 +349,6 @@ 'groupSize': group.size, 'averagePoints': average_points, 'totalPoints': total_points, - 'totalParticipantPoints': total_participant_points, 'pointsToNextLevel': points_to_next_level }) group_data.sort(key=itemgetter('averagePoints'), reverse=True) @@ -371,6 +374,7 @@ 'groupActivity': team_activity, 'groupName': own_group.name, 'activities': activity_dict_list, + 'totalParticipantPoints': total_participant_points, 'activitiesByLevel': level_activity_list }) diff -r 70ad0836180c56cb3013e55118bdf8619ce23493 -r 8b493168a7f748a74eddd2f6a16681a8bb6167bb vcweb/requirements.pip --- a/vcweb/requirements.pip +++ b/vcweb/requirements.pip @@ -26,6 +26,7 @@ # FIXME: this will fail on Mac OS X, see http://lxml.de/installation.html#macos-x for workarounds. # easiest is to use MacPorts, sudo port install py27-lxml beforehand to set up the appropriate xml libraries lxml +django-debug-toolbar # XXX: disabled packages #celery #tornadio Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-03 08:09:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/70ad0836180c/ Changeset: 70ad0836180c User: alllee Date: 2013-04-03 10:09:27 Summary: moving static assets into per-app static directories instead Affected #: 50 files diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/boundaries/static/css/boundaries/style.css --- /dev/null +++ b/vcweb/boundaries/static/css/boundaries/style.css @@ -0,0 +1,28 @@ +.chat-sidebar { + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + padding: 0px 0px 0px 0px; + margin: 0px; +} +.chat-messages { + padding: 5px; +} +#chat-div { + overflow: auto; + height: 820px; +} +#chatMessage { +} +.boundaries-status-dashboard p { + padding-top: 15px; + font-size: 2em; +} +.boundaries-status-dashboard h4 { + border-bottom: 1px solid #ccc; +} +.boundaries-status-dashboard { + height: 100px; + width: 110px; + margin-right: 0px; + padding: 8px 8px 8px 8px; +} diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/css/lighterprints/style.css --- /dev/null +++ b/vcweb/lighterprints/static/css/lighterprints/style.css @@ -0,0 +1,372 @@ +body { + background-color: #F7F7F7; +} +/* navbar css from fervor +.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { + -webkit-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; + -moz-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; + box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; +} +.navbar-fixed-top .navbar-inner, .navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + border-width: 0 0 0px; +} +.navbar-inner { + min-height: 64px; + padding-left: 20px; + padding-right: 20px; + background-color: #009fe1; + background-image: -moz-linear-gradient(top, #29afee, #009fe1); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#29afee), to(#009fe1)); + background-image: -webkit-linear-gradient(top, #29afee, #009fe1); + background-image: -o-linear-gradient(top, #29afee, #009fe1); + background-image: linear-gradient(to bottom, #29afee, #009fe1); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#29afee', endColorstr='#009fe1', GradientType=0); + border-bottom: 1px solid #0089bb; + border-top: 1px solid #87d7f7; +} +.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { + border-width: 0 0 0px; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; + border: 0; +} +.navbar .nav > li > a { + float: none; + padding: 20px 27px 20px 25px; + color: #ffffff; + text-decoration: none; + -webkit-font-smoothing: antialiased; + border-radius: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-right: 1px solid rgb(5, 150, 204); + box-shadow: 1px 0 0 rgb(24, 193, 255); +} +.navbar .brand { + float: left; + display: block; + padding: 17px 25px 0px !important; + margin-left: -20px; + font-size: 22px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 1px #0196cd; + border: 0 !important; + box-shadow: none !important; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 22px; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; + font-weight: bold; +} +.navbar .nav > li > a:focus, .navbar .nav > li > a:hover { + background-color: transparent; + color: #bee3f3; + text-decoration: none; + cursor: pointer; +} +.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus { + color: #b9ed2e; + text-decoration: none; + background-color: #42555e; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + border-radius: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-top: 1px solid #42555e; + border-bottom: 1px solid #42555e; + text-shadow: 0 0 5px rgba(149, 203, 41, 0.25); +} +.nav-tabs > .active > a, .nav-tabs > .active > a:hover, .nav-tabs > .active > a:focus { + color: #555555; + background-color: #ffffff; + border-bottom: 1px solid #42555e; + border-bottom-color: transparent; + cursor: pointer; + border-top: 1px solid #42555e; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #42555e; + color: #ffffff; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, .navbar .nav li.dropdown.active > .dropdown-toggle .caret, .navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:1em;font-size:1.3em}li [class^="icon-"],.nav li [class^="icon-"],li [class*=" icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 16px 10px; + margin: 25px 0 0; + list-style: none; + background-color: #ffffff; + -webkit-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); + box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu > li > a { + display: block; + padding: 5px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; + font-size: 12px; + font-family: 'Lucida Grande'; +} +.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { + text-decoration: none; + color: #13a6e7; +} +.icon-cog { + background-position: -432px 0; + font-size: 1.5em; + color: #bee3f3; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #bee3f3; + border-bottom-color: #bee3f3; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 10px; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 7px solid #000000; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + content: ""; +} +*/ +.challenge-tabs > .nav-tabs > .active > a, .challenge-tabs > .nav-tabs > .active > a:hover { + border-top: 3px solid #DFB03D; + border-bottom: none; +} +.challenge-tabs > .nav-tabs > li > a { + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; + border-bottom: none; + color: #A9A9A9; +} +.challenge-row { + padding: 20px 0 20px 0; + border-bottom: 1px solid #ddd; +} +.challenges { + margin-top: -20px; + background-color: #FFFFFF; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; +} +..expired-challenge { + color: red; +} +a.upcoming-challenge, a.expired-challenge, a.perform-challenge, a.completed-challenge { + text-transform: uppercase; + color: #FFF !important; + -webkit-font-smoothing: antialiased; + background-repeat: repeat-x; +} +a.upcoming-challenge { + background-color: hsl(0, 0%, 54%) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#f4f4f4", endColorstr="#898989"); + background-image: -khtml-gradient(linear, left top, left bottom, from(#f4f4f4), to(#898989)); + background-image: -moz-linear-gradient(top, #f4f4f4, #898989); + background-image: -ms-linear-gradient(top, #f4f4f4, #898989); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4f4f4), color-stop(100%, #898989)); + background-image: -webkit-linear-gradient(top, #f4f4f4, #898989); + background-image: -o-linear-gradient(top, #f4f4f4, #898989); + background-image: linear-gradient(#f4f4f4, #898989); + border-color: #898989 #898989 hsl(0, 0%, 43.5%); + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.69); +} +a.expired-challenge { + background-color: hsl(0, 100%, 79%) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffbcbc", endColorstr="#ff9393"); + background-image: -khtml-gradient(linear, left top, left bottom, from(#ffbcbc), to(#ff9393)); + background-image: -moz-linear-gradient(top, #ffbcbc, #ff9393); + background-image: -ms-linear-gradient(top, #ffbcbc, #ff9393); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffbcbc), color-stop(100%, #ff9393)); + background-image: -webkit-linear-gradient(top, #ffbcbc, #ff9393); + background-image: -o-linear-gradient(top, #ffbcbc, #ff9393); + background-image: linear-gradient(#ffbcbc, #ff9393); + border-color: #ff9393 #ff9393 hsl(0, 100%, 77%); + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.13); +} +a.perform-challenge,a.completed-challenge { + background-color: hsl(96, 81%, 42%) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#66dd17", endColorstr="#59c114"); + background-image: -khtml-gradient(linear, left top, left bottom, from(#66dd17), to(#59c114)); + background-image: -moz-linear-gradient(top, #66dd17, #59c114); + background-image: -ms-linear-gradient(top, #66dd17, #59c114); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #66dd17), color-stop(100%, #59c114)); + background-image: -webkit-linear-gradient(top, #66dd17, #59c114); + background-image: -o-linear-gradient(top, #66dd17, #59c114); + background-image: linear-gradient(#66dd17, #59c114); + border-color: #59c114 #59c114 hsl(96, 81%, 40.5%); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.09); +} +h1.header { + font-family:"Open Sans"; + font-size:1.8em; + font-weight: normal; + line-height:133%; + color:rgb(201,205,209); + text-align:left; + padding: 10px 0px 5px 0px; + /* Firefox v4.0+ , Safari v5.1+ , Chrome v10.0+, IE v10+ and by Opera v10.5+ */ + text-shadow:0px 1px 1px rgb(255,255,255); + -ms-filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true)";zoom:1; + filter:progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true); +} +div.lighterprints-scoreboard { + color: #A9A9A9; +} +.lighterprints-scoreboard-large { + font-size: 3em; + font-family: 'TrumpGothicWestW01-Bold', sans-serif; + color: #666666; +} +.lighterprints-scoreboard-xlarge { + font-size: 4.6em; + font-family: 'TrumpGothicWestW01-Bold', sans-serif; + color: #666666; +} +div.lighterprints-scoreboard h1 { + font-size: 5em; + color: #666666; + font-family: 'TrumpGothicWestW01-Bold', sans-serif; +} +div.lighterprints-scoreboard h2 { + font-size: 4em; + color: #666666; + font-family: 'TrumpGothicWestW01-Bold', sans-serif; +} +div.lighterprints-scoreboard h5 { + padding-bottom: 15px; +} +h3.popover-title { + font-weight: bolder; +} +.chart { + margin-top: -25px; +} +.dashboard-content { + margin-top: -3px; +} +.lighterprints-gray { + color: #D0D0D0; +} +.comment:hover, .commented { + color: #13a5e6; + text-decoration: none; +} +.like:hover, .liked { + color: #FF0066; + text-decoration: none; +} +.lighterprints-red { + color: #FF0066; +} +.lighterprints-blue { + color: #13a5e6; +} +.lighterprints-green { + color: #95CB29; +} +.badge-lighterprints-green { + background-color: #95CB29; + color: #FFFFFF; +} +.btn-lighterprints-blue { + background-color: hsl(197, 89%, 37%) !important; + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#39bef3", endColorstr="#0a82b2"); + background-image: -khtml-gradient(linear, left top, left bottom, from(#39bef3), to(#0a82b2)); + background-image: -moz-linear-gradient(top, #39bef3, #0a82b2); + background-image: -ms-linear-gradient(top, #39bef3, #0a82b2); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #39bef3), color-stop(100%, #0a82b2)); + background-image: -webkit-linear-gradient(top, #39bef3, #0a82b2); + background-image: -o-linear-gradient(top, #39bef3, #0a82b2); + background-image: linear-gradient(#39bef3, #0a82b2); + border-color: #0a82b2 #0a82b2 hsl(197, 89%, 31.5%); + color: #fff !important; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.36); + -webkit-font-smoothing: antialiased; +} +.lighterprints-scoreboard-uppercase { + letter-spacing:1pt; + line-height:187%; + color:rgb(65,85,93); + /* Firefox v4.0+ , Safari v5.1+ , Chrome v10.0+, IE v10+ and by Opera v10.5+ */ + text-shadow:0px 1px 1px rgb(255,255,255); + -ms-filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true)";zoom:1; + filter:progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true); + font-size: 1.2em; + font-weight: normal; + padding-bottom: 15px; + text-transform: uppercase; +} +.sidebar { + min-height: 100%; + background-color: #FFFFFF; +} +.lighterprints-sidebar { + padding: 10px 20px 10px 20px; +} +.lighterprints-leaderboard { + font-weight: normal; + color: #41555d; +} +.group-level { + margin-top: -15px; + vertical-align: top; +} +h3.underline { + font-weight: normal; +} +td.group-activity-icon { + padding-right: 2px; +} +td.group-activity { + padding-left: 2px; +} +a { + color:#0088cc; + text-decoration:none; + -webkit-transition: color 180ms ease-in; + -moz-transition: color 180ms ease-in; + transition: color 180ms ease-in; +} diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/adjust-thermostat.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/adjust-thermostat.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/air-dry-clothes.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/air-dry-clothes.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/bike-or-walk.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/bike-or-walk.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/cold-water-wash.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/cold-water-wash.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/computer-off-night.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/computer-off-night.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/eat-green-lunch.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/eat-green-lunch.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/eat-local-lunch.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/eat-local-lunch.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/enable-sleep-on-computer.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/enable-sleep-on-computer.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/lights-off.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/lights-off.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/no-beef.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/no-beef.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/recycle-materials.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/recycle-materials.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/recycle-paper.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/recycle-paper.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/share-your-ride.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/share-your-ride.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/sprites.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/sprites.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/vegan-for-a-day.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/vegan-for-a-day.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/badges/water-off-while-brushing-teeth.png Binary file vcweb/lighterprints/static/images/lighterprints/badges/water-off-while-brushing-teeth.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/experiment-completed.png Binary file vcweb/lighterprints/static/images/lighterprints/experiment-completed.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/logo.png Binary file vcweb/lighterprints/static/images/lighterprints/logo.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/rank1.png Binary file vcweb/lighterprints/static/images/lighterprints/rank1.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/rank2.png Binary file vcweb/lighterprints/static/images/lighterprints/rank2.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/images/lighterprints/rank3.png Binary file vcweb/lighterprints/static/images/lighterprints/rank3.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/js/lighterprints/mobile/controller.js --- /dev/null +++ b/vcweb/lighterprints/static/js/lighterprints/mobile/controller.js @@ -0,0 +1,262 @@ +var participant_group_id; +var plot1; +var globalViewModel; + +//Model for details of the current activities used in home page and activity detail page +/* +function LighterFootprintsModel(modelJson) { + var self = this; + var model = ko.mapping.fromJS(modelJson); + // FIXME: hacky, figure out if there is a way to pass the observable in directly from the model object we get in + // performActivity + model.lastPerformedActivity = ko.observable(); + model.lastPerformedActivityPoints = ko.observable(); + model.errorMessage = ko.observable(); + model.hasChatMessages = function() { + return model.chatMessages().length > 0; + } + + model.submitChatMessage = function() { + var formData = "participant_group_id="+participant_group_id+"&"; + formData += $('#chat-form').serialize(); + $.post('http://vcweb.asu.edu/lighterprints/api/message', formData, function(data) { + ko.mapping.fromJS(data, model); + $('#groupPageMessageList').listview('refresh'); + }); + $('#chatText').val(''); + return false; + }; + + model.availableActivities = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { return activity.available_now() }); + }); + + model.availableL1 = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { + console.log(activity.level()); + if (activity.level() == '1') return true; + }); + }); + + model.availableL2 = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { + console.log(activity.level()); + if (activity.level() == '2') return true; + }); + }); + + model.availableL3 = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { + console.log(activity.level()); + if (activity.level() == '3') return true; + }); + }); + + model.hasAvailableActivities = ko.computed(function() { + return model.availableActivities().length > 0; + }); + return model; +} +*/ + +function initHomePageKO() { + var homeUrl = "http://vcweb.asu.edu/lighterprints/api/view-model"; + var activity_id; + var activity_name; + $.ajax({ + type : "GET", + url : homeUrl, + data : { + participant_group_id : participant_group_id + }, + dataType : "json", + cache : false, + success : function(response) { + var viewModelData = $.parseJSON(response.view_model_json); + globalViewModel = new LighterFootprintsModel(viewModelData); + globalViewModel.currentActivity = ko.observable(); + globalViewModel.showActivityDetail = function(activityModel) { + globalViewModel.currentActivity(activityModel); + activity_id = activityModel.pk; + console.log("activity id and name"); + console.log(activity_id); + activity_name = ko.utils.unwrapObservable(activityModel.display_name); + console.log(activity_name); + $.mobile.changePage("#activityDetailsPage"); + }; + globalViewModel.done = function() { + $.ajax({ + type : 'POST', + url : "http://vcweb.asu.edu/lighterprints/api/do-activity", + data : { + participant_group_id : participant_group_id, + activity_id : activity_id, + latitude : "", + longitude : "" + }, + dataType : "json", + success : function(data) { + if (data.success){ + ko.mapping.fromJSON(data.viewModel, globalViewModel); + alert("Success:Performed Acitivity " + activity_name + "!"); + //$.mobile.changePage('#popupDialog', "pop", false, false); + } + else + alert("Could not perform activity"); + //initHomePageKO(); + $.mobile.changePage('#homePage'); + }, + error : function(form, response) { + alert(response.message); + } + }); + }; + + ko.applyBindings(globalViewModel); +// ko.applyBindings(globalViewModel, $('#homePage')[0]); +// ko.applyBindings(globalViewModel, $('#homePage')[0]); +// ko.applyBindings(globalViewModel, $('#homePage')[0]); + + }, + error : function(form, response) { + alert(response.message); + } + }); + +}; + +function buildScorePage() { + var groupScoreURL = "http://vcweb.asu.edu/lighterprints/api/group-score/"+participant_group_id; + function parseResult(result) { + console.debug("invoking parse data for group score"); + console.log(result); + scoreObj = result.scores[0]; + console.log(scoreObj); + var total_points = scoreObj.total_points; + var points_to_next_level = scoreObj.points_to_next_level; + var average_points_per_person = scoreObj.average_points_per_person; + console.log(ko.utils.unwrapObservable(globalViewModel.groupLevel)); + // For horizontal bar charts, x an y values must will be "flipped" + // from their vertical bar counterpart. + plot1 = $.jqplot('scoreChart', [[points_to_next_level,total_points, average_points_per_person]],{ + title:'Group Level: '+ko.utils.unwrapObservable(globalViewModel.groupLevel), + series:[{color:'#357EC7'}], + seriesDefaults: { + renderer:$.jqplot.BarRenderer, + // Show point labels to the right ('e'ast) of each bar. + // edgeTolerance of -15 allows labels flow outside the grid + // up to 15 pixels. If they flow out more than that, they + // will be hidden. + //pointLabels: { show: true, location: 'e', edgeTolerance: -15 }, + pointLabels:{ + show: true, + labels:['Average Needed To Advance', 'Total Group Points', 'Average Points Per Person'], + location: 'e', + edgeTolerance: -100 + }, + // Rotate the bar shadow as if bar is lit from top right + // Here's where we tell the chart it is oriented horizontally. + rendererOptions: { + barWidth: 20.0, + barDirection: 'horizontal' + } + }, + axes: { + xaxis:{max:1000}, + yaxis: { + renderer: $.jqplot.CategoryAxisRenderer + } + } + }); + plot1.replot({clear: true, resetAxes:true}); + } + + $.ajax({ + type : "GET", + url : groupScoreURL, + dataType : "json", + cache : false, + success : function(result) { + $('scoreChart').empty(); + parseResult(result); + }, + error : function(form, response) { + alert(response.message); + } + }); +}; + +$(document).live('pageinit', function(event) { + + $("#submitLogin").click(function(event) { + event.preventDefault(); + + var formData = $("#loginForm").serialize(); + + $.ajax({ + type : "POST", + url : "http://vcweb.asu.edu/lighterprints/api/login", + cache : false, + data : formData, + dataType : "json", + success : function(data) { + if (data.success == false) { + alert("Invalid login!"); + } else if (data.success == true) { + participant_group_id = data.participant_group_id; + $.mobile.changePage($("#homePage")); + } + }, + error : function(form, response) { + alert(response.message); + } + }); + }); + + + $("#loginPage").bind('pageinit', function(event) { + participant_group_id =""; + }); + $("#loginPage").bind('pageshow', function(event) { + participant_group_id =""; + }); + $("#homePage").bind('pageinit', function(event) { + initHomePageKO(); + //initGroupPageKO(); + }); + +// $("#homePage").bind('pageaftershow', function(event) { +// //$("#homePageNoActFlag").listview('refresh'); +// }); + + + $('[data-role=page]').bind('pageshow', function(event) { + if(participant_group_id == null){ + window.location.href="index.html"; + } + }); + + $('[data-role=page]').bind('pageinit', function(event) { + if(participant_group_id == null){ + window.location.href="index.html"; + } + }); + + $("#activityDetailsPage").bind('pagebeforeshow', function(event) { + $('#currActivityInfoList').listview('refresh'); + $('#currActivityDetailsList').listview('refresh'); + //$('#footerList').listview('refresh'); + }); + + $("#messagePage").bind('pagebeforeshow', function(event) { + $('#groupPageMessageList').listview('refresh'); + }); + + $("#scorePage").bind('pageshow', function(event) { + buildScorePage(); + $(window).resize(function() { + plot1.replot( { resetAxes: true } ); + }); + }); + +}); diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/lighterprints/static/js/lighterprints/model.js --- /dev/null +++ b/vcweb/lighterprints/static/js/lighterprints/model.js @@ -0,0 +1,94 @@ +function LighterFootprintsModel(modelJson) { + var self = this; + var model = ko.mapping.fromJS(modelJson); + model.minuteTick = function() { + var hoursLeft = model.hoursLeft(); + var minutesLeft = model.minutesLeft() - 1; + if (minutesLeft < 0) { + minutesLeft = 59; + hoursLeft--; + if (hoursLeft < 0) { + hoursLeft = 23; + } + } + model.hoursLeft(hoursLeft); + var minutes = minutesLeft + ""; + if (minutesLeft.length == 1) { + minutesLeft = "0" + minutesLeft; + } + model.minutesLeft(minutesLeft); + }; + setInterval(model.minuteTick, 1000*60); + // FIXME: hacky, figure out if there is a way to pass the observable in directly from the model object we get in + // performActivity + model.lastPerformedActivity = ko.observable(); + model.errorMessage = ko.observable(); + model.hasGroupActivity = ko.computed(function() { + return model.groupActivity().length > 0; + }); + model.groupActivityTemplate = function(groupActivity) { + return groupActivity.parameter_name(); + }; + model.teamActivity = ko.computed(function() { + return ko.utils.arrayFilter(model.groupActivity(), function(groupActivity) { + return groupActivity.parameter_name().indexOf("chat_message") != 0; + }); + }); + model.chatMessages = ko.computed(function() { + return ko.utils.arrayFilter(model.groupActivity(), function(groupActivity) { return groupActivity.parameter_name().indexOf("chat_message") === 0 }); + }); + model.hasChatMessages = ko.computed(function() { + return model.chatMessages().length > 0; + }); + model.submitChatMessage = function() { + var formData = $('#chat-form').serialize(); + $.post('/lighterprints/api/message', formData, function(response) { + if (response.success) { + console.debug("successful post - updated view model: "); + ko.mapping.fromJS(response.viewModel, model); + } + else { + console.debug("unable to post message to server"); + console.debug(response); + } + }); + $('#chatText').val(''); + return false; + }; + model.lockedChallenges = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { return activity.locked() }); + }); + model.unlockedChallenges = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { return ! activity.locked() }); + }); + model.availableActivities = ko.computed(function() { + return ko.utils.arrayFilter(model.activities(), function(activity) { return activity.availableNow() }); + }); + model.hasAvailableActivities = ko.computed(function() { + return model.availableActivities().length > 0; + }); + model.closeCommentPopover = function(targetModel) { + $('.comment-popover').popover('hide'); + }; + return model; +} +ko.bindingHandlers.popover = { + init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var attribute = ko.utils.unwrapObservable(valueAccessor()); + var cssSelectorForPopoverTemplate = attribute.content; + var popOverTemplate = "<div id='"+attribute.id+"-popover'>" + $(cssSelectorForPopoverTemplate).html() + "</div>"; + $(element).popover({ + content: popOverTemplate, + html: true, + trigger: 'manual' + }); + var popoverId = "comment-popover" + attribute.id; + $(element).attr('id', popoverId); + $(element).click(function() { + $(this).popover('toggle'); + var thePopover = document.getElementById(attribute.id+"-popover"); + childBindingContext = bindingContext.createChildContext(viewModel); + ko.applyBindingsToDescendants(childBindingContext, thePopover); + }); + }, +}; diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/css/boundaries/style.css --- a/vcweb/static/css/boundaries/style.css +++ /dev/null @@ -1,28 +0,0 @@ -.chat-sidebar { - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - padding: 0px 0px 0px 0px; - margin: 0px; -} -.chat-messages { - padding: 5px; -} -#chat-div { - overflow: auto; - height: 820px; -} -#chatMessage { -} -.boundaries-status-dashboard p { - padding-top: 15px; - font-size: 2em; -} -.boundaries-status-dashboard h4 { - border-bottom: 1px solid #ccc; -} -.boundaries-status-dashboard { - height: 100px; - width: 110px; - margin-right: 0px; - padding: 8px 8px 8px 8px; -} diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/css/lighterprints/style.css --- a/vcweb/static/css/lighterprints/style.css +++ /dev/null @@ -1,372 +0,0 @@ -body { - background-color: #F7F7F7; -} -/* navbar css from fervor -.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { - -webkit-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; - -moz-box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; - box-shadow: inset 0 1px 0px #87d7f7, inset 0 -1px 0px #0089bb; -} -.navbar-fixed-top .navbar-inner, .navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - border-width: 0 0 0px; -} -.navbar-inner { - min-height: 64px; - padding-left: 20px; - padding-right: 20px; - background-color: #009fe1; - background-image: -moz-linear-gradient(top, #29afee, #009fe1); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#29afee), to(#009fe1)); - background-image: -webkit-linear-gradient(top, #29afee, #009fe1); - background-image: -o-linear-gradient(top, #29afee, #009fe1); - background-image: linear-gradient(to bottom, #29afee, #009fe1); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#29afee', endColorstr='#009fe1', GradientType=0); - border-bottom: 1px solid #0089bb; - border-top: 1px solid #87d7f7; -} -.navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { - border-width: 0 0 0px; -} -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; - border: 0; -} -.navbar .nav > li > a { - float: none; - padding: 20px 27px 20px 25px; - color: #ffffff; - text-decoration: none; - -webkit-font-smoothing: antialiased; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-right: 1px solid rgb(5, 150, 204); - box-shadow: 1px 0 0 rgb(24, 193, 255); -} -.navbar .brand { - float: left; - display: block; - padding: 17px 25px 0px !important; - margin-left: -20px; - font-size: 22px; - font-weight: 200; - color: #777777; - text-shadow: 0 1px 1px #0196cd; - border: 0 !important; - box-shadow: none !important; -} -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 22px; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; - font-weight: bold; -} -.navbar .nav > li > a:focus, .navbar .nav > li > a:hover { - background-color: transparent; - color: #bee3f3; - text-decoration: none; - cursor: pointer; -} -.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus { - color: #b9ed2e; - text-decoration: none; - background-color: #42555e; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-top: 1px solid #42555e; - border-bottom: 1px solid #42555e; - text-shadow: 0 0 5px rgba(149, 203, 41, 0.25); -} -.nav-tabs > .active > a, .nav-tabs > .active > a:hover, .nav-tabs > .active > a:focus { - color: #555555; - background-color: #ffffff; - border-bottom: 1px solid #42555e; - border-bottom-color: transparent; - cursor: pointer; - border-top: 1px solid #42555e; -} -.navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #42555e; - color: #ffffff; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, .navbar .nav li.dropdown.active > .dropdown-toggle .caret, .navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} -.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:1em;font-size:1.3em}li [class^="icon-"],.nav li [class^="icon-"],li [class*=" icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 16px 10px; - margin: 25px 0 0; - list-style: none; - background-color: #ffffff; - -webkit-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - box-shadow: 0 0px 5px rgba(0, 0, 0, 0.15); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.dropdown-menu > li > a { - display: block; - padding: 5px 20px; - clear: both; - font-weight: normal; - line-height: 20px; - color: #333333; - white-space: nowrap; - font-size: 12px; - font-family: 'Lucida Grande'; -} -.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { - text-decoration: none; - color: #13a6e7; -} -.icon-cog { - background-position: -432px 0; - font-size: 1.5em; - color: #bee3f3; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #bee3f3; - border-bottom-color: #bee3f3; -} -.dropdown .caret { - margin-top: 8px; - margin-left: 10px; -} -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 7px solid #000000; - border-right: 5px solid transparent; - border-left: 5px solid transparent; - content: ""; -} -*/ -.challenge-tabs > .nav-tabs > .active > a, .challenge-tabs > .nav-tabs > .active > a:hover { - border-top: 3px solid #DFB03D; - border-bottom: none; -} -.challenge-tabs > .nav-tabs > li > a { - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; - border-right: 1px solid #ddd; - border-bottom: none; - color: #A9A9A9; -} -.challenge-row { - padding: 20px 0 20px 0; - border-bottom: 1px solid #ddd; -} -.challenges { - margin-top: -20px; - background-color: #FFFFFF; - border-left: 1px solid #ddd; - border-right: 1px solid #ddd; -} -..expired-challenge { - color: red; -} -a.upcoming-challenge, a.expired-challenge, a.perform-challenge, a.completed-challenge { - text-transform: uppercase; - color: #FFF !important; - -webkit-font-smoothing: antialiased; - background-repeat: repeat-x; -} -a.upcoming-challenge { - background-color: hsl(0, 0%, 54%) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#f4f4f4", endColorstr="#898989"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#f4f4f4), to(#898989)); - background-image: -moz-linear-gradient(top, #f4f4f4, #898989); - background-image: -ms-linear-gradient(top, #f4f4f4, #898989); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4f4f4), color-stop(100%, #898989)); - background-image: -webkit-linear-gradient(top, #f4f4f4, #898989); - background-image: -o-linear-gradient(top, #f4f4f4, #898989); - background-image: linear-gradient(#f4f4f4, #898989); - border-color: #898989 #898989 hsl(0, 0%, 43.5%); - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.69); -} -a.expired-challenge { - background-color: hsl(0, 100%, 79%) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffbcbc", endColorstr="#ff9393"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#ffbcbc), to(#ff9393)); - background-image: -moz-linear-gradient(top, #ffbcbc, #ff9393); - background-image: -ms-linear-gradient(top, #ffbcbc, #ff9393); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffbcbc), color-stop(100%, #ff9393)); - background-image: -webkit-linear-gradient(top, #ffbcbc, #ff9393); - background-image: -o-linear-gradient(top, #ffbcbc, #ff9393); - background-image: linear-gradient(#ffbcbc, #ff9393); - border-color: #ff9393 #ff9393 hsl(0, 100%, 77%); - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.13); -} -a.perform-challenge,a.completed-challenge { - background-color: hsl(96, 81%, 42%) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#66dd17", endColorstr="#59c114"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#66dd17), to(#59c114)); - background-image: -moz-linear-gradient(top, #66dd17, #59c114); - background-image: -ms-linear-gradient(top, #66dd17, #59c114); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #66dd17), color-stop(100%, #59c114)); - background-image: -webkit-linear-gradient(top, #66dd17, #59c114); - background-image: -o-linear-gradient(top, #66dd17, #59c114); - background-image: linear-gradient(#66dd17, #59c114); - border-color: #59c114 #59c114 hsl(96, 81%, 40.5%); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.09); -} -h1.header { - font-family:"Open Sans"; - font-size:1.8em; - font-weight: normal; - line-height:133%; - color:rgb(201,205,209); - text-align:left; - padding: 10px 0px 5px 0px; - /* Firefox v4.0+ , Safari v5.1+ , Chrome v10.0+, IE v10+ and by Opera v10.5+ */ - text-shadow:0px 1px 1px rgb(255,255,255); - -ms-filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true)";zoom:1; - filter:progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true); -} -div.lighterprints-scoreboard { - color: #A9A9A9; -} -.lighterprints-scoreboard-large { - font-size: 3em; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; - color: #666666; -} -.lighterprints-scoreboard-xlarge { - font-size: 4.6em; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; - color: #666666; -} -div.lighterprints-scoreboard h1 { - font-size: 5em; - color: #666666; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; -} -div.lighterprints-scoreboard h2 { - font-size: 4em; - color: #666666; - font-family: 'TrumpGothicWestW01-Bold', sans-serif; -} -div.lighterprints-scoreboard h5 { - padding-bottom: 15px; -} -h3.popover-title { - font-weight: bolder; -} -.chart { - margin-top: -25px; -} -.dashboard-content { - margin-top: -3px; -} -.lighterprints-gray { - color: #D0D0D0; -} -.comment:hover, .commented { - color: #13a5e6; - text-decoration: none; -} -.like:hover, .liked { - color: #FF0066; - text-decoration: none; -} -.lighterprints-red { - color: #FF0066; -} -.lighterprints-blue { - color: #13a5e6; -} -.lighterprints-green { - color: #95CB29; -} -.badge-lighterprints-green { - background-color: #95CB29; - color: #FFFFFF; -} -.btn-lighterprints-blue { - background-color: hsl(197, 89%, 37%) !important; - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#39bef3", endColorstr="#0a82b2"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#39bef3), to(#0a82b2)); - background-image: -moz-linear-gradient(top, #39bef3, #0a82b2); - background-image: -ms-linear-gradient(top, #39bef3, #0a82b2); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #39bef3), color-stop(100%, #0a82b2)); - background-image: -webkit-linear-gradient(top, #39bef3, #0a82b2); - background-image: -o-linear-gradient(top, #39bef3, #0a82b2); - background-image: linear-gradient(#39bef3, #0a82b2); - border-color: #0a82b2 #0a82b2 hsl(197, 89%, 31.5%); - color: #fff !important; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.36); - -webkit-font-smoothing: antialiased; -} -.lighterprints-scoreboard-uppercase { - letter-spacing:1pt; - line-height:187%; - color:rgb(65,85,93); - /* Firefox v4.0+ , Safari v5.1+ , Chrome v10.0+, IE v10+ and by Opera v10.5+ */ - text-shadow:0px 1px 1px rgb(255,255,255); - -ms-filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true)";zoom:1; - filter:progid:DXImageTransform.Microsoft.dropshadow(OffX = 0,OffY = 1,Color = #ffffffff,Positive = true); - font-size: 1.2em; - font-weight: normal; - padding-bottom: 15px; - text-transform: uppercase; -} -.sidebar { - min-height: 100%; - background-color: #FFFFFF; -} -.lighterprints-sidebar { - padding: 10px 20px 10px 20px; -} -.lighterprints-leaderboard { - font-weight: normal; - color: #41555d; -} -.group-level { - margin-top: -15px; - vertical-align: top; -} -h3.underline { - font-weight: normal; -} -td.group-activity-icon { - padding-right: 2px; -} -td.group-activity { - padding-left: 2px; -} -a { - color:#0088cc; - text-decoration:none; - -webkit-transition: color 180ms ease-in; - -moz-transition: color 180ms ease-in; - transition: color 180ms ease-in; -} diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/adjust-thermostat.png Binary file vcweb/static/images/lighterprints/badges/adjust-thermostat.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/air-dry-clothes.png Binary file vcweb/static/images/lighterprints/badges/air-dry-clothes.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/bike-or-walk.png Binary file vcweb/static/images/lighterprints/badges/bike-or-walk.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/cold-water-wash.png Binary file vcweb/static/images/lighterprints/badges/cold-water-wash.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/computer-off-night.png Binary file vcweb/static/images/lighterprints/badges/computer-off-night.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/eat-green-lunch.png Binary file vcweb/static/images/lighterprints/badges/eat-green-lunch.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/eat-local-lunch.png Binary file vcweb/static/images/lighterprints/badges/eat-local-lunch.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/enable-sleep-on-computer.png Binary file vcweb/static/images/lighterprints/badges/enable-sleep-on-computer.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/lights-off.png Binary file vcweb/static/images/lighterprints/badges/lights-off.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/no-beef.png Binary file vcweb/static/images/lighterprints/badges/no-beef.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/recycle-materials.png Binary file vcweb/static/images/lighterprints/badges/recycle-materials.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/recycle-paper.png Binary file vcweb/static/images/lighterprints/badges/recycle-paper.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/share-your-ride.png Binary file vcweb/static/images/lighterprints/badges/share-your-ride.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/sprites.png Binary file vcweb/static/images/lighterprints/badges/sprites.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/vegan-for-a-day.png Binary file vcweb/static/images/lighterprints/badges/vegan-for-a-day.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/badges/water-off-while-brushing-teeth.png Binary file vcweb/static/images/lighterprints/badges/water-off-while-brushing-teeth.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/experiment-completed.png Binary file vcweb/static/images/lighterprints/experiment-completed.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/logo.png Binary file vcweb/static/images/lighterprints/logo.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/rank1.png Binary file vcweb/static/images/lighterprints/rank1.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/rank2.png Binary file vcweb/static/images/lighterprints/rank2.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/images/lighterprints/rank3.png Binary file vcweb/static/images/lighterprints/rank3.png has changed diff -r f2d2410357c8cc88dafc62143504e8929f8a1bfc -r 70ad0836180c56cb3013e55118bdf8619ce23493 vcweb/static/js/lighterprints/mobile/controller.js --- a/vcweb/static/js/lighterprints/mobile/controller.js +++ /dev/null @@ -1,262 +0,0 @@ -var participant_group_id; -var plot1; -var globalViewModel; - -//Model for details of the current activities used in home page and activity detail page -/* -function LighterFootprintsModel(modelJson) { - var self = this; - var model = ko.mapping.fromJS(modelJson); - // FIXME: hacky, figure out if there is a way to pass the observable in directly from the model object we get in - // performActivity - model.lastPerformedActivity = ko.observable(); - model.lastPerformedActivityPoints = ko.observable(); - model.errorMessage = ko.observable(); - model.hasChatMessages = function() { - return model.chatMessages().length > 0; - } - - model.submitChatMessage = function() { - var formData = "participant_group_id="+participant_group_id+"&"; - formData += $('#chat-form').serialize(); - $.post('http://vcweb.asu.edu/lighterprints/api/message', formData, function(data) { - ko.mapping.fromJS(data, model); - $('#groupPageMessageList').listview('refresh'); - }); - $('#chatText').val(''); - return false; - }; - - model.availableActivities = ko.computed(function() { - return ko.utils.arrayFilter(model.activities(), function(activity) { return activity.available_now() }); - }); - - model.availableL1 = ko.computed(function() { - return ko.utils.arrayFilter(model.activities(), function(activity) { - console.log(activity.level()); - if (activity.level() == '1') return true; - }); - }); - - model.availableL2 = ko.computed(function() { - return ko.utils.arrayFilter(model.activities(), function(activity) { - console.log(activity.level()); - if (activity.level() == '2') return true; - }); - }); - - model.availableL3 = ko.computed(function() { - return ko.utils.arrayFilter(model.activities(), function(activity) { - console.log(activity.level()); - if (activity.level() == '3') return true; - }); - }); - - model.hasAvailableActivities = ko.computed(function() { - return model.availableActivities().length > 0; - }); - return model; -} -*/ - -function initHomePageKO() { - var homeUrl = "http://vcweb.asu.edu/lighterprints/api/view-model"; - var activity_id; - var activity_name; - $.ajax({ - type : "GET", - url : homeUrl, - data : { - participant_group_id : participant_group_id - }, - dataType : "json", - cache : false, - success : function(response) { - var viewModelData = $.parseJSON(response.view_model_json); - globalViewModel = new LighterFootprintsModel(viewModelData); - globalViewModel.currentActivity = ko.observable(); - globalViewModel.showActivityDetail = function(activityModel) { - globalViewModel.currentActivity(activityModel); - activity_id = activityModel.pk; - console.log("activity id and name"); - console.log(activity_id); - activity_name = ko.utils.unwrapObservable(activityModel.display_name); - console.log(activity_name); - $.mobile.changePage("#activityDetailsPage"); - }; - globalViewModel.done = function() { - $.ajax({ - type : 'POST', - url : "http://vcweb.asu.edu/lighterprints/api/do-activity", - data : { - participant_group_id : participant_group_id, - activity_id : activity_id, - latitude : "", - longitude : "" - }, - dataType : "json", - success : function(data) { - if (data.success){ - ko.mapping.fromJSON(data.viewModel, globalViewModel); - alert("Success:Performed Acitivity " + activity_name + "!"); - //$.mobile.changePage('#popupDialog', "pop", false, false); - } - else - alert("Could not perform activity"); - //initHomePageKO(); - $.mobile.changePage('#homePage'); - }, - error : function(form, response) { - alert(response.message); - } - }); - }; - - ko.applyBindings(globalViewModel); -// ko.applyBindings(globalViewModel, $('#homePage')[0]); -// ko.applyBindings(globalViewModel, $('#homePage')[0]); -// ko.applyBindings(globalViewModel, $('#homePage')[0]); - - }, - error : function(form, response) { - alert(response.message); - } - }); - -}; - -function buildScorePage() { - var groupScoreURL = "http://vcweb.asu.edu/lighterprints/api/group-score/"+participant_group_id; - function parseResult(result) { - console.debug("invoking parse data for group score"); - console.log(result); - scoreObj = result.scores[0]; - console.log(scoreObj); - var total_points = scoreObj.total_points; - var points_to_next_level = scoreObj.points_to_next_level; - var average_points_per_person = scoreObj.average_points_per_person; - console.log(ko.utils.unwrapObservable(globalViewModel.groupLevel)); - // For horizontal bar charts, x an y values must will be "flipped" - // from their vertical bar counterpart. - plot1 = $.jqplot('scoreChart', [[points_to_next_level,total_points, average_points_per_person]],{ - title:'Group Level: '+ko.utils.unwrapObservable(globalViewModel.groupLevel), - series:[{color:'#357EC7'}], - seriesDefaults: { - renderer:$.jqplot.BarRenderer, - // Show point labels to the right ('e'ast) of each bar. - // edgeTolerance of -15 allows labels flow outside the grid - // up to 15 pixels. If they flow out more than that, they - // will be hidden. - //pointLabels: { show: true, location: 'e', edgeTolerance: -15 }, - pointLabels:{ - show: true, - labels:['Average Needed To Advance', 'Total Group Points', 'Average Points Per Person'], - location: 'e', - edgeTolerance: -100 - }, - // Rotate the bar shadow as if bar is lit from top right - // Here's where we tell the chart it is oriented horizontally. - rendererOptions: { - barWidth: 20.0, - barDirection: 'horizontal' - } - }, - axes: { - xaxis:{max:1000}, - yaxis: { - renderer: $.jqplot.CategoryAxisRenderer - } - } - }); - plot1.replot({clear: true, resetAxes:true}); - } - - $.ajax({ - type : "GET", - url : groupScoreURL, - dataType : "json", - cache : false, - success : function(result) { - $('scoreChart').empty(); - parseResult(result); - }, - error : function(form, response) { - alert(response.message); - } - }); -}; - -$(document).live('pageinit', function(event) { - - $("#submitLogin").click(function(event) { - event.preventDefault(); - - var formData = $("#loginForm").serialize(); - - $.ajax({ - type : "POST", - url : "http://vcweb.asu.edu/lighterprints/api/login", - cache : false, - data : formData, - dataType : "json", - success : function(data) { - if (data.success == false) { - alert("Invalid login!"); - } else if (data.success == true) { - participant_group_id = data.participant_group_id; - $.mobile.changePage($("#homePage")); - } - }, - error : function(form, response) { - alert(response.message); - } - }); - }); - - - $("#loginPage").bind('pageinit', function(event) { - participant_group_id =""; - }); - $("#loginPage").bind('pageshow', function(event) { - participant_group_id =""; - }); - $("#homePage").bind('pageinit', function(event) { - initHomePageKO(); - //initGroupPageKO(); - }); - -// $("#homePage").bind('pageaftershow', function(event) { -// //$("#homePageNoActFlag").listview('refresh'); -// }); - - - $('[data-role=page]').bind('pageshow', function(event) { - if(participant_group_id == null){ - window.location.href="index.html"; - } - }); - - $('[data-role=page]').bind('pageinit', function(event) { - if(participant_group_id == null){ - window.location.href="index.html"; - } - }); - - $("#activityDetailsPage").bind('pagebeforeshow', function(event) { - $('#currActivityInfoList').listview('refresh'); - $('#currActivityDetailsList').listview('refresh'); - //$('#footerList').listview('refresh'); - }); - - $("#messagePage").bind('pagebeforeshow', function(event) { - $('#groupPageMessageList').listview('refresh'); - }); - - $("#scorePage").bind('p... [truncated message content] |
From: <com...@bi...> - 2013-04-03 07:51:19
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/f2d2410357c8/ Changeset: f2d2410357c8 User: alllee Date: 2013-04-03 09:51:01 Summary: fixes issue 79 using Chart.js (www.chartjs.org). Improving lighterprints scoreboard UI consistency Affected #: 4 files diff -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 -r f2d2410357c8cc88dafc62143504e8929f8a1bfc vcweb/lighterprints/templates/lighterprints/participate.html --- a/vcweb/lighterprints/templates/lighterprints/participate.html +++ b/vcweb/lighterprints/templates/lighterprints/participate.html @@ -52,7 +52,8 @@ <div class='row lighterprints-scoreboard'><div class='span2'><h5><span class='lighterprints-scoreboard-uppercase'>Today's Score</span> - <i id='score-info' style='margin:8px 0 0 0;' rel='popover' data-trigger='hover' data-placement='top' data-content="This is your group's average score for the day. Complete high-value challenges to rank your group up." class='pull-right icon-info-sign'></i></h5> + <i id='score-info' style='margin:8px 0 0 0;' rel='popover' data-trigger='hover' data-placement='top' + data-content="This is your group's average score for the day. Complete high-value challenges to rank your group up." class='pull-right icon-info-sign'></i></h5><table><tr><td class='lighterprints-scoreboard-xlarge'><span data-bind='text: averagePoints'></span></td> @@ -62,22 +63,33 @@ </div><div class='span2 left-divider'><h5><span class='lighterprints-scoreboard-uppercase'>Current Level</span></h5> - <h1 data-bind='if: experimentCompleted'> - <img class='group-level' width='120' height='70' src='{% static "images/lighterprints/experiment-completed.png"%}'> - </h1> - <h1 data-bind='ifnot: experimentCompleted'> - <img class='group-level' width="104" height="65" data-bind="attr: { src: '{% static "images/lighterprints/rank"%}' + groupLevel() + '.png' }"> - </h1> + <div class='dashboard-content'> + <div data-bind='if: experimentCompleted'> + <img class='group-level' width='120' height='70' src='{% static "images/lighterprints/experiment-completed.png"%}'> + </div> + <div data-bind='ifnot: experimentCompleted'> + <img class='group-level' width="104" height="65" data-bind="attr: { src: '{% static "images/lighterprints/rank"%}' + groupLevel() + '.png' }"> + </div> + </div></div><div class='span2 left-divider'> - <h5><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span></h5> - <div class='lighterprints-scoreboard-xlarge'> - <span data-bind='text: averagePoints'></span>/<span data-bind='text:pointsToNextLevel'></span> + <h5><span class='lighterprints-scoreboard-uppercase'>Today's Progress</span> + <i id='progress-info' style='padding: 0px 0px 0px 0px; margin: -1px 0px 0px -1px;' rel='popover' data-trigger='hover' + data-placement='top' data-content='This chart shows the average group score needed to advance to the next level.' + class='icon-info-sign'></i> + </h5> + <div class='chart'> + <canvas id='todaysProgressChart' width="87" height="87"></canvas></div></div><div class='span2 left-divider'><h5><span class='lighterprints-scoreboard-uppercase'>Time Remaining</span></h5> - <div class='lighterprints-scoreboard-xlarge'><span data-bind='text:hoursLeft'></span>:<span data-bind='text:minutesLeft'></span></div> + <table> + <tr> + <td class='lighterprints-scoreboard-xlarge'><span data-bind='text: hoursLeft'></span>h</td> + <td class='lighterprints-scoreboard-xlarge'><span data-bind='text: minutesLeft'></span>m</td> + </tr> + </table></div></div><h3 class='underline'>Challenges</h3> @@ -294,6 +306,7 @@ {{ block.super }} <script src="//fast.fonts.com/jsapi/e86344be-530a-495b-be28-7a22a9cda219.js"></script><script src='{% static "js/lighterprints/model.js" %}'></script> +<script src='{% static "js/Chart.min.js" %}'></script><script> $(function() { // XXX: set up bootstrap nav-tabs to be semi-refresh friendly, remove in production @@ -310,6 +323,12 @@ var viewModelData = $.parseJSON("{{ view_model_json|escapejs }}"); var viewModel = new LighterFootprintsModel(viewModelData); // custom view model methods, some of these may be lifted into the model itself + var ctx = document.getElementById("todaysProgressChart").getContext("2d"); + var data = [ + { value: viewModel.averagePoints(), color: "#95CB29" }, + { value: viewModel.pointsToNextLevel(), color: "#D0D0D0" }, + ] + var progressChart = new Chart(ctx).Doughnut(data); viewModel.activateChallengesTab = activateTabFunctor('#challenges', '#lfp-navtabs'); viewModel.activateDashboardTab = activateTabFunctor('#dashboard', '#lfp-navtabs'); viewModel.activateHelpTab = activateTabFunctor('#help', '#lfp-navtabs'); @@ -368,7 +387,7 @@ }; ko.applyBindings(viewModel); // FIXME: use $('.popover').popover() if we end up having a lot more of these. - $('#score-info').popover(); + $('[data-content]').popover(); }); </script><!-- bootstrap popover templates --> diff -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 -r f2d2410357c8cc88dafc62143504e8929f8a1bfc vcweb/static/css/lighterprints/style.css --- a/vcweb/static/css/lighterprints/style.css +++ b/vcweb/static/css/lighterprints/style.css @@ -260,7 +260,7 @@ color: #666666; } .lighterprints-scoreboard-xlarge { - font-size: 5em; + font-size: 4.6em; font-family: 'TrumpGothicWestW01-Bold', sans-serif; color: #666666; } @@ -280,6 +280,12 @@ h3.popover-title { font-weight: bolder; } +.chart { + margin-top: -25px; +} +.dashboard-content { + margin-top: -3px; +} .lighterprints-gray { color: #D0D0D0; } diff -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 -r f2d2410357c8cc88dafc62143504e8929f8a1bfc vcweb/static/images/lighterprints/experiment-completed.png Binary file vcweb/static/images/lighterprints/experiment-completed.png has changed diff -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 -r f2d2410357c8cc88dafc62143504e8929f8a1bfc vcweb/static/js/Chart.min.js --- /dev/null +++ b/vcweb/static/js/Chart.min.js @@ -0,0 +1,40 @@ +var Chart=function(s){function v(a,c,b){a=B((a-c.graphMin)/(c.steps*c.stepValue),1,0);return b*c.steps*a}function x(a,c,b,d){function l(){f+=g;var m=a.animation?B(h(f),null,0):1;d.clearRect(0,0,q,u);a.scaleOverlay?(b(m),c()):(c(),b(m));if(1>=f)E(l);else if("function"==typeof a.onAnimationComplete)a.onAnimationComplete()}var g=a.animation?1/B(a.animationSteps,Number.MAX_VALUE,1):1,h=C[a.animationEasing],f=a.animation?0:1;"function"!==typeof c&&(c=function(){});E(l)}function D(a,c,b,d,l,g){var h;a= +Math.floor(Math.log(d-l)/Math.LN10);l=Math.floor(l/(1*Math.pow(10,a)))*Math.pow(10,a);h=Math.ceil(d/(1*Math.pow(10,a)))*Math.pow(10,a)-l;d=Math.pow(10,a);for(a=Math.round(h/d);a<b||a>c;)d=a<b?d/2:2*d,a=Math.round(h/d);c=[];if(g)for(b=1;b<a+1;b++)c.push(y(g,{value:(l+d*b).toFixed(A(d))}));return{steps:a,stepValue:d,graphMin:l,labels:c}}function B(a,c,b){return!isNaN(parseFloat(c))&&isFinite(c)&&a>c?c:!isNaN(parseFloat(b))&&isFinite(b)&&a<b?b:a}function A(a){return 0!=a%1?a.toString().split(".")[1].length: +0}function z(a,c){var b={},d;for(d in a)b[d]=a[d];for(d in c)b[d]=c[d];return b}function y(a,c){var b=!/\W/.test(a)?F[a]=F[a]||y(document.getElementById(a).innerHTML):new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return c?b(c):b}var r= +this,C={linear:function(a){return a},easeInQuad:function(a){return a*a},easeOutQuad:function(a){return-1*a*(a-2)},easeInOutQuad:function(a){return 1>(a/=0.5)?0.5*a*a:-0.5*(--a*(a-2)-1)},easeInCubic:function(a){return a*a*a},easeOutCubic:function(a){return 1*((a=a/1-1)*a*a+1)},easeInOutCubic:function(a){return 1>(a/=0.5)?0.5*a*a*a:0.5*((a-=2)*a*a+2)},easeInQuart:function(a){return a*a*a*a},easeOutQuart:function(a){return-1*((a=a/1-1)*a*a*a-1)},easeInOutQuart:function(a){return 1>(a/=0.5)?0.5*a*a*a* +a:-0.5*((a-=2)*a*a*a-2)},easeInQuint:function(a){return 1*(a/=1)*a*a*a*a},easeOutQuint:function(a){return 1*((a=a/1-1)*a*a*a*a+1)},easeInOutQuint:function(a){return 1>(a/=0.5)?0.5*a*a*a*a*a:0.5*((a-=2)*a*a*a*a+2)},easeInSine:function(a){return-1*Math.cos(a/1*(Math.PI/2))+1},easeOutSine:function(a){return 1*Math.sin(a/1*(Math.PI/2))},easeInOutSine:function(a){return-0.5*(Math.cos(Math.PI*a/1)-1)},easeInExpo:function(a){return 0==a?1:1*Math.pow(2,10*(a/1-1))},easeOutExpo:function(a){return 1==a?1:1* +(-Math.pow(2,-10*a/1)+1)},easeInOutExpo:function(a){return 0==a?0:1==a?1:1>(a/=0.5)?0.5*Math.pow(2,10*(a-1)):0.5*(-Math.pow(2,-10*--a)+2)},easeInCirc:function(a){return 1<=a?a:-1*(Math.sqrt(1-(a/=1)*a)-1)},easeOutCirc:function(a){return 1*Math.sqrt(1-(a=a/1-1)*a)},easeInOutCirc:function(a){return 1>(a/=0.5)?-0.5*(Math.sqrt(1-a*a)-1):0.5*(Math.sqrt(1-(a-=2)*a)+1)},easeInElastic:function(a){var c=1.70158,b=0,d=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);d<Math.abs(1)?(d=1,c=b/4):c=b/(2*Math.PI)* +Math.asin(1/d);return-(d*Math.pow(2,10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b))},easeOutElastic:function(a){var c=1.70158,b=0,d=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);d<Math.abs(1)?(d=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/d);return d*Math.pow(2,-10*a)*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInOutElastic:function(a){var c=1.70158,b=0,d=1;if(0==a)return 0;if(2==(a/=0.5))return 1;b||(b=1*0.3*1.5);d<Math.abs(1)?(d=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/d);return 1>a?-0.5*d*Math.pow(2,10*(a-=1))* +Math.sin((1*a-c)*2*Math.PI/b):0.5*d*Math.pow(2,-10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInBack:function(a){return 1*(a/=1)*a*(2.70158*a-1.70158)},easeOutBack:function(a){return 1*((a=a/1-1)*a*(2.70158*a+1.70158)+1)},easeInOutBack:function(a){var c=1.70158;return 1>(a/=0.5)?0.5*a*a*(((c*=1.525)+1)*a-c):0.5*((a-=2)*a*(((c*=1.525)+1)*a+c)+2)},easeInBounce:function(a){return 1-C.easeOutBounce(1-a)},easeOutBounce:function(a){return(a/=1)<1/2.75?1*7.5625*a*a:a<2/2.75?1*(7.5625*(a-=1.5/2.75)*a+0.75): +a<2.5/2.75?1*(7.5625*(a-=2.25/2.75)*a+0.9375):1*(7.5625*(a-=2.625/2.75)*a+0.984375)},easeInOutBounce:function(a){return 0.5>a?0.5*C.easeInBounce(2*a):0.5*C.easeOutBounce(2*a-1)+0.5}},q=s.canvas.width,u=s.canvas.height;window.devicePixelRatio&&(s.canvas.style.width=q+"px",s.canvas.style.height=u+"px",s.canvas.height=u*window.devicePixelRatio,s.canvas.width=q*window.devicePixelRatio,s.scale(window.devicePixelRatio,window.devicePixelRatio));this.PolarArea=function(a,c){r.PolarArea.defaults={scaleOverlay:!0, +scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce", +animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?z(r.PolarArea.defaults,c):r.PolarArea.defaults;return new G(a,b,s)};this.Radar=function(a,c){r.Radar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!1,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)", +scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,angleShowLineOut:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:12,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?z(r.Radar.defaults,c):r.Radar.defaults;return new H(a,b,s)};this.Pie=function(a, +c){r.Pie.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?z(r.Pie.defaults,c):r.Pie.defaults;return new I(a,b,s)};this.Doughnut=function(a,c){r.Doughnut.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1, +onAnimationComplete:null};var b=c?z(r.Doughnut.defaults,c):r.Doughnut.defaults;return new J(a,b,s)};this.Line=function(a,c){r.Line.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,bezierCurve:!0, +pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:2,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?z(r.Line.defaults,c):r.Line.defaults;return new K(a,b,s)};this.Bar=function(a,c){r.Bar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'", +scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?z(r.Bar.defaults,c):r.Bar.defaults;return new L(a,b,s)};var G=function(a,c,b){var d,l,g,h,f,m,j,e,k;f=Math.min.apply(Math,[q,u])/2;f-=Math.max.apply(Math,[0.5*c.scaleFontSize,0.5*c.scaleLineWidth]); +e=2*c.scaleFontSize;c.scaleShowLabelBackdrop&&(e+=2*c.scaleBackdropPaddingY,f-=1.5*c.scaleBackdropPaddingY);k=f;e=e?e:5;d=Number.MIN_VALUE;l=Number.MAX_VALUE;for(g=0;g<a.length;g++)a[g].value>d&&(d=a[g].value),a[g].value<l&&(l=a[g].value);g=Math.floor(k/(0.66*e));h=Math.floor(0.5*(k/e));e=c.scaleShowLabels?c.scaleLabel:null;if(c.scaleOverride){j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]};for(k=0;k<j.steps;k++)e&&j.labels.push(y(e,{value:(c.scaleStartValue+ +c.scaleStepWidth*k).toFixed(A(c.scaleStepWidth))}))}else j=D(k,g,h,d,l,e);m=f/j.steps;x(c,function(){for(var a=0;a<j.steps;a++)if(c.scaleShowLine&&(b.beginPath(),b.arc(q/2,u/2,m*(a+1),0,2*Math.PI,!0),b.strokeStyle=c.scaleLineColor,b.lineWidth=c.scaleLineWidth,b.stroke()),c.scaleShowLabels){b.textAlign="center";b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;var d=j.labels[a];if(c.scaleShowLabelBackdrop){var e=b.measureText(d).width;b.fillStyle=c.scaleBackdropColor;b.beginPath(); +b.rect(Math.round(q/2-e/2-c.scaleBackdropPaddingX),Math.round(u/2-m*(a+1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(e+2*c.scaleBackdropPaddingX),Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY));b.fill()}b.textBaseline="middle";b.fillStyle=c.scaleFontColor;b.fillText(d,q/2,u/2-m*(a+1))}},function(d){var e=-Math.PI/2,f=2*Math.PI/a.length,g=1,h=1;c.animation&&(c.animateScale&&(g=d),c.animateRotate&&(h=d));for(d=0;d<a.length;d++)b.beginPath(),b.arc(q/2,u/2,g*v(a[d].value,j,m),e,e+ +h*f,!1),b.lineTo(q/2,u/2),b.closePath(),b.fillStyle=a[d].color,b.fill(),c.segmentShowStroke&&(b.strokeStyle=c.segmentStrokeColor,b.lineWidth=c.segmentStrokeWidth,b.stroke()),e+=h*f},b)},H=function(a,c,b){var d,l,g,h,f,m,j,e,k;a.labels||(a.labels=[]);f=Math.min.apply(Math,[q,u])/2;e=2*c.scaleFontSize;for(d=k=0;d<a.labels.length;d++)b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily,l=b.measureText(a.labels[d]).width,l>k&&(k=l);f-=Math.max.apply(Math,[k,1.5*(c.pointLabelFontSize/ +2)]);f-=c.pointLabelFontSize;k=f=B(f,null,0);e=e?e:5;d=Number.MIN_VALUE;l=Number.MAX_VALUE;for(g=0;g<a.datasets.length;g++)for(h=0;h<a.datasets[g].data.length;h++)a.datasets[g].data[h]>d&&(d=a.datasets[g].data[h]),a.datasets[g].data[h]<l&&(l=a.datasets[g].data[h]);g=Math.floor(k/(0.66*e));h=Math.floor(0.5*(k/e));e=c.scaleShowLabels?c.scaleLabel:null;if(c.scaleOverride){j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]};for(k=0;k<j.steps;k++)e&&j.labels.push(y(e, +{value:(c.scaleStartValue+c.scaleStepWidth*k).toFixed(A(c.scaleStepWidth))}))}else j=D(k,g,h,d,l,e);m=f/j.steps;x(c,function(){var d=2*Math.PI/a.datasets[0].data.length;b.save();b.translate(q/2,u/2);if(c.angleShowLineOut){b.strokeStyle=c.angleLineColor;b.lineWidth=c.angleLineWidth;for(var e=0;e<a.datasets[0].data.length;e++)b.rotate(d),b.beginPath(),b.moveTo(0,0),b.lineTo(0,-f),b.stroke()}for(e=0;e<j.steps;e++){b.beginPath();if(c.scaleShowLine){b.strokeStyle=c.scaleLineColor;b.lineWidth=c.scaleLineWidth; +b.moveTo(0,-m*(e+1));for(var g=0;g<a.datasets[0].data.length;g++)b.rotate(d),b.lineTo(0,-m*(e+1));b.closePath();b.stroke()}c.scaleShowLabels&&(b.textAlign="center",b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily,b.textBaseline="middle",c.scaleShowLabelBackdrop&&(g=b.measureText(j.labels[e]).width,b.fillStyle=c.scaleBackdropColor,b.beginPath(),b.rect(Math.round(-g/2-c.scaleBackdropPaddingX),Math.round(-m*(e+1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(g+2*c.scaleBackdropPaddingX), +Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY)),b.fill()),b.fillStyle=c.scaleFontColor,b.fillText(j.labels[e],0,-m*(e+1)))}for(e=0;e<a.labels.length;e++){b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily;b.fillStyle=c.pointLabelFontColor;var g=Math.sin(d*e)*(f+c.pointLabelFontSize),h=Math.cos(d*e)*(f+c.pointLabelFontSize);b.textAlign=d*e==Math.PI||0==d*e?"center":d*e>Math.PI?"right":"left";b.textBaseline="middle";b.fillText(a.labels[e],g,-h)}b.restore()},function(d){var e= +2*Math.PI/a.datasets[0].data.length;b.save();b.translate(q/2,u/2);for(var f=0;f<a.datasets.length;f++){b.beginPath();b.moveTo(0,d*-1*v(a.datasets[f].data[0],j,m));for(var g=1;g<a.datasets[f].data.length;g++)b.rotate(e),b.lineTo(0,d*-1*v(a.datasets[f].data[g],j,m));b.closePath();b.fillStyle=a.datasets[f].fillColor;b.strokeStyle=a.datasets[f].strokeColor;b.lineWidth=c.datasetStrokeWidth;b.fill();b.stroke();if(c.pointDot){b.fillStyle=a.datasets[f].pointColor;b.strokeStyle=a.datasets[f].pointStrokeColor; +b.lineWidth=c.pointDotStrokeWidth;for(g=0;g<a.datasets[f].data.length;g++)b.rotate(e),b.beginPath(),b.arc(0,d*-1*v(a.datasets[f].data[g],j,m),c.pointDotRadius,2*Math.PI,!1),b.fill(),b.stroke()}b.rotate(e)}b.restore()},b)},I=function(a,c,b){for(var d=0,l=Math.min.apply(Math,[u/2,q/2])-5,g=0;g<a.length;g++)d+=a[g].value;x(c,null,function(g){var f=-Math.PI/2,m=1,j=1;c.animation&&(c.animateScale&&(m=g),c.animateRotate&&(j=g));for(g=0;g<a.length;g++){var e=j*a[g].value/d*2*Math.PI;b.beginPath();b.arc(q/ +2,u/2,m*l,f,f+e);b.lineTo(q/2,u/2);b.closePath();b.fillStyle=a[g].color;b.fill();c.segmentShowStroke&&(b.lineWidth=c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());f+=e}},b)},J=function(a,c,b){for(var d=0,l=Math.min.apply(Math,[u/2,q/2])-5,g=l*(c.percentageInnerCutout/100),h=0;h<a.length;h++)d+=a[h].value;x(c,null,function(f){var h=-Math.PI/2,j=1,e=1;c.animation&&(c.animateScale&&(j=f),c.animateRotate&&(e=f));for(f=0;f<a.length;f++){var k=e*a[f].value/d*2*Math.PI;b.beginPath(); +b.arc(q/2,u/2,j*l,h,h+k,!1);b.arc(q/2,u/2,j*g,h+k,h,!0);b.closePath();b.fillStyle=a[f].color;b.fill();c.segmentShowStroke&&(b.lineWidth=c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());h+=k}},b)},K=function(a,c,b){var d,l,g,h,f,m,j,e,k,t,r,n,p,s=0;f=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(e=0;e<a.labels.length;e++)d=b.measureText(a.labels[e]).width,t=d>t?d:t;q/a.labels.length<t?(s=45,q/a.labels.length<Math.cos(s)*t?(s=90,f-=t):f-=Math.sin(s)* +t):f-=c.scaleFontSize;e=c.scaleFontSize;f=f-5-e;d=Number.MIN_VALUE;l=Number.MAX_VALUE;for(g=0;g<a.datasets.length;g++)for(h=0;h<a.datasets[g].data.length;h++)a.datasets[g].data[h]>d&&(d=a.datasets[g].data[h]),a.datasets[g].data[h]<l&&(l=a.datasets[g].data[h]);g=Math.floor(f/(0.66*e));h=Math.floor(0.5*(f/e));e=c.scaleShowLabels?c.scaleLabel:"";if(c.scaleOverride){j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]};for(d=0;d<j.steps;d++)e&&j.labels.push(y(e,{value:(c.scaleStartValue+ +c.scaleStepWidth*d).toFixed(A(c.scaleStepWidth))}))}else j=D(f,g,h,d,l,e);m=Math.floor(f/j.steps);e=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;for(d=0;d<j.labels.length;d++)l=b.measureText(j.labels[d]).width,e=l>e?l:e;e+=10}r=q-e-t;k=Math.floor(r/(a.labels.length-1));n=q-t/2-r;p=f+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<s?(b.save(), +b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<s?(b.translate(n+d*k,p+c.scaleFontSize),b.rotate(-(s*(Math.PI/180))),b.fillText(a.labels[d],0,0),b.restore()):b.fillText(a.labels[d],n+d*k,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+d*k,p+3),c.scaleShowGridLines&&0<d?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+d*k,5)):b.lineTo(n+d*k,p+3),b.stroke();b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor; +b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*m),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*m)):b.lineTo(n-0.5,p-(d+1)*m),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*m)},function(d){function e(b,c){return p-d*v(a.datasets[b].data[c],j,m)}for(var f=0;f<a.datasets.length;f++){b.strokeStyle=a.datasets[f].strokeColor; +b.lineWidth=c.datasetStrokeWidth;b.beginPath();b.moveTo(n,p-d*v(a.datasets[f].data[0],j,m));for(var g=1;g<a.datasets[f].data.length;g++)c.bezierCurve?b.bezierCurveTo(n+k*(g-0.5),e(f,g-1),n+k*(g-0.5),e(f,g),n+k*g,e(f,g)):b.lineTo(n+k*g,e(f,g));b.stroke();c.datasetFill?(b.lineTo(n+k*(a.datasets[f].data.length-1),p),b.lineTo(n,p),b.closePath(),b.fillStyle=a.datasets[f].fillColor,b.fill()):b.closePath();if(c.pointDot){b.fillStyle=a.datasets[f].pointColor;b.strokeStyle=a.datasets[f].pointStrokeColor;b.lineWidth= +c.pointDotStrokeWidth;for(g=0;g<a.datasets[f].data.length;g++)b.beginPath(),b.arc(n+k*g,p-d*v(a.datasets[f].data[g],j,m),c.pointDotRadius,0,2*Math.PI,!0),b.fill(),b.stroke()}}},b)},L=function(a,c,b){var d,l,g,h,f,m,j,e,k,t,r,n,p,s,w=0;f=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(e=0;e<a.labels.length;e++)d=b.measureText(a.labels[e]).width,t=d>t?d:t;q/a.labels.length<t?(w=45,q/a.labels.length<Math.cos(w)*t?(w=90,f-=t):f-=Math.sin(w)*t):f-=c.scaleFontSize;e=c.scaleFontSize; +f=f-5-e;d=Number.MIN_VALUE;l=Number.MAX_VALUE;for(g=0;g<a.datasets.length;g++)for(h=0;h<a.datasets[g].data.length;h++)a.datasets[g].data[h]>d&&(d=a.datasets[g].data[h]),a.datasets[g].data[h]<l&&(l=a.datasets[g].data[h]);g=Math.floor(f/(0.66*e));h=Math.floor(0.5*(f/e));e=c.scaleShowLabels?c.scaleLabel:"";if(c.scaleOverride){j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]};for(d=0;d<j.steps;d++)e&&j.labels.push(y(e,{value:(c.scaleStartValue+c.scaleStepWidth*d).toFixed(A(c.scaleStepWidth))}))}else j= +D(f,g,h,d,l,e);m=Math.floor(f/j.steps);e=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;for(d=0;d<j.labels.length;d++)l=b.measureText(j.labels[d]).width,e=l>e?l:e;e+=10}r=q-e-t;k=Math.floor(r/a.labels.length);s=(k-2*c.scaleGridLineWidth-2*c.barValueSpacing-(c.barDatasetSpacing*a.datasets.length-1)-(c.barStrokeWidth/2*a.datasets.length-1))/a.datasets.length;n=q-t/2-r;p=f+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor; +b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<w?(b.save(),b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<w?(b.translate(n+d*k,p+c.scaleFontSize),b.rotate(-(w*(Math.PI/180))),b.fillText(a.labels[d],0,0),b.restore()):b.fillText(a.labels[d],n+d*k+k/2,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+(d+1)*k,p+3),b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+(d+1)*k,5),b.stroke();b.lineWidth= +c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*m),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*m)):b.lineTo(n-0.5,p-(d+1)*m),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*m)},function(d){b.lineWidth=c.barStrokeWidth;for(var e=0;e<a.datasets.length;e++){b.fillStyle= +a.datasets[e].fillColor;b.strokeStyle=a.datasets[e].strokeColor;for(var f=0;f<a.datasets[e].data.length;f++){var g=n+c.barValueSpacing+k*f+s*e+c.barDatasetSpacing*e+c.barStrokeWidth*e;b.beginPath();b.moveTo(g,p);b.lineTo(g,p-d*v(a.datasets[e].data[f],j,m)+c.barStrokeWidth/2);b.lineTo(g+s,p-d*v(a.datasets[e].data[f],j,m)+c.barStrokeWidth/2);b.lineTo(g+s,p);c.barShowStroke&&b.stroke();b.closePath();b.fill()}}},b)},E=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame|| +window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)},F={}}; \ No newline at end of file Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-03 00:47:03
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/af7fe153d0b3/ Changeset: af7fe153d0b3 User: alllee Date: 2013-04-03 00:03:16 Summary: patching input-block-level and input-prepend from https://gist.github.com/matt-mozzy/5020957 Affected #: 3 files diff -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -28,19 +28,17 @@ </div></div><form id="chat-form" class='form-inline' data-bind='submit: submitChatMessage' > - <div class='input-prepend input-append'> + <div class='input-prepend input-block-level'><span class='add-on'><i class='text-info icon-comment'></i></span> - <input id='chatMessage' type="text" placeholder="Enter a chat message"> - <button class='btn btn-primary'>Send</button> + <input id='chatMessage' type="text" placeholder="Chat with your group"></div></form><div class='chat-sidebar'><div id='chat-div'><div class='chat-messages' data-bind='foreach: chatMessages'> - <i class='icon-user muted'></i><strong>Participant <span data-bind='text: participant_number'></strong><b class='pull-right muted' data-bind='text: short_date_created'></b> - <p> + <i class='icon-user muted'></i><strong data-bind='text: participant_number'></strong><small><i class='icon-double-angle-right'></i></small><span data-bind='text: message'></span> - </p> + <br></div></div></div> diff -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 vcweb/static/css/boundaries/style.css --- a/vcweb/static/css/boundaries/style.css +++ b/vcweb/static/css/boundaries/style.css @@ -3,17 +3,15 @@ border: 1px solid #e3e3e3; padding: 0px 0px 0px 0px; margin: 0px; - height: 520px; } .chat-messages { padding: 5px; } #chat-div { overflow: auto; - height: inherit; + height: 820px; } #chatMessage { - width: auto; } .boundaries-status-dashboard p { padding-top: 15px; diff -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 vcweb/static/css/style.css --- a/vcweb/static/css/style.css +++ b/vcweb/static/css/style.css @@ -122,6 +122,20 @@ col.error { background-color: #f2dede; } +.input-prepend.input-block-level { + display: table; + width: 100%; +} +.input-prepend.input-block-level .add-on { + display: table-cell; +} +.input-prepend.input-block-level > input { + box-sizing: border-box; + height: 30px; + display: table-cell; + width: 100%; + border-left-style: none; +} /* @font-face { font-family: Entypo; https://bitbucket.org/virtualcommons/vcweb/commits/a8327e0d4738/ Changeset: a8327e0d4738 User: alllee Date: 2013-04-03 02:46:52 Summary: updating set_harvest_decision to create a new harvest decision always and deactivate the previous ones Affected #: 5 files diff -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -201,15 +201,22 @@ logger.error("Received round started signal with no experiment: %s", sender) raise ValueError("Received round started signal with no experiment") round_configuration = experiment.current_round + round_data = experiment.get_round_data(round_configuration) logger.debug("setting up round %s", round_configuration) # initialize group and participant data values if round_configuration.is_playable_round: experiment.initialize_data_values( group_cluster_parameters=(get_regrowth_parameter(), get_resource_level_parameter(),), group_parameters=(get_regrowth_parameter(), get_group_harvest_parameter(), get_resource_level_parameter(),), - participant_parameters=(get_harvest_decision_parameter(), get_storage_parameter(), + participant_parameters=(get_storage_parameter(), get_player_status_parameter(),) ) +# check for dead participants and set their ready and harvest decision flags + deceased_participants = ParticipantRoundDataValue.objects.select_related('participant_group_relationship').filter(parameter=get_player_status_parameter(), + round_data=round_data, boolean_value=False) + for prdv in deceased_participants: + pgr = prdv.participant_group_relationship + set_harvest_decision(pgr, 0, round_data, submitted=True) ''' during a practice or regular round, set up resource levels, participant harvest decision parameters, and group formation @@ -217,7 +224,6 @@ if should_reset_resource_level(round_configuration): initial_resource_level = get_max_resource_level(round_configuration) logger.debug("Resetting resource level for %s to %d", round_configuration, initial_resource_level) - round_data = experiment.get_round_data(round_configuration) for group in experiment.group_set.filter(session_id=round_configuration.session_id): ''' set resource level to initial default ''' existing_resource_level = get_resource_level_dv(group, round_data, round_configuration) diff -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -38,7 +38,6 @@ harvest_decision = form.cleaned_data['integer_decision'] round_data = experiment.current_round_data set_harvest_decision(pgr, harvest_decision, round_data, submitted=True) - pgr.set_participant_ready(round_data) message = "%s harvested %s trees" experiment.log(message % (pgr.participant, harvest_decision)) response_dict = { diff -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -938,7 +938,10 @@ all_round_data = [] for round_data in self.round_data_set.reverse(): group_data_values = [gdv.to_dict() for gdv in round_data.group_data_value_set.select_related('group', 'parameter').all()] - participant_data_values = [pdv.to_dict(include_email=True, cacheable=True) for pdv in round_data.participant_data_value_set.select_related('participant_group_relationship__participant__user', 'parameter').all()] +# FIXME: do this more efficiently + participant_data_values = [pdv.to_dict(include_email=True, cacheable=True) + for pdv + in round_data.participant_data_value_set.select_related('participant_group_relationship__participant__user', 'parameter').exclude(parameter=get_chat_message_parameter())] rc = round_data.round_configuration all_round_data.append({ 'roundDataId': "roundData_%s" % round_data.pk, diff -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html +++ b/vcweb/core/templates/experimenter/monitor.html @@ -20,7 +20,7 @@ <div class='btn-toolbar'><div class='btn-group'><a class='btn btn-primary' data-bind='click: updateParticipants' data-content='Updates all connected participants.' ><i class='icon-exchange'></i> update participants</a> - <a class='btn btn-primary' data-bind='click: update' data-content='Updates this pagedata.' ><i class='icon-refresh'></i> refresh this page</a> + <a class='btn btn-primary' data-bind='click: refresh' data-content='Updates this page.' ><i class='icon-refresh'></i> refresh this page</a></div></div><div class='btn-toolbar'> @@ -76,6 +76,7 @@ Registered participants: <span id='participantCountId' data-bind='text:participantCount' class='badge badge-info'></span></a></div> + {% comment %} switch to KO for this, doesn't get updated properly when transitioning rounds {% endcomment %} <div id='registeredParticipants' class='accordion-body collapse'><div class='accordion-inner'> {% regroup registeredParticipants by group as group_list %} @@ -229,6 +230,9 @@ } model.tick = function() { model.timeRemaining(model.timeRemaining() - 1); + if (model.timeRemaining() % 10 == 0) { + model.checkAllParticipantsReady(); + } if (model.timeRemaining() < 0) { model.addMessage("Round time has expired!"); model.clearCurrentInterval(); @@ -245,16 +249,19 @@ } // FIXME: factor out the code duplication with this and confirmExperimentControllerAction for // showing the modal and invoking the ajax call if possible + model.refresh = function() { + console.debug("refreshing page"); + window.location.reload(true); + } model.update = function(localModel, evt) { $('#progress-modal').modal('show'); Dajaxice.vcweb.core.get_experiment_model(function(data) { - console.debug("model has time remaining: " + model.timeRemaining()); - ko.mapping.fromJS(data, model); - model.startTimer(); - $('#progress-modal').modal('hide'); - - }, - {pk: {{experiment.pk}}}); + ko.mapping.fromJS(data, model); + console.debug("time remaining: " + model.timeRemaining()); + model.startTimer(); + $('#progress-modal').modal('hide'); + }, + {pk: {{experiment.pk}}}); } model.startTimer = function() { if (model.timeRemaining() > 0) { @@ -272,7 +279,6 @@ } model.confirmExperimentControllerAction = function(shouldUpdateParticipants, localModel, evt) { element = evt.target; - console.debug(element); if ($(element).hasClass('disabled')) { console.debug("aborting disabled action: " + element); return false; @@ -296,6 +302,7 @@ return model.isRoundInProgress() ? "stop" : "start"; }); model.checkAllParticipantsReady = function() { + console.debug("checking if all participants are ready"); $.get('/experiment/{{experiment.pk}}/check-ready-participants', function(response) { if (response.all_participants_ready) { model.addMessage("All participants are ready, advancing to next round"); @@ -338,9 +345,9 @@ ko.applyBindings(experimentModel); // establish sockjs websocket connection var s = connect("/experimenter"); - s.onmessage = function(evt) { - console.log("Received event: " + evt); - experiment_event = $.parseJSON(evt.data); + s.onmessage = function(message) { + console.log("sockjs event: " + message); + experiment_event = $.parseJSON(message.data); switch (experiment_event.event_type) { case 'update': console.debug("FIXME: ignoring update requests, patch sockjs broadcast to not send certain messages"); @@ -358,8 +365,6 @@ } }; return experimentModel; - // FIXME: this won't quite work - // $('#participantCountId').popover({ html: true, title: "Participants", content: experimentModel.registeredParticipants() }); } $('[data-content]').popover({placement: 'top', trigger: 'hover'}); // initialize experiment model JSON from experiment model diff -r af7fe153d0b3d365186bcc816f8e1031d3b1faf1 -r a8327e0d4738a2a3c0b66e1291f5d65c85958e95 vcweb/forestry/models.py --- a/vcweb/forestry/models.py +++ b/vcweb/forestry/models.py @@ -99,10 +99,13 @@ def set_harvest_decision(participant_group_relationship=None, value=None, round_data=None, submitted=False): if round_data is None: round_data = participant_group_relationship.current_round_data - prdv = participant_group_relationship.get_data_value(parameter=get_harvest_decision_parameter(), round_data=round_data) - prdv.submitted = submitted - prdv.int_value = value - prdv.save() +# deactivate all previous harvest decisions in this round + ParticipantRoundDataValue.objects.for_participant(participant_group_relationship, + round_data=round_data).update(is_active=False) + return ParticipantRoundDataValue.objects.create(participant_group_relationship=participant_group_relationship, + parameter=get_harvest_decision_parameter(), round_data=round_data, + int_value=value, + submitted=True) def set_resource_level(group, value, round_data=None): return group.set_data_value(parameter=get_resource_level_parameter(), round_data=round_data, value=value) @@ -153,6 +156,7 @@ current_resource_level_dv = get_resource_level_dv(group) current_resource_level = current_resource_level_dv.int_value if current_round_configuration.is_playable_round: + # FIXME: update this to use django queryset aggregation ala boundaries experiment total_harvest = sum( [ hd.value for hd in get_harvest_decisions(group).all() ]) logger.debug("total harvest for playable round: %d", total_harvest) if current_resource_level > 0 and total_harvest > 0: Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: A L. <iss...@bi...> - 2013-04-02 23:39:18
|
New issue 102: boundaries: update harvest decision submission protocol https://bitbucket.org/virtualcommons/vcweb/issue/102/boundaries-update-harvest-decision A Lee: Harvest decision submission: 1. Allow for multiple submissions of harvest decisions, each one invalidating the last 2. Change from select box to selectable trees labeled 0 - 10 3. Each time user selects a tree number it gets stored on the server side. Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: A L. <iss...@bi...> - 2013-04-02 21:42:31
|
New issue 101: set up ssl proxy for sockjs-tornado https://bitbucket.org/virtualcommons/vcweb/issue/101/set-up-ssl-proxy-for-sockjs-tornado A Lee: http://stackoverflow.com/questions/14946015/proxying-requests-to-tornado-with-apache-502-error Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: <com...@bi...> - 2013-04-02 21:41:27
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/de9e1276f2d7/ Changeset: de9e1276f2d7 User: alllee Date: 2013-04-02 23:41:15 Summary: get_average_harvest was reporting over the current round which was why it was always 0. it now displays the previous round's average harvest - fixes issue 100 highlighting column for the given participant in group status table Affected #: 3 files diff -r 908f369f9df1ce5110cb95876f9d1432441ad3ce -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -5,7 +5,7 @@ <link rel='stylesheet' href='{% static "css/boundaries/style.css" %}'/> {% endblock %} {% block content %} -<h3>Round <span data-bind='text: roundSequenceLabel'></span></h3> +<h3><span data-bind='text: roundSequenceLabel'></span></h3><div data-bind='template: { name: templateId(), afterRender: afterRenderTemplate }'></div><div id='progress-modal' class='modal hide fade'> @@ -336,11 +336,16 @@ </div><div class='span4'><h3>Group Status</h3> - <table class='table table-bordered table-condensed table-striped'> + <table class='table table-bordered table-condensed'> + <colgroup> + <!-- ko foreach: playerData --> + <col data-bind='css: { success: id() == $root.participantGroupId() }'> + <!-- /ko --> + </colgroup><thead><tr><th>Player</th><!-- ko foreach: playerData --> - <th data-bind='text: id'></th> + <th data-bind='text: number'></th><!-- /ko --></tr></thead> @@ -358,9 +363,9 @@ <!-- /ko --></tr><tr> - <td>Alive</td> + <td>Status</td><!-- ko foreach: playerData --> - <td data-bind='css: { "text-error": ! alive(), "text-success": alive() }, text: alive() ? "Yes" : "No"'></td> + <td data-bind='css: { "text-error": ! alive(), "text-success": alive() }, text: alive() ? "Alive" : "Deceased"'></td><!-- /ko --></tr></tbody> @@ -377,15 +382,23 @@ <div data-bind="ifnot: isResourceEmpty" id='resourceDisplay'><div class='alert alert-info'>There are <strong class='badge badge-success' data-bind='text:resourceLevel'></strong> trees remaining in the forest.</div> + <div class='well'><div data-bind='style: { width: resourceImageWidth, height: resourceImageHeight, background: resourceImageBackgroundUrl }'> </div> + </div></div><div data-bind="if: isResourceEmpty"> + <div class='well'> + <center><img src="{% static 'images/forestry/deforestation.jpg' %}" class="img-polaroid" width="425" + height="282"></center> + </div> + <!-- this centers the image <div style='padding: 8px; margin: auto; border: solid 1px; background: url("{{STATIC_URL}}images/forestry/deforestation.jpg") no-repeat center; height: 282px; width:425px;'> </div> - <div class='alert alert-error'>There are no more trees to harvest. Please wait until the next round begins.</div> + --> + <div class='alert alert-error'><i class='icon-warning-sign'></i> There are no more trees to harvest. Please wait until the next round begins.</div></div><div data-bind='if: canObserveOtherGroup'><h3>Observe Other Group</h3> @@ -415,6 +428,7 @@ </div></div></div> +<div data-bind='visible: ! isResourceEmpty()'><h3>Harvest</h3><div data-bind='if: submitted'><div class='alert alert-success'> @@ -444,6 +458,7 @@ </div></form></div> +</div></script><script src='{% static "js/bootstrap-tour.js" %}'></script><script type="text/javascript"> diff -r 908f369f9df1ce5110cb95876f9d1432441ad3ce -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -118,7 +118,8 @@ own_resource_level = get_resource_level(own_group) last_harvest_decision = get_last_harvest_decision(participant_group_relationship, round_data=previous_round_data) experiment_model_dict['playerData'] = [{ - 'id': pgr.participant_number, + 'id': pgr.pk, + 'number': pgr.participant_number, 'lastHarvestDecision': get_last_harvest_decision(pgr, round_data=previous_round_data), 'alive': get_player_status(pgr, current_round_data), 'storage': get_storage(pgr, current_round_data), @@ -142,7 +143,7 @@ experiment_model_dict['canObserveOtherGroup'] = True other_group = own_group.get_related_group() experiment_model_dict['otherGroupResourceLevel'] = get_resource_level(other_group, current_round_data) - experiment_model_dict['otherGroupAverageHarvest'] = get_average_harvest(other_group, current_round_data) + experiment_model_dict['otherGroupAverageHarvest'] = get_average_harvest(other_group, previous_round_data) experiment_model_dict['otherGroupAverageStorage'] = get_average_storage(other_group, current_round_data) return dumps(experiment_model_dict) diff -r 908f369f9df1ce5110cb95876f9d1432441ad3ce -r de9e1276f2d7e5e76da4574e00ce27230db0b6c1 vcweb/static/css/style.css --- a/vcweb/static/css/style.css +++ b/vcweb/static/css/style.css @@ -113,6 +113,15 @@ .text-gold { color: #DFB03D; } +col.success { + background-color: #dff0d8; +} +col.warning { + background-color: #fcf8e3; +} +col.error { + background-color: #f2dede; +} /* @font-face { font-family: Entypo; Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: A L. <iss...@bi...> - 2013-04-02 19:00:07
|
New issue 100: observe other group average harvest broken https://bitbucket.org/virtualcommons/vcweb/issue/100/observe-other-group-average-harvest-broken A Lee: average harvest is broken when observing the other group Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: <com...@bi...> - 2013-04-02 18:44:56
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/908f369f9df1/ Changeset: 908f369f9df1 User: alllee Date: 2013-04-02 20:44:47 Summary: adding round numbers for pretesting Affected #: 1 file diff -r 7befe4f6b6ecd1eb69926e36e6695d3ef63fa6d0 -r 908f369f9df1ce5110cb95876f9d1432441ad3ce vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -5,6 +5,7 @@ <link rel='stylesheet' href='{% static "css/boundaries/style.css" %}'/> {% endblock %} {% block content %} +<h3>Round <span data-bind='text: roundSequenceLabel'></span></h3><div data-bind='template: { name: templateId(), afterRender: afterRenderTemplate }'></div><div id='progress-modal' class='modal hide fade'> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-02 18:19:59
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/7befe4f6b6ec/ Changeset: 7befe4f6b6ec User: alllee Date: 2013-04-02 20:19:47 Summary: updated max resource level calculations, fixes issue 98 Affected #: 4 files diff -r dc5e00007bd35954a69e7aadcca04b334b7beb76 -r 7befe4f6b6ecd1eb69926e36e6695d3ef63fa6d0 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -19,7 +19,7 @@ MAX_RESOURCE_LEVEL = 240 MAX_SHARED_RESOURCE_LEVEL = 480 -RESOURCES_PER_PARTICIPANT = 60 +INITIAL_RESOURCES_PER_PARTICIPANT_PER_ROUND = 3 ''' Experiment Parameters and Metadata Accessors @@ -82,11 +82,14 @@ return round_configuration.get_parameter_value(parameter=get_shared_resource_enabled_parameter(), default=False).boolean_value -def get_max_resource_level(experiment_configuration): - return RESOURCES_PER_PARTICIPANT * experiment_configuration.max_group_size +def get_max_resource_level(round_configuration): + ec = round_configuration.experiment_configuration +# FIXME: number of rounds currently hard coded to be 20 for regular rounds, 10 for practice rounds + number_of_rounds = 20 if round_configuration.is_regular_round else 10 + return INITIAL_RESOURCES_PER_PARTICIPANT_PER_ROUND * ec.max_group_size * number_of_rounds def get_initial_resource_level(round_configuration, default=None): - return get_max_resource_level(round_configuration.experiment_configuration) + return get_max_resource_level(round_configuration) def should_reset_resource_level(round_configuration): return round_configuration.get_parameter_value(parameter=get_reset_resource_level_parameter(), @@ -212,7 +215,7 @@ formation ''' if should_reset_resource_level(round_configuration): - initial_resource_level = get_max_resource_level(round_configuration.experiment_configuration) + initial_resource_level = get_max_resource_level(round_configuration) logger.debug("Resetting resource level for %s to %d", round_configuration, initial_resource_level) round_data = experiment.get_round_data(round_configuration) for group in experiment.group_set.filter(session_id=round_configuration.session_id): @@ -269,7 +272,7 @@ def update_resource_level(experiment, group, round_data, regrowth_rate, max_resource_level=None): if max_resource_level is None: - max_resource_level = get_max_resource_level(experiment.experiment_configuration) + max_resource_level = get_max_resource_level(round_data.round_configuration) current_resource_level_dv = get_resource_level_dv(group, round_data) current_resource_level = current_resource_level_dv.int_value # FIXME: would be nicer to extend Group behavior and have group.get_total_harvest() instead of @@ -287,6 +290,7 @@ resource_regrowth = calculate_regrowth(current_resource_level, regrowth_rate, max_resource_level) group.log("Regrowth: adding %s to current resource level %s" % (resource_regrowth, current_resource_level)) set_regrowth(group, resource_regrowth, round_data) + # clamp resource current_resource_level_dv.int_value = min(current_resource_level + resource_regrowth, max_resource_level) current_resource_level_dv.save() else: @@ -308,11 +312,11 @@ group.copy_to_next_round(current_resource_level_dv) -# FIXME: try to reduce duplication between this and update_resource_level +# FIXME: reduce duplication between this and update_resource_level def update_shared_resource_level(experiment, group_cluster, round_data, regrowth_rate, max_resource_level=None): logger.debug("updating shared resource level") if max_resource_level is None: - max_resource_level = get_max_resource_level(experiment.experiment_configuration) + max_resource_level = get_max_resource_level(round_data.round_configuration) max_resource_level = max_resource_level * group_cluster.size shared_resource_level_dv = get_shared_resource_level_dv(cluster=group_cluster, round_data=round_data) shared_resource_level = shared_resource_level_dv.int_value @@ -336,6 +340,7 @@ resource_regrowth = calculate_regrowth(shared_resource_level, regrowth_rate, max_resource_level) group.log("Regrowth: adding %s to shared resource level %s" % (resource_regrowth, shared_resource_level)) group_cluster.set_data_value(parameter=get_regrowth_parameter(), round_data=round_data, value=resource_regrowth) + # clamp resource level to max_resource_level shared_resource_level_dv.int_value = min(shared_resource_level + resource_regrowth, max_resource_level) shared_resource_level_dv.save() if experiment.has_next_round: @@ -387,6 +392,6 @@ update_participants(experiment, round_data) -def calculate_regrowth(resource_level, regrowth_rate, max_resource_level=240): +def calculate_regrowth(resource_level, regrowth_rate, max_resource_level): return (regrowth_rate * resource_level) * (1 - (resource_level / float(max_resource_level))) diff -r dc5e00007bd35954a69e7aadcca04b334b7beb76 -r 7befe4f6b6ecd1eb69926e36e6695d3ef63fa6d0 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -439,7 +439,7 @@ <select id='harvestDecisionSelect' name='harvest_decision' required="required" form="vcweb-form" data-bind='options: harvestDecisionOptions, value: harvestDecision'></select></div> - <button id='submitDecision' type='submit' class='btn btn-primary'>Submit</button> + <button id='submitDecisionButton' type='submit' class='btn btn-primary'>Submit</button></div></form></div> diff -r dc5e00007bd35954a69e7aadcca04b334b7beb76 -r 7befe4f6b6ecd1eb69926e36e6695d3ef63fa6d0 vcweb/boundaries/tests.py --- a/vcweb/boundaries/tests.py +++ b/vcweb/boundaries/tests.py @@ -25,7 +25,7 @@ def test_adjust_harvest_decisions(self): e = self.experiment e.activate() - for rl in range(1, 40): + for rl in range(30, 40): e.start_round() self.create_harvest_decisions() for g in e.groups: @@ -36,6 +36,13 @@ for pgr in self.participant_group_relationships: self.assertTrue(get_harvest_decision(pgr) <= 8) +class MaxResourceLevelTest(BaseTest): + def test_max_resource_level(self): + e = self.experiment + e.activate() + self.assertEqual(get_max_resource_level(e.current_round), 5 * 3 * 20) + + class InitialDataTest(BaseTest): def test_experiment_metadata(self): self.assertIsNotNone(get_experiment_metadata()) diff -r dc5e00007bd35954a69e7aadcca04b334b7beb76 -r 7befe4f6b6ecd1eb69926e36e6695d3ef63fa6d0 vcweb/vcweb-sockjs.py --- a/vcweb/vcweb-sockjs.py +++ b/vcweb/vcweb-sockjs.py @@ -236,6 +236,9 @@ # replace with namedtuple class Struct: + def to_json(self): + return json.dumps(self.__dict__) + def __init__(self, **attributes): self.__dict__.update(attributes) @@ -298,10 +301,9 @@ logger.debug("handling participant ready event %s for experiment %s", event, experiment) (per, valid) = self.verify_auth_token(event) if valid: - if getattr(event, 'message', None): + if not getattr(event, 'message', None): event.message = "Participant %s is ready." % per.participant - # FIXME: any reason to bootstrap this - connection_manager.broadcast(experiment, create_message_event(event.message, event_type=READY_EVENT_TYPE)) + connection_manager.broadcast(experiment, event.to_json()) else: logger.warning("Invalid auth token for participant %s", per) self.send(UNAUTHORIZED_EVENT) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-04-02 16:37:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/dc5e00007bd3/ Changeset: dc5e00007bd3 User: alllee Date: 2013-04-02 18:37:35 Summary: - fixing a slew of bugs with harvest decision form submission - replacing select options with data-bind options (was causing the refresh display error bug on harvestDecision) - setting visibility on the harvest decision form based on whether the form is submitted or not - moving popover initialization into afterRenderTemplate Affected #: 1 file diff -r 56af1f18ed4d23b02356b5187fd58a3b599bc074 -r dc5e00007bd35954a69e7aadcca04b334b7beb76 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -26,11 +26,11 @@ <i class='icon-warning-sign'></i> Chat is currently disabled. </div></div> -<form id="chat-form" class='form-inline'> +<form id="chat-form" class='form-inline' data-bind='submit: submitChatMessage' ><div class='input-prepend input-append'><span class='add-on'><i class='text-info icon-comment'></i></span><input id='chatMessage' type="text" placeholder="Enter a chat message"> - <button class='btn btn-primary' data-bind='click: submitChatMessage'>Send</button> + <button class='btn btn-primary'>Send</button></div></form><div class='chat-sidebar'> @@ -386,12 +386,6 @@ </div><div class='alert alert-error'>There are no more trees to harvest. Please wait until the next round begins.</div></div> -<div data-bind='if: submitted'> - <div class='alert alert-error'> - You have submitted a harvest decision for <span class='badge badge-success' data-bind='text: harvestDecision'></span> trees. - </div> -</div> - <div data-bind='if: canObserveOtherGroup'><h3>Observe Other Group</h3><div class='row'> @@ -421,6 +415,13 @@ </div></div><h3>Harvest</h3> +<div data-bind='if: submitted'> + <div class='alert alert-success'> + <i class='icon-leaf'></i> You have submitted a harvest decision for <span class='badge badge-info' + data-bind='text: harvestDecision'></span> trees. Please wait quietly while the rest of the participants submit + their decisions. + </div> +</div><div data-bind='ifnot: alive'><div class='alert alert-error'><b><i class='icon-ambulance'></i></b> You didn't harvest enough trees to meet the cost of living and are now @@ -428,21 +429,17 @@ </div></div><div data-bind='ifnot: isResourceEmpty'> - <form id='vcweb-form' action='' method='post' class='form-horizontal' > + <form id='vcweb-form' data-bind='submit: submitDecision' action='' method='post' class='form-horizontal' > {% csrf_token %} - <div class='control-group'> + <div id='harvestDecisionDiv' data-bind='visible: !submitted()' class='control-group'><div class='input-prepend'><span class='add-on'><i class='icon-leaf'></i></span><input id='participantGroupId' type='hidden' name='participant_group_id' data-bind='value: participantGroupId'/><input id='harvestDecisionTextInput' type='hidden' name='integer_decision' data-bind='value: harvestDecision'> - <select id='harvestDecisionSelect' required="required" form="vcweb-form" data-bind='value: harvestDecision'> - <!-- ko foreach: ko.utils.range(0, maxHarvestDecision()) --> - <option data-bind='value: $data, text: $data'></option> - <!-- /ko --> + <select id='harvestDecisionSelect' name='harvest_decision' required="required" form="vcweb-form" data-bind='options: harvestDecisionOptions, value: harvestDecision'></select> - </div> - <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn btn-primary'>Submit</button> + <button id='submitDecision' type='submit' class='btn btn-primary'>Submit</button></div></form></div> @@ -453,6 +450,9 @@ function ExperimentModel(experimentModelJson) { var self = this; var model = ko.mapping.fromJS(experimentModelJson); + model.harvestDecisionOptions = ko.computed(function() { + return ko.utils.range(0, model.maxHarvestDecision()); + }); model.secondsLeft = ko.observable(0); model.currentInterval = ko.observable(); model.totalEarnings = ko.computed(function() { @@ -479,7 +479,7 @@ tour.addStep({ element: "#dashboard-time", title: "Time Left", placement: "top", content: "The time remaining in this round will be displayed here. It will turn red when " + - experimentModel.warningCountdownTime() + " seconds are left."}); + model.warningCountdownTime() + " seconds are left."}); tour.addStep({ element: "#chatMessage", title: "Text Chat", placement: "left", content: "If chat is enabled, you can communicate with your group by typing messages into this box and hitting the enter key or clicking 'Send'."}); @@ -552,6 +552,7 @@ model.disableChatForm(); return; } + model.enableHarvestForm(); console.debug("starting round"); if (isInt(model.timeRemaining()) && model.timeRemaining() > 0) { model.setupChat(); @@ -559,12 +560,6 @@ model.setCurrentInterval( setInterval(function() { model.tick(); - if (model.secondsLeft() > 30 && model.waitThirtySeconds()) { - model.disableHarvestForm(); - } - else { - model.enableHarvestForm(); - } if (! model.isTimerRunning()) { model.submitDecision(); model.clearCurrentInterval(); @@ -574,29 +569,27 @@ } }; model.submitDecision = function(data, evt) { - model.enableHarvestForm(); var formData = $('#vcweb-form').serialize(); - model.disableHarvestForm(); - model.disableChatForm(); + model.submitted(true); console.debug(formData); $.post('submit-harvest-decision', formData, function(response) { console.log(response); // model.update($.parseJSON(response.experimentModelJson)); getWebSocket().send(createReadyEvent(response.message)); - model.submitted(true); model.clearCurrentInterval(); model.secondsLeft(0); }); + return false; } model.submitChatMessage = function(data, evt) { - evt.preventDefault(); - console.log("clicking chat message"); + console.log("submitting chat message"); var message = $('#chatMessage').val(); if (message) { $('#chatMessage').val(''); getWebSocket().send(createMessageEvent(message)); $('#chatMessage').focus(); } + return false; } model.update = function() { $.get('view-model', { participant_group_id: model.participantGroupId() }, function(data) { @@ -615,10 +608,10 @@ $(formId + " :input").prop("disabled", disabled); } model.enableHarvestForm = function() { - model.setFormDisabled("#vcweb-form", false); + $('#harvestDecisionDiv').show(); } model.disableHarvestForm = function() { - model.setFormDisabled("#vcweb-form", true); + $('#harvestDecisionDiv').hide(); } model.enableChatForm = function() { model.setFormDisabled("#chat-form", false); @@ -632,10 +625,12 @@ model.chatEnabled(! chatDisabled); } model.afterRenderTemplate = function(elements) { + console.debug("after render template: " + model.harvestDecision()); if (model.templateId() === "REGULAR") { model.startRound() } model.setupChat(); + $('[data-content]').popover({placement: 'top', trigger: 'hover'}); } return model; } @@ -643,14 +638,14 @@ var experimentModel = new ExperimentModel(experimentModelJson); ko.applyBindings(experimentModel); var s = connect(); - s.onmessage = function(json) { - console.debug(json); - var data = $.parseJSON(json.data); + s.onmessage = function(message) { + console.debug(message); + var data = $.parseJSON(message.data); console.debug(data); switch (data.event_type) { case 'chat': + console.debug("received chat message:" + message); experimentModel.chatMessages.unshift(data); - console.debug("received chat message:" + json); break; case 'update': $('#progress-modal').modal('show'); @@ -662,14 +657,14 @@ }); break; default: - console.debug("unhandled json message:" + json); + console.debug("unhandled message:" + message); break; } }; return experimentModel; } - var experimentModel = initialize($.parseJSON("{{ experimentModelJson|escapejs }}")); - $('[data-content]').popover({placement: 'top', trigger: 'hover'}); + model = initialize($.parseJSON("{{ experimentModelJson|escapejs }}")); }); + var model; </script> {% endblock %} Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |