Skip to content

Commit e9233c0

Browse files
committed
CSL-2041: Improve can_show()
Clean up a few other small issues in tour.
1 parent 1e37463 commit e9233c0

6 files changed

Lines changed: 53 additions & 42 deletions

File tree

src/frontend/js/tour.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@
5959
$next[0].focus();
6060
var name = $next.attr('id').replace('tour_', '');
6161
window.parent.clusiveEvents.addTipViewToQueue(name);
62-
}
62+
};
6363

6464
// Hide tip/tour tooltip if showing
6565
$('#tip').CFW_Tooltip('hide');
6666

6767
if ($curr.length) {
68-
// Wait until hide animation is complete before callling show
68+
// Wait until hide animation is complete before calling show
6969
$curr.CFW_Popover('hide').CFW_transition(null, function() {
7070
document.body.classList.add(CLASS_TOUR);
7171
$trigger.one('afterShow.cfw.popover', showComplete);
@@ -102,4 +102,4 @@
102102
};
103103

104104
window.tour = tourModule.prototype;
105-
}(jQuery));
105+
}(jQuery));

src/pages/templates/pages/partial/dashboard_panel_affect.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="box" {% if clusive_user.role == 'ST' %} data-clusive-tip-id="student_reactions" {% endif %}>
1+
<div class="box" data-clusive-tip-id="student_reactions">
22
<h2>Your thoughts <span class="icon-thought" aria-hidden="true"></span></h2>
33
<div class="box-divider"></div>
44
{% if data.empty %}

src/roster/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@ class UserStats (models.Model):
580580
# Total active time using Clusive
581581
active_duration = models.DurationField(null=True)
582582

583+
def __str__(self):
584+
return '<Stats for %s>' % (self.user)
585+
583586
class Meta:
584587
verbose_name = 'user stats'
585588
verbose_name_plural = 'user stats'

src/shared/templates/shared/partial/popover_tour.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
</div>
133133
<div class="popover-body">
134134
<div class="embed-fluid embed-fluid-16x9 mb-0_5">
135-
<iframe id="studentReactionsIframe" src="https://videos.sproutvideo.com/embed/119ed9b21f1aeac598/961f727539a6dc9b?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Your students reactions video"></iframe>
135+
<iframe id="studentReactionsIframe0" src="https://videos.sproutvideo.com/embed/119ed9b21f1aeac598/961f727539a6dc9b?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Your students reactions video"></iframe>
136136
</div>
137137
<p>Click on a reaction word and see a list of Clusive readings that have inspired your students, and other Clusive readers, to react with that word.</p>
138138
{% include "shared/partial/popover_tour_footer.html" with resource_id="SREACT" resource_name="your students&apos; reactions" %}
@@ -144,7 +144,7 @@
144144
</div>
145145
<div class="popover-body">
146146
<div class="embed-fluid embed-fluid-16x9 mb-0_5">
147-
<iframe id="studentReactionsIframe" src="https://videos.sproutvideo.com/embed/449ed4bf1c1ee2cbcd/7eeb1eb5c62a2389?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Your thoughts video"></iframe>
147+
<iframe id="studentReactionsIframe1" src="https://videos.sproutvideo.com/embed/449ed4bf1c1ee2cbcd/7eeb1eb5c62a2389?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Your thoughts video"></iframe>
148148
</div>
149149
<p>Click on a reaction word and see Clusive readings that inspired you and others to react with that word.</p>
150150
{% include "shared/partial/popover_tour_footer.html" with resource_id=None %}
@@ -160,7 +160,7 @@
160160
</div>
161161
<div class="popover-body">
162162
<div class="embed-fluid embed-fluid-16x9 mb-0_5">
163-
<iframe id="readingDataIframe" src="https://videos.sproutvideo.com/embed/449ed9b61c1aecc5cd/5993d5016938853d?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Student Reading data video"></iframe>
163+
<iframe id="readingDataIframe0" src="https://videos.sproutvideo.com/embed/449ed9b61c1aecc5cd/5993d5016938853d?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="How to find and use Student Reading data video"></iframe>
164164
</div>
165165
<p>Get a quick view of student reading interests and learning. Check out reading data on assigned and popular readings. Get a summary of student self-rating of learning, and see answers to prompts you have customized.</p>
166166
{% include "shared/partial/popover_tour_footer.html" with resource_id="SREADP" resource_name="student reading data" %}
@@ -172,7 +172,7 @@
172172
</div>
173173
<div class="popover-body">
174174
<div class="embed-fluid embed-fluid-16x9 mb-0_5">
175-
<iframe id="readingDataIframe" src="https://videos.sproutvideo.com/embed/ea9ed4b41b15e2c263/bd13498e66ded346?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="Your Reading video"></iframe>
175+
<iframe id="readingDataIframe1" src="https://videos.sproutvideo.com/embed/ea9ed4b41b15e2c263/bd13498e66ded346?type=hd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen aria-label="Your Reading video"></iframe>
176176
</div>
177177
<p>See assigned readings your recent readings, and popular readings to check out. Go to the library to find more things to read. Have a document you want to upload? Click Upload a new reading to get started!</p>
178178
{% include "shared/partial/popover_tour_footer.html" with resource_id=None %}

