summaryrefslogtreecommitdiff
path: root/addons/website_slides/static/src/js/slides_course_quiz_finish.js
blob: 8d6d11e5658fe1fa4e34a320e4844ae9008fbea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
odoo.define('website_slides.quiz.finish', function (require) {
'use strict';

var Dialog = require('web.Dialog');
var core = require('web.core');
var _t = core._t;

/**
 * This modal is used when the user finishes the quiz.
 * It handles the animation of karma gain and leveling up by animating
 * the progress bar and the text.
 */
var SlideQuizFinishModal = Dialog.extend({
    template: 'slide.slide.quiz.finish',
    events: {
        "click .o_wslides_quiz_modal_btn": '_onClickNext',
    },

    init: function(parent, options) {
        var self = this;
        this.quiz = options.quiz;
        this.hasNext = options.hasNext;
        this.userId = options.userId;
        options = _.defaults(options || {}, {
            size: 'medium',
            dialogClass: 'd-flex p-0',
            technical: false,
            renderHeader: false,
            renderFooter: false
        });
        this._super.apply(this, arguments);
        this.opened(function () {
            self._animateProgressBar();
            self._animateText();
        })
    },

    start: function() {
        var self = this;
        this._super.apply(this, arguments).then(function () {
            self.$modal.addClass('o_wslides_quiz_modal pt-5');
            self.$modal.find('.modal-dialog').addClass('mt-5');
            self.$modal.find('.modal-content').addClass('shadow-lg');
        });
    },

    //--------------------------------
    // Handlers
    //--------------------------------

    _onClickNext: function() {
        this.trigger_up('slide_go_next');
        this.destroy();
    },

    //--------------------------------
    // Private
    //--------------------------------

    /**
     * Handles the animation of the karma gain in the following steps:
     * 1. Initiate the tooltip which will display the actual Karma
     *    over the progress bar.
     * 2. Animate the tooltip text to increment smoothly from the old
     *    karma value to the new karma value and updates it to make it
     *    move as the progress bar moves.
     * 3a. The user doesn't level up
     *    I.   When the user doesn't level up the progress bar simply goes
     *         from the old karma value to the new karma value.
     * 3b. The user levels up
     *    I.   The first step makes the progress bar go from the old karma
     *         value to 100%.
     *    II.  The second step makes the progress bar go from 100% to 0%.
     *    III. The third and final step makes the progress bar go from 0%
     *         to the new karma value. It also changes the lower and upper
     *         bound to match the new rank.
     * @param $modal
     * @param rankProgress
     * @private
     */
    _animateProgressBar: function () {
        var self = this;
        this.$('[data-toggle="tooltip"]').tooltip({
            trigger: 'manual',
            container: '.progress-bar-tooltip',
        }).tooltip('show');

        this.$('.tooltip-inner')
            .prop('karma', this.quiz.rankProgress.previous_rank.karma)
            .animate({
                karma: this.quiz.rankProgress.new_rank.karma
            }, {
                duration: this.quiz.rankProgress.level_up ? 1700 : 800,
                step: function (newKarma) {
                    self.$('.tooltip-inner').text(Math.ceil(newKarma));
                    self.$('[data-toggle="tooltip"]').tooltip('update');
                }
            }
        );

        var $progressBar = this.$('.progress-bar');
        if (this.quiz.rankProgress.level_up) {
            this.$('.o_wslides_quiz_modal_title').text(_t('Level up!'));
            $progressBar.css('width', '100%');
            _.delay(function () {
                self.$('.o_wslides_quiz_modal_rank_lower_bound')
                    .text(self.quiz.rankProgress.new_rank.lower_bound);
                self.$('.o_wslides_quiz_modal_rank_upper_bound')
                    .text(self.quiz.rankProgress.new_rank.upper_bound || "");

                // we need to use _.delay to force DOM re-rendering between 0 and new percentage
                _.delay(function () {
                    $progressBar.addClass('no-transition').width('0%');
                }, 1);
                _.delay(function () {
                    $progressBar
                        .removeClass('no-transition')
                        .width(self.quiz.rankProgress.new_rank.progress + '%');
                }, 100);
            }, 800);
        } else {
            $progressBar.css('width', this.quiz.rankProgress.new_rank.progress + '%');
        }
    },

    /**
     * Handles the animation of the different text such as the karma gain
     * and the motivational message when the user levels up.
     * @private
     */
    _animateText: function () {
        var self = this;
       _.delay(function () {
            self.$('h4.o_wslides_quiz_modal_xp_gained').addClass('show in');
            self.$('.o_wslides_quiz_modal_dismiss').removeClass('d-none');
        }, 800);

        if (this.quiz.rankProgress.level_up) {
            _.delay(function () {
                self.$('.o_wslides_quiz_modal_rank_motivational').addClass('fade');
                _.delay(function () {
                    self.$('.o_wslides_quiz_modal_rank_motivational').html(
                        self.quiz.rankProgress.last_rank ?
                            self.quiz.rankProgress.description :
                            self.quiz.rankProgress.new_rank.motivational
                    );
                    self.$('.o_wslides_quiz_modal_rank_motivational').addClass('show in');
                }, 800);
            }, 800);
        }
    },

});

return SlideQuizFinishModal;

});