Skip to content

Commit df41457

Browse files
authored
Merge pull request #336 from cast-org/feature/CSL-2041-popover-tour-2
CSL-2041: Popover tours
2 parents 86c2c1e + e9233c0 commit df41457

29 files changed

Lines changed: 370 additions & 156 deletions

src/frontend/js/frontend.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,36 @@ function setUpDeferredLoadOfCompDetails() {
12981298
});
12991299
}
13001300

1301+
function dialogMediaStop() {
1302+
'use strict';
1303+
1304+
function dialogTarget(evt) {
1305+
if (evt.namespace.includes('popover')) {
1306+
return $(evt.target).data('cfw.popover').$target[0];
1307+
}
1308+
if (evt.namespace.includes('modal')) {
1309+
return $(evt.target).data('cfw.modal').$target[0];
1310+
}
1311+
return null;
1312+
}
1313+
1314+
$(document.body).on('beforeHide.cfw.popover beforeHide.cfw.modal', function(evt) {
1315+
if (evt.isDefaultPrevented()) { return; }
1316+
1317+
var target = dialogTarget(evt);
1318+
if (target === null) { return; }
1319+
1320+
var $iframes = $(target).find('iframe[src]');
1321+
$iframes.each(function() {
1322+
var source = this.src;
1323+
if (source.includes('youtube.com') || source.includes('sproutvideo.com')) {
1324+
this.src = '';
1325+
this.src = source;
1326+
}
1327+
});
1328+
});
1329+
}
1330+
13011331
$(window).ready(function() {
13021332
'use strict';
13031333

@@ -1328,6 +1358,7 @@ $(window).ready(function() {
13281358
shareForm();
13291359
dashboardStudentReadingViewButtons();
13301360
toolboxHandleUpdate();
1361+
dialogMediaStop();
13311362

13321363
var settingFontSize = document.querySelector('#set-size');
13331364
if (settingFontSize !== null) {

src/frontend/js/tour.js

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,78 @@
33

44
var SELECTOR_CONTAINER = '#tourContainer';
55
var SELECTOR_TOUR_VISIBLE = '.popover-tour:visible';
6+
var CLASS_TOUR = 'touring';
67

78
var tourModule = function() {
89
// placeholder
910
};
1011

1112
tourModule.prototype = {
1213
// Initialize tour popover item
13-
// `selector` - the trigger for the popover to initialize
14-
prepare : function(selector) {
15-
if (selector) {
16-
var control = $(selector);
17-
var target = control.attr('data-cfw-popover-target');
18-
if ((typeof target === 'undefined' || target === false) && control.is('[data-clusive-tip-id]')) {
19-
target = '#tour_' + control.attr('data-clusive-tip-id');
20-
}
21-
var placement = control.attr('data-cfw-popover-placement');
22-
control.CFW_Popover({
23-
container: SELECTOR_CONTAINER,
24-
viewport: 'window',
25-
trigger: 'manual',
26-
target: target,
27-
placement: placement ? placement : 'right auto',
28-
popperConfig: {
29-
positionFixed: true
30-
}
31-
});
14+
// `name` - name (via data attribute) trigger for the popover to initialize
15+
prepare : function(name) {
16+
var $control = $('[data-clusive-tip-id="' + name + '"]');
17+
if (!$control.length) { return; }
18+
19+
var target = $control.attr('data-cfw-popover-target');
20+
if ((typeof target === 'undefined' || target === false) && $control.is('[data-clusive-tip-id]')) {
21+
target = '#tour_' + $control.attr('data-clusive-tip-id');
3222
}
23+
var placement = $control.attr('data-cfw-popover-placement');
24+
$control.CFW_Popover({
25+
container: SELECTOR_CONTAINER,
26+
viewport: 'window',
27+
trigger: 'manual',
28+
target: target,
29+
placement: placement ? placement : 'right auto',
30+
popperConfig: {
31+
positionFixed: true
32+
}
33+
});
34+
},
35+
36+
// Show a singleton from the tour
37+
singleton: function(name) {
38+
var $control = $('[data-clusive-tip-id="' + name + '"]');
39+
if (!$control.length) { return; }
40+
41+
document.body.classList.remove(CLASS_TOUR);
42+
$control.one('afterShow.cfw.popover', function() {
43+
document.querySelector('#tour_' + name).focus();
44+
window.parent.clusiveEvents.addTipViewToQueue(name);
45+
});
46+
setTimeout(function() {
47+
$control.CFW_Popover('show');
48+
}, 2000);
3349
},
3450

3551
// Chain animations for tour items together
3652
// `selector` - the next popover in the chain
3753
chain: function(selector) {
3854
var $curr = $(document).find(SELECTOR_TOUR_VISIBLE);
3955
var $next = $(selector);
56+
var $trigger = $next.data('cfw.popover').$element;
57+
58+
var showComplete = function() {
59+
$next[0].focus();
60+
var name = $next.attr('id').replace('tour_', '');
61+
window.parent.clusiveEvents.addTipViewToQueue(name);
62+
};
63+
64+
// Hide tip/tour tooltip if showing
65+
$('#tip').CFW_Tooltip('hide');
4066

4167
if ($curr.length) {
42-
// Wait until hide animation is complete before callling show
68+
// Wait until hide animation is complete before calling show
4369
$curr.CFW_Popover('hide').CFW_transition(null, function() {
44-
$next.CFW_Popover('show');
45-
$next[0].focus();
70+
document.body.classList.add(CLASS_TOUR);
71+
$trigger.one('afterShow.cfw.popover', showComplete);
72+
$trigger.CFW_Popover('show');
4673
});
4774
} else {
48-
$next.CFW_Popover('show');
49-
$next[0].focus();
75+
document.body.classList.add(CLASS_TOUR);
76+
$trigger.one('afterShow.cfw.popover', showComplete);
77+
$trigger.CFW_Popover('show');
5078
}
5179

5280
return false;
@@ -61,9 +89,11 @@
6189
if ($curr.length) {
6290
// Wait until hide animation is complete before focusing
6391
$curr.CFW_Popover('hide').CFW_transition(null, function() {
92+
document.body.classList.remove(CLASS_TOUR);
6493
$next[0].focus();
6594
});
6695
} else {
96+
document.body.classList.remove(CLASS_TOUR);
6797
$next[0].focus();
6898
}
6999

src/frontend/scss/site/_box.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@
8383
background-repeat: no-repeat;
8484
background-size: contain;
8585
}
86+
87+
.tip-mascot {
88+
position: absolute;
89+
top: calc(var(--CT_boxMascotSize) * -.375);
90+
left: calc(1rem + var(--CT_boxMascotSize));
91+
display: block;
92+
width: 1px;
93+
height: 1px;
94+
content: "";
95+
}
8696
}
8797

8898
.clusive-reduced-motion {

src/frontend/scss/site/_button.scss

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
.btn-nav,
77
.btn-setting,
88
.btn-tool,
9-
.btn-tts {
9+
.btn-tts,
10+
.btn-mascot-tipped {
1011
display: inline-flex;
1112
align-items: center;
1213
justify-content: center;
@@ -135,3 +136,21 @@
135136
@include font-size($tag-font-size);
136137
font-weight: $tag-font-weight;
137138
}
139+
140+
.btn-mascot-tipped {
141+
position: relative;
142+
143+
&::before {
144+
position: absolute;
145+
top: 50%;
146+
left: 50%;
147+
display: block;
148+
width: 1.75rem;
149+
height: calc(1.75rem * #{$img-ratio-mascot-tipped});
150+
content: "";
151+
background-image: var(--CT_imgMascotTipped);
152+
background-repeat: no-repeat;
153+
background-size: contain;
154+
transform: translate(-50%, -50%);
155+
}
156+
}

src/frontend/scss/site/_content.scss

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -542,19 +542,13 @@ h2,
542542
}
543543
.feature-context {
544544
position: absolute;
545-
//top: 33%;
546-
//left: 50%;
547-
top: 66%;
548-
left: $sidebar-width;
545+
top: 25%;
546+
left: 50%;
549547
margin-right: ($grid-gutter-width / -2);
550548
margin-left: ($grid-gutter-width / -2);
551549
pointer-events: none;
552550
outline: 0;
553551
@include sr-only();
554-
555-
@include media-breakpoint-up(md) {
556-
left: $sidebar-md-width;
557-
}
558552
}
559553

560554
.feature-list {
@@ -720,3 +714,19 @@ h2,
720714
animation-duration: $loader-circle-animation-speed * 2;
721715
}
722716
}
717+
718+
// stylelint-disable selector-no-qualifying-type
719+
// Conditionally show/hide content in tour popovers depending on if
720+
// state is singleton (auto-shown) or part of the tour started from
721+
// the tour/mascot button
722+
body:not(.touring) {
723+
.touring-on {
724+
display: none;
725+
}
726+
}
727+
body.touring {
728+
.touring-off {
729+
display: none;
730+
}
731+
}
732+
// stylelint-enable selector-no-qualifying-type

src/frontend/scss/site/_tooltip.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,12 @@
9797
.tooltip-step {
9898
margin-right: auto;
9999
}
100+
101+
.tooltip-tour {
102+
.tooltip-body {
103+
max-width: 15.5rem;
104+
}
105+
.tooltip-action {
106+
justify-content: space-between;
107+
}
108+
}

src/library/templates/library/library.html

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,5 @@ <h1>Library</h1>
5454
</main>
5555

5656
{% include "shared/partial/modal_vocab_check.html" %}
57-
{% for tour in tours %}
58-
{% include "shared/partial/popover_tour.html" with tour_name=tour.name tour_robust=tour.robust %}
59-
{% endfor %}
60-
{% if tip_name %}
61-
{% include "shared/partial/tooltip_tip.html" %}
62-
{% endif %}
6357
{% include "shared/partial/modal_confirm.html" %}
6458
{% endblock %}

src/library/templates/library/resources.html

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,4 @@ <h2>{{ cat.name }}</h2>
4242
{% endfor %}
4343

4444
</main>
45-
{% for tour in tours %}
46-
{% include "shared/partial/popover_tour.html" with tour_name=tour.name tour_robust=tour.robust %}
47-
{% endfor %}
48-
{% if tip_name %}
49-
{% include "shared/partial/tooltip_tip.html" %}
50-
{% endif %}
5145
{% endblock %}

src/library/views.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
from roster.models import ClusiveUser, Period, LibraryViews, LibraryStyles, check_valid_choice
3737
from tips.models import TipHistory
3838

39-
4039
logger = logging.getLogger(__name__)
4140

4241
# The library page requires a lot of parameters, which interact in rather complex ways.
@@ -385,14 +384,15 @@ def dispatch(self, request, *args, **kwargs):
385384

386385
def get(self, request, *args, **kwargs):
387386
self.tip_shown = TipHistory.get_tip_to_show(request.clusive_user, 'Library')
387+
self.tours = TipHistory.tour_list(request.clusive_user, page='Library')
388388
return super().get(request, *args, **kwargs)
389389

390390
def get_context_data(self, **kwargs):
391391
context = super().get_context_data(**kwargs)
392392
context['search_form'] = self.search_form
393393
context['tip_name'] = None
394-
context['tours'] = [{'name': self.tip_shown.name, 'robust': True }] if self.tip_shown else None
395-
context['tip_shown'] = self.tip_shown
394+
context['tip_shown'] = self.tip_shown.name if self.tip_shown else None
395+
context['tours'] = self.tours
396396
context['show_teacher_resource_link'] = self.request.clusive_user.can_manage_periods
397397
context['has_bookshare_account'] = has_bookshare_account(self.request)
398398
return context
@@ -422,6 +422,7 @@ class ResourcesPageView(LoginRequiredMixin, ThemedPageMixin, SettingsPageMixin,
422422

423423
def get(self, request, *args, **kwargs):
424424
self.tip_shown = TipHistory.get_tip_to_show(request.clusive_user, self.page_name)
425+
self.tours = TipHistory.tour_list(request.clusive_user, page=self.page_name)
425426
tip_name = self.tip_shown.name if self.tip_shown else ''
426427
if request.clusive_user.can_manage_periods and tip_name != 'resources':
427428
show_teacher_resource_link = True
@@ -432,8 +433,8 @@ def get(self, request, *args, **kwargs):
432433
'categories': EducatorResourceCategory.objects.all()
433434
.prefetch_related(Prefetch('resources', queryset=Book.objects.order_by('resource_sort_order'))),
434435
'tip_name': None,
435-
'tours': [{'name': self.tip_shown.name, 'robust': True }] if self.tip_shown else None,
436-
'tip_shown': self.tip_shown,
436+
'tip_shown': self.tip_shown.name if self.tip_shown else None,
437+
'tours': self.tours,
437438
'show_teacher_resource_link': show_teacher_resource_link,
438439
'clusive_user': request.clusive_user,
439440
}

src/pages/templates/pages/dashboard.html

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,5 @@ <h1>Dashboard</h1>
6666

6767
</main>
6868
{% include "shared/partial/modal_vocab_check.html" %}
69-
{% for tour in tours %}
70-
{% include "shared/partial/popover_tour.html" with tour_name=tour.name tour_robust=tour.robust %}
71-
{% endfor %}
72-
{% if tip_name %}
73-
{% include "shared/partial/tooltip_tip.html" %}
74-
{% endif %}
7569
{% include "shared/partial/modal_confirm.html" %}
76-
7770
{% endblock %}

0 commit comments

Comments
 (0)