src/tips/models.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
'wordbank',
3636
]
3737

38+
RES_READING_TIPS = [
39+
'settings',
40+
'readaloud',
41+
'context',
42+
'wordbank',
43+
]
44+
3845
LIBRARY_TIPS = [
3946
'view',
4047
'filters',
@@ -64,7 +71,7 @@
6471
PAGE_TIPS_MAP = {
6572
'Dashboard': DASHBOARD_TIPS,
6673
'Reading': READING_TIPS,
67-
'ResourceReading': READING_TIPS,
74+
'ResourceReading': RES_READING_TIPS,
6875
'Library': LIBRARY_TIPS,
6976
'Wordbank': WORD_BANK_TIPS,
7077
'Manage': MANAGE_TIPS,
@@ -86,29 +93,28 @@ class TipType(models.Model):
8693
max = models.PositiveSmallIntegerField(verbose_name='Maximum times to show')
8794
interval = models.DurationField(verbose_name='Interval between shows')
8895

89-
def can_show(self, page: str, version_count: int, user: ClusiveUser):
96+
def can_show(self, page: str, version_count: int, user: ClusiveUser, stats: UserStats):
9097
"""Test whether this tip can be shown on a particular page"""
91-
is_student_or_guest = user.role == Roles.STUDENT or user.role == Roles.GUEST
92-
# Teacher/parent-only tips
93-
if (self.name in TEACHER_ONLY_TIPS or page == 'ResourceReading') and is_student_or_guest:
98+
is_student_or_guest = not user.can_manage_periods
99+
100+
# Check for proper role
101+
if self.name in TEACHER_ONLY_TIPS and is_student_or_guest:
102+
return False
103+
104+
# Check for proper page
105+
if not self.name in PAGE_TIPS_MAP.get(page, []):
94106
return False
107+
95108
# Switch TipType requires multiple versions
96-
if self.name == 'switch':
97-
return (page == 'Reading' or page == 'ResourceReading') and version_count > 1
98-
# Thoughts TipType is only for students or guests
99-
if self.name == 'thoughts' and not is_student_or_guest:
109+
if self.name == 'switch' and version_count == 1:
100110
return False
101111

102-
# 'wordbank', 'manage', and 'reources' TipTypes appear on multiple pages.
103-
# Check first whether the `page` parameter is 'WordBank', 'Manage', or
104-
# 'Resources'.
105-
if page in PAGES_WITH_OWN_TIP and self.name in PAGE_TIPS_MAP[page]:
106-
return True
107-
# Most tooltips need to check if on correct page
108-
if self.name in PAGE_TIPS_MAP.get(page, []):
109-
return True
110-
# Unknown tip never shown
111-
return False
112+
# student_reactions TipType, for students, requires that they have read at least one book
113+
if self.name == 'student_reactions' and is_student_or_guest and stats and stats.reading_views == 0:
114+
return False
115+
116+
# Passed all tests
117+
return True
112118

113119
def __str__(self):
114120
return '<TipType %s>' % self.name
@@ -195,29 +201,33 @@ def register_action(cls, user: ClusiveUser, action: str, timestamp):
195201
def available_tips(cls, user: ClusiveUser, page: str, version_count: int):
196202
"""Return all tips that are currently available to show this user."""
197203

204+
stats: UserStats
205+
stats = UserStats.for_clusive_user(user)
206+
198207
# All tips are currently disallowed on the user's FIRST reading page view
199208
if page == 'Reading' or page == 'ResourceReading':
200-
stats: UserStats
201-
stats = UserStats.for_clusive_user(user)
202209
if stats.reading_views < 1:
203210
return []
204211

205212
# Check tip history to see which are ready to be shown
206213
histories = TipHistory.objects.filter(user=user).order_by('type__priority')
214+
207215
return [h for h in histories
208-
if h.type.can_show(page=page, version_count=version_count, user=user)
216+
if h.type.can_show(page=page, version_count=version_count, user=user, stats=stats)
209217
and h.ready_to_show()]
210218

211219
@classmethod
212220
def tour_list(cls, user: ClusiveUser, page: str, version_count: int = 0):
213221
"""Return names of all tips that should make up the tour for the given user and page."""
214222
histories = TipHistory.objects.filter(user=user).order_by('type__tour_position')
215-
can_show = [h.type.name for h in histories if h.type.can_show(page=page, version_count=version_count, user=user)]
223+
stats = UserStats.for_clusive_user(user)
224+
can_show = [h.type.name for h in histories if
225+
h.type.can_show(page=page, version_count=version_count, user=user, stats=stats)]
216226
# Showing the 'tour' tip during a tour would be weirdly recursive.
217227
if 'tour' in can_show:
218228
can_show.remove('tour')
219229
logger.debug('Tour list: %s', can_show)
220-
return can_show if len(can_show) > 1 else None
230+
return can_show if len(can_show) > 0 else None
221231

222232
@classmethod
223233
def get_tip_to_show(cls, clusive_user: ClusiveUser, page: str, version_count=0):

src/tips/tests.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import logging
2-
from datetime import datetime, timedelta
2+
from datetime import timedelta
33

44
from django.contrib.auth.models import User
5-
from django.core.exceptions import ValidationError
65
from django.test import TestCase
76
from django.utils import timezone
87

98
from roster.models import ClusiveUser, Roles
10-
11-
from .models import TipType, TEACHER_ONLY_TIPS, DASHBOARD_TIPS, READING_TIPS, \
12-
LIBRARY_TIPS, WORD_BANK_TIPS, MANAGE_TIPS, RESOURCES_TIPS, \
13-
PAGES_WITH_OWN_TIP, PAGE_TIPS_MAP, TipHistory
9+
from .models import TipType, TipHistory
1410

1511
logger = logging.getLogger(__name__)
1612

@@ -52,16 +48,18 @@
5248
'Reading': ['switch', 'settings', 'readaloud', 'context', 'thoughts', 'wordbank'],
5349
'Library': ['view', 'filters', 'search'],
5450
'Wordbank': ['wordbank'],
51+
# can_show() is true, but doesn't really matter since student shouldn't ever end up on the ResourceReading page:
52+
'ResourceReading': ['settings', 'readaloud', 'context', 'wordbank'],
5553
}
5654

5755
TEACHER_OR_PARENT_CAN_SHOW = {
5856
'Dashboard': ['student_reactions', 'reading_data', 'activity', 'manage'],
59-
'Reading': ['switch', 'settings', 'readaloud', 'context', 'wordbank'],
57+
'Reading': ['switch', 'settings', 'readaloud', 'context', 'thoughts', 'wordbank'],
6058
'Library': ['view', 'filters', 'search', 'book_actions'],
6159
'Wordbank': ['wordbank'],
6260
'Resources': ['resources'],
6361
'Manage': ['manage'],
64-
'ResourceReading': ['switch', 'settings', 'readaloud', 'context', 'wordbank'],
62+
'ResourceReading': ['settings', 'readaloud', 'context', 'wordbank'],
6563
}
6664

6765
START_DELTA = 250 # msec
@@ -144,7 +142,7 @@ def can_show_tips(self, clusive_user):
144142
version_count = 3
145143
for page_name in PAGE_NAMES:
146144
for tip in TipType.objects.all():
147-
actual = tip.can_show(page_name, version_count, clusive_user)
145+
actual = tip.can_show(page_name, version_count, clusive_user, None)
148146
expected = self.look_up_expected(clusive_user, page_name, tip)
149147
self.assertEqual(
150148
actual, expected,
@@ -166,7 +164,7 @@ def test_can_show_switch_single_version(self):
166164
"""
167165
for clusive_user in ClusiveUser.objects.all():
168166
switch_tip = TipType.objects.get(name='switch')
169-
actual = switch_tip.can_show('Reading', 1, clusive_user)
167+
actual = switch_tip.can_show('Reading', 1, clusive_user, None)
170168
self.assertFalse(
171169
actual,
172170
f"Can show 'switch' tip for {clusive_user.user.username} on Reading page"

0 commit comments

Comments
 (0)