summaryrefslogtreecommitdiff
path: root/addons/website_slides/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/website_slides/static/src')
-rw-r--r--addons/website_slides/static/src/js/slides_category.js148
-rw-r--r--addons/website_slides/static/src/js/slides_course_fullscreen_player.js427
-rw-r--r--addons/website_slides/static/src/js/slides_course_progress_bar.js47
-rw-r--r--addons/website_slides/static/src/js/slides_course_quiz.js206
-rw-r--r--addons/website_slides/static/src/js/slides_course_sidebar_list.js34
-rw-r--r--addons/website_slides/static/src/js/slides_course_slides_list.js251
-rw-r--r--addons/website_slides/static/src/js/slides_delete_slide.js88
-rw-r--r--addons/website_slides/static/src/js/slides_upload.js51
-rw-r--r--addons/website_slides/static/src/js/website_slides.editor.js1
-rw-r--r--addons/website_slides/static/src/scss/slide_course.scss536
-rw-r--r--addons/website_slides/static/src/scss/slide_slide.scss156
-rw-r--r--addons/website_slides/static/src/scss/slides_slide_fullscreen.scss303
-rw-r--r--addons/website_slides/static/src/scss/website_slides_quiz.scss237
-rw-r--r--addons/website_slides/static/src/xml/website_slides_fullscreen.xml111
-rw-r--r--addons/website_slides/static/src/xml/website_slides_upload.xml105
15 files changed, 2693 insertions, 8 deletions
diff --git a/addons/website_slides/static/src/js/slides_category.js b/addons/website_slides/static/src/js/slides_category.js
new file mode 100644
index 00000000000..d1d7efb7747
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_category.js
@@ -0,0 +1,148 @@
+odoo.define('website_slides.add.section', function (require) {
+ 'use strict';
+
+ var sAnimations = require('website.content.snippets.animation');
+ var core = require('web.core');
+ var Widget = require('web.Widget');
+
+ var _t = core._t;
+
+ var SectionDialog = Widget.extend({
+ template: 'website.slide.add.section',
+ events: {
+ 'hidden.bs.modal': 'destroy',
+ 'click button.save': '_save',
+ 'click button[data-dismiss="modal"]': '_cancel',
+ 'change input#upload': '_slideUpload',
+ 'change input#url': '_slideUrl',
+ 'click .list-group-item': function (ev) {
+ this.$('.list-group-item').removeClass('active');
+ $(ev.target).closest('li').addClass('active');
+ }
+ },
+
+ /**
+ * @override
+ * @param {Object} el
+ * @param {number} channel_id
+ */
+ init: function (el, channelID) {
+ this._super(el, channelID);
+ this.channel_id = parseInt(channelID, 10);
+ this.index_content = '';
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ this.$el.modal({
+ backdrop: 'static'
+ });
+
+ return this._super.apply(this, arguments);
+ },
+ _getValue: function () {
+ var canvas = this.$('#data_canvas')[0],
+ values = {
+ 'channel_id': this.channel_id || '',
+ 'url': this.$('#url').val(),
+ 'name': this.$('#section_name').val()
+ };
+ return values;
+ },
+ /**
+ * @private
+ */
+ _validate: function () {
+ this.$('.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
+ if (!this.$('#name').val()) {
+ this.$('#name').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
+ return false;
+ }
+ var url = this.$('#url').val() ? this.is_valid_url : false;
+ if (!(this.file.name || url)) {
+ this.$('#url').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
+ return false;
+ }
+ return true;
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @param {Object} ev
+ */
+ _save: function (ev) {
+ var self = this;
+
+ var values = this._getValue();
+ if ($(ev.target).data('published')) {
+ values.website_published = true;
+ }
+ this.$('.oe_slides_upload_loading').show();
+ this.$('.modal-footer, .modal-body').hide();
+ this._rpc({
+ route: '/slides/add_category',
+ params: values,
+ }).then(function (data) {
+ if (data.error) {
+ self._displayAlert(data.error);
+ self.$('.oe_slides_upload_loading').hide();
+ self.$('.modal-footer, .modal-body').show();
+
+ } else {
+ window.location = data.url;
+ }
+ });
+ },
+ /**
+ * @override
+ */
+ _cancel: function () {
+ this.trigger('cancel');
+ },
+
+ });
+
+ sAnimations.registry.websiteSlidesSection = sAnimations.Class.extend({
+ selector: '.oe_slide_js_add_section',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides_upload.xml'],
+ read_events: {
+ 'click': '_onAddSectionClick',
+ },
+
+ /**
+ * @override
+ */
+ start: function () {
+ // Automatically open the upload dialog if requested from query string
+ if ($.deparam.querystring().enable_slide_upload !== undefined) {
+ this._openDialog(this.$el.attr('channel_id'));
+ }
+ return this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _openDialog: function (channelID) {
+ new SectionDialog(this, channelID).appendTo(document.body);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onAddSectionClick: function (ev) {
+ console.log('test');
+ this._openDialog($(ev.currentTarget).attr('channel_id'));
+ },
+ });
+ }); \ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js
new file mode 100644
index 00000000000..1da173a2f46
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js
@@ -0,0 +1,427 @@
+var onYouTubeIframeAPIReady;
+
+odoo.define('website_slides.fullscreen', function (require) {
+ 'use strict';
+ var sAnimations = require('website.content.snippets.animation');
+ var Widget = require('web.Widget');
+ var core = require('web.core');
+ var QWeb = core.qweb;
+
+ var tag = document.createElement('script');
+
+ var QuizWidget = require('website_slides.quiz');
+
+ tag.src = "https://www.youtube.com/iframe_api";
+ var firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+
+
+ var Fullscreen = Widget.extend({
+ /**
+ * @override
+ * @param {Object} el
+ * @param {Object} data holding channelId and optionally upload and publish control parameters
+ */
+ init: function(el, course_id,slide_id, user_id){
+ this._super.apply(this,arguments);
+ this.courseID = parseInt(course_id, 10);
+ this.slideID = parseInt(slide_id, 10);
+ this.userID = parseInt(user_id, 10);
+ this.course = undefined;
+ this.slide = undefined;
+ this.slides = [];
+ this.nextSlide = undefined;
+ this.previousSlide = undefined;
+ this.url = undefined;
+ this.urlToSmallScreen = undefined;
+ this.activetab = undefined;
+ this.player = undefined;
+ this.goToQuiz = false;
+ this.answeredQuestions = [];
+ this.slideTitle = undefined;
+ },
+ start: function(){
+ var self = this;
+ this.url = window.location.pathname;
+ this.urlToSmallScreen = this.url.replace('/fullscreen','');
+ this._getSlides();
+ this._renderPlayer();
+ this._bindListEvents();
+
+ $(document).keydown(this._onKeyDown.bind(this));
+ return this._super.apply(this, arguments);
+ },
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+ /**
+ * @private
+ * Renders the player accordingly to the current slide
+ */
+ _renderPlayer: function(){
+ var self = this;
+ var embed_url;
+ if(self.slide.slide_type !== 'webpage' || self.slide.htmlContent){
+ if((self.slide.slide_type == "quiz" || self.slide.hasQuiz) && !self.slide.quiz){
+ self._fetchQuiz();
+ } else {
+ embed_url = $(this.slide.embed_code).attr('src');
+ if (self.slide.slide_type === "video"){
+ embed_url = "https://" + embed_url + "&rel=0&autoplay=1&enablejsapi=1&origin=" + window.location.origin;
+ }
+ $('.o_wslides_fullscreen_player').html(QWeb.render('website.slides.fullscreen', {
+ slide: self.slide,
+ nextSlide: self.nextSlide,
+ questions: self.slide.quiz ? self.slide.quiz.questions: '',
+ reward: self.slide.quiz ? self.slide.quiz.nb_attempts < 3 ? self.slide.quiz.possible_rewards[self.slide.quiz.nb_attempts] : self.slide.quiz.possible_rewards[3]: self.slide.maxPoints,
+ embed_url: embed_url,
+ question_count: self.slide.quiz ? self.slide.quiz.questions.length : '',
+ letters: self.slide.quiz ? self.letters : '',
+ showMiniQuiz: self.goToQuiz
+ }));
+ if(self.slide.slide_type === "video"){
+ self._renderYoutubeIframe();
+ }
+ if(self.slide.slide_type == 'webpage'){
+ self._renderWebpage();
+ }
+ if((self.slide.slide_type == "presentation" || self.slide.slide_type == "document" || self.slide.slide_type == "infographic" || self.slide.slide_type == "webpage") && !self.slide.quiz){
+ self._setSlideStateAsDone();
+ }
+ if ((self.slide.quiz && self.slide.slide_type === "quiz") || self.goToQuiz){
+ self._renderQuiz();
+ }
+ }
+ } else {
+ self._fetchHtmlContent();
+ }
+ self._renderTitle();
+ },
+ _renderYoutubeIframe: function(){
+ var self = this;
+ /**
+ * Due to issues of synchronization between the youtube api script and the widget's instanciation.
+ */
+ try{
+ self._setupYoutubePlayer();
+ }
+ catch {
+ onYouTubeIframeAPIReady = function(){
+ var self = this;
+ self._setupYoutubePlayer();
+ }.bind(this)
+ }
+ },
+ _renderWebpage: function(){
+ var self = this;
+ $(self.slide.htmlContent).appendTo('.o_wslides_fullscreen_webpage_content');
+ },
+ _renderQuiz: function(){
+ var self = this;
+ var Quiz = new QuizWidget(this, self.slide);
+ Quiz.appendTo('.o_wslides_fullscreen_player');
+ $('.next-slide').click(function(){
+ self._goToNextSlide();
+ })
+ $('.back-to-video').click(function(){
+ self.goToQuiz = false;
+ self._renderPlayer();
+ });
+ },
+ _renderTitle: function(){
+ var self = this;
+ $('.o_wslides_fullscreen_slide_title').empty().html(QWeb.render('website.course.fullscreen.title', {
+ slide: self.slide,
+ miniQuiz: self.goToQuiz
+ }));
+ },
+ /**
+ * @private
+ * Links the youtube api to the iframe present in the template
+ */
+ _setupYoutubePlayer: function(){
+ var self = this;
+ self.player = new YT.Player('youtube-player', {
+ host: 'https://www.youtube.com',
+ playerVars: {'autoplay': 1, 'origin': window.location.origin},
+ autoplay: 1,
+ events: {
+ 'onReady': self._onPlayerReady,
+ 'onStateChange': this._onPlayerStateChange.bind(self)
+ }
+ });
+ },
+ /**
+ * @param {*} event
+ * Specific method of the youtube api.
+ * Whenever the player starts playing, a setinterval is created.
+ * This setinterval is used to check te user's progress in the video.
+ * Once the user reaches a particular time in the video, the slide will be considered as completed if the video doesn't have a mini-quiz.
+ * This method also allows to automatically go to the next slide (or the quiz associated to the current video) once the video is over
+ */
+ _onPlayerStateChange: function(event){
+ var self = this;
+ var tid;
+ clearInterval(self.tid);
+ if (event.data == YT.PlayerState.PLAYING && !self.slide.done) {
+ self.tid = setInterval(function(){
+ if(event.target.getCurrentTime){
+ var currentTime = event.target.getCurrentTime();
+ var totalTime = event.target.getDuration();
+ if(totalTime && currentTime > totalTime - 30){
+ clearInterval(self.tid);
+ if(!self.slide.hasQuiz && !self.slide.done){
+ self.slide.done = true;
+ self._setSlideStateAsDone();
+ }
+ }
+ }
+ }, 1000);
+ }
+ if(event.data == YT.PlayerState.ENDED){
+ self.player = undefined;
+ self._goToNextSlide();
+ }
+ },
+ /**
+ * @private
+ * Creates slides objects from every slide-list-cells attributes
+ */
+ _getSlides: function(){
+ var self = this;
+ var slides = $('.o_wslides_fullscreen_sidebar_slide_tab');
+ for(var i = 0; i < slides.length;i++){
+ var slide = $(slides[i]);
+ self.slides.push({
+ id: parseInt(slide.attr('slide_id'), 10),
+ name: slide.attr('slide_name'),
+ embed_code: slide.attr('slide_embed_code'),
+ slide_type: slide.attr('slide_type'),
+ done: slide.attr('done'),
+ hasQuiz: slide.attr('quiz'),
+ slug: slide.attr('slide_slug'),
+ htmlContent: undefined
+ });
+ this._getActiveSlide();
+ }
+ },
+ /**
+ * @private
+ * @param {object} slide
+ * Fetch the quiz for a particular slide
+ */
+ _fetchQuiz: function(){
+ var self = this;
+ self._rpc({
+ route:"/slide/quiz/get",
+ params: {
+ 'slide_id': self.slide.id
+ }
+ }).then(function(data){
+ if(data){
+ self.slide.quiz = data;
+ self._renderPlayer();
+ }
+ })
+ },
+ _fetchHtmlContent: function(){
+ var self = this;
+ self._rpc({
+ route:"/slide/html_content/get",
+ params: {
+ 'slide_id': self.slide.id
+ }
+ }).then(function(data){
+ self.slide.htmlContent = data.html_content;
+ self._renderPlayer();
+ })
+ },
+ /**
+ * @private
+ * Once the completion conditions are filled,
+ * sends a json request to the backend to set the relation between the slide and the user as being completed
+ */
+ _setSlideStateAsDone: function(){
+ var self = this;
+ self._rpc({
+ route: '/slides/set_completed',
+ params: {
+ slide_id: self.slide.id,
+ }
+ }).then(function(data){
+ $('#check-'+self.slide.id).replaceWith($('<i class="check-done o_wslides_slide_completed fa fa-check-circle"></i>'))
+ self.slide.done = true;
+ clearInterval(self.tid);
+ self.channelCompletion = data.channel_completion;
+ self._updateProgressbar();
+ });
+ },
+ _updateProgressbar: function(){
+ var self = this;
+ var completion = self.channelCompletion <= 100 ? self.channelCompletion : 100;
+ $('.o_wslides_fullscreen_sidebar_progress_gauge').css('width', completion + "%" );
+ $('.o_wslides_progress_percentage').text(completion);
+ },
+ /**
+ * @private
+ * Creates an array of letters to be used in the quiz with a foreach
+ */
+ _generateQuizLetters: function(){
+ var letters = [];
+ for(var i = 65; i < 91; i++){
+ letters.push(String.fromCharCode(i));
+ }
+ return letters;
+ },
+ _goToNextSlide: function(){
+ var self = this;
+ clearInterval(self.tid);
+ self.player = undefined;
+ self.goToQuiz = self.slide.hasQuiz && !self.goToQuiz;
+ if(self.nextSlide && !self.goToQuiz){
+ self.slide = self.nextSlide;
+ self.index++;
+ self._setActiveTab();
+ self._renderPlayer();
+ self._setPreviousAndNextSlides();
+ self._updateUrl();
+ history.pushState(null,'',self.url);
+ }
+ else if(self.nextSlide){
+ self._renderPlayer();
+ }
+ },
+ _goToPreviousSlide: function(){
+ var self = this;
+ clearInterval(self.tid);
+ self.goToQuiz = false;
+ self.player = undefined;
+ if(self.previousSlide){
+ self.slide = self.previousSlide;
+ self.index--;
+ self._setActiveTab();
+ self._renderPlayer();
+ self._setPreviousAndNextSlides();
+ self._updateUrl();
+ history.pushState(null,'',self.url);
+ }
+ },
+ _setPreviousAndNextSlides: function(){
+ var self = this;
+ self.previousSlide = self.index > 0 ? self.slides[self.index-1] : undefined;
+ self.nextSlide = self.index < (self.slides.length - 1) ? self.slides[self.index+1] : undefined;
+ },
+ /**
+ * Changes the url whenever the user changes slides.
+ * This allows the user to refresh the page and stay at the right video
+ */
+ _updateUrl: function(){
+ var self = this;
+ var url = window.location.pathname.split('/');
+ url[url.length-1] = self.slide.slug;
+ url = url.join('/');
+ self.url = url;
+ self.urlToSmallScreen = self.url;
+ self.url += "?fullscreen=1";
+ $('.o_wslides_small_screen').attr('href', self.urlToSmallScreen);
+ },
+ /**
+ * Whenever the user changes slide, change the active tab
+ */
+ _setActiveTab: function(){
+ var self = this;
+ self.activeTab.removeClass('active');
+ $('li.active').removeClass('active');
+ $('li[slide_id='+self.slide.id+']').addClass('active');
+ self.activeTab = $('.o_wslides_fullscreen_sidebar_slide_tab[index="'+self.index+'"]')
+ self.activeTab.addClass('active');
+ },
+ /**
+ * The first time the user gets on the player,
+ * get the slide that is represented by the active tab in the sidebar
+ */
+ _getActiveSlide: function(){
+ var self = this;
+ self.activeTab = $('.o_wslides_fullscreen_sidebar_slide_tab.active');
+ self.index = parseInt(self.activeTab.attr('index'), 10);
+ self.slide = self.slides[self.index];
+ self._setPreviousAndNextSlides();
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+ _onListCellClick: function(ev){
+ var self = this;
+ clearInterval(self.tid);
+ self.player = undefined;
+ var target = $(ev.currentTarget);
+ self.goToQuiz = false;
+ if(target[0] !== self.activeTab[0]){
+ self.activeTab.removeClass('active');
+ target.addClass('active');
+ self.index = parseInt(target.attr('index'));
+ self._getActiveSlide();
+ self._renderPlayer();
+ $('li.active').removeClass('active');
+ $('li[slide_id='+self.slide.id+']').addClass('active');
+ self._setPreviousAndNextSlides();
+ self._updateUrl();
+ history.pushState(null,'',self.url);
+ }
+ },
+ _onMiniQuizClick: function(ev){
+ var self = this;
+ self.index = parseInt($(ev.currentTarget).attr('index'));
+ self.slide = self.slides[self.index];
+ self.goToQuiz = true;
+ self._setPreviousAndNextSlides();
+ self._renderPlayer();
+ self._setActiveTab();
+ self._updateUrl();
+ history.pushState(null,'' ,self.url);
+ },
+ /**
+ * @private
+ * Binds events related to the list
+ */
+ _bindListEvents: function(){
+ var self = this;
+ $('.o_wslides_fullscreen_sidebar_slide_tab').each(function () {
+ $(this).click(self._onListCellClick.bind(self));
+ });
+
+ $('.o_wslides_slide_quiz ').each(function(){
+ $(this).click(self._onMiniQuizClick.bind(self));
+ })
+ },
+ _onKeyDown: function(ev){
+ var self = this;
+ switch(ev.key){
+ case "ArrowRight":
+ self._goToNextSlide();
+ break;
+ case "ArrowLeft":
+ self._goToPreviousSlide();
+ break;
+ }
+ },
+ })
+
+ sAnimations.registry.websiteSlidesFullscreenPlayer = Widget.extend({
+ selector: '.oe_js_course_slide',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides_fullscreen.xml'],
+ init: function(el){
+ this._super.apply(this, arguments);
+ },
+ start: function(){
+ this._super.apply(this, arguments);
+ var user_id = this.$el.attr('user_id');
+ var course_id = this.$el.attr('course_id');
+ var slide_id = this.$el.attr('slide_id');
+ var fullscreen = new Fullscreen(this, course_id, slide_id, user_id);
+ fullscreen.appendTo(".oe_js_course_slide");
+ }
+ });
+
+ return Fullscreen;
+}); \ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_course_progress_bar.js b/addons/website_slides/static/src/js/slides_course_progress_bar.js
new file mode 100644
index 00000000000..2412368018f
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_course_progress_bar.js
@@ -0,0 +1,47 @@
+odoo.define('website_slides.progress.bar', function (require) {
+
+ var sAnimations = require('website.content.snippets.animation');
+ var Widget = require('web.Widget');
+
+ var ProgressBar = Widget.extend({
+
+ /**
+ * @override
+ * @param {Object} el
+ * @param {number} channel_id
+ */
+ init: function (el, completion) {
+ this._super(el);
+ this.completion = completion;
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ this._renderProgressBar();
+ return this._super.apply(this, arguments);
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+ _renderProgressBar: function (ev) {
+ var self = this;
+ $('.oe_slide_js_progress_bar').css('width', (self.completion <= 100 ? self.completion : 100) + '%');
+ },
+ });
+
+ sAnimations.registry.websiteSlidesProgressBar = sAnimations.Class.extend({
+ selector: '.oe_slide_js_progress_bar',
+ /**
+ * @override
+ */
+ start: function () {
+ var completion = parseInt($('.oe_slide_js_progress_bar').attr('channel_completion'));
+ var progressBar = new ProgressBar(this, completion);
+ progressBar.appendTo(".oe_slide_js_progress_bar");
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ return ProgressBar;
+ });
diff --git a/addons/website_slides/static/src/js/slides_course_quiz.js b/addons/website_slides/static/src/js/slides_course_quiz.js
new file mode 100644
index 00000000000..f98d5b3ed8a
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_course_quiz.js
@@ -0,0 +1,206 @@
+odoo.define('website_slides.quiz', function (require) {
+ 'use strict';
+ var sAnimations = require('website.content.snippets.animation');
+ var core = require('web.core');
+ var Widget = require('web.Widget');
+
+ var QWeb = core.qweb;
+
+ var Quiz= Widget.extend({
+ /**
+ * @override
+ * @param {Object} el
+ * @param {Object} data holding all the slide elements needed for the quiz
+ * It will either come from the fullscreen widget or the sAnimation at the end of this file
+ */
+ init: function(el, data){
+ this.slide = data;
+ this.answeredQuestions = [];
+ this.fullscreen = el;
+ return this._super.apply(this,arguments);
+ },
+ start: function(){
+ var self = this;
+ self._bindQuizEvents();
+ /**
+ * If the quiz is rendered by the server instead of the fullscreen widget,
+ * questions and their answers will have to be created manually from attributes
+ */
+ if(self.slide.quiz.questions.length === 0){
+ this._setQuestions();
+ }
+ return this._super.apply(this, arguments);
+ },
+ _renderSuccessModal: function(){
+ var self =this;
+ $('.o_wslides_fullscreen_quiz').append(QWeb.render('website.course.quiz.success', {
+ data: data
+ }));
+ $('.submit-quiz').remove();
+ $('.next-slide').css('display', 'inline-block');
+ $('.next-slide').click(function(){
+ self.fullscreen._goToNextSlide();
+ });
+ $('.o_wslides_quiz_success_modal_close').click(function(){
+ $('.o_wslides_quiz_success_modal').remove();
+ $('.o_wslides_quiz_modal_background').remove();
+ });
+ $(".o_wslides_quiz_modal_background").click(function(ev){
+ $(ev.currentTarget).remove();
+ $('.o_wslides_quiz_success_modal').remove();
+ });
+ },
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+ /**
+ * @private
+ * In case the quiz is rendered by the server and the data don't come from the fullscreen widget,
+ * questions and their answers will have to be set here by using attributes
+ */
+ _setQuestions: function(){
+ var self = this;
+ $('.o_wslides_quiz_question').each(function(){
+ self.slide.quiz.questions.push({
+ id: parseInt($(this).attr('id')),
+ title: $(this).attr('title'),
+ answers: []
+ });
+ })
+ for(var i = 0; i < self.slide.quiz.questions.length; i++){
+ self._setAnswersForQuestion(self.slide.quiz.questions[i]);
+ }
+ },
+ _setAnswersForQuestion: function (question){
+ var self = this;
+ $('.o_wslides_quiz_answer[question_id='+question.id+']').each(function (){
+ question.answers.push({
+ id: parseInt($(this).attr('id')),
+ text: $(this).attr('text_value'),
+ is_correct: $(this).attr('is_correct')
+ });
+ });
+ },
+ _updateProgressbar: function (){
+ var self = this;
+ var completion = self.channelCompletion <= 100 ? self.channelCompletion : 100;
+ $('.o_wslides_fullscreen_sidebar_progress_gauge').css('width', completion + "%" );
+ $('.o_wslides_progress_percentage').text(completion);
+ },
+ _bindQuizEvents: function (){
+ var self = this;
+ if (!self.slide.done){
+ $('.o_wslides_quiz_answer').each(function(){
+ $(this).click(self._onAnswerClick.bind(self));
+ });
+ }
+ $('.submit-quiz').click(self._onSubmitQuiz.bind(self));
+ },
+ _highlightAnswers: function (answers){
+ var self = this;
+ self.answeredQuestions = [];
+ for (var i = 0; i < answers.goodAnswers.length; i++){
+ $('#answer'+ answers.goodAnswers[i] +'').addClass('o_wslides_quiz_good_answer');
+ $('#answer'+ answers.goodAnswers[i] +' .o_wslides_quiz_radio_box span').replaceWith($('<i class="fa fa-check-circle"></i>'));
+ var questionID =$('#answer'+ answers.goodAnswers[i] +' .o_wslides_quiz_radio_box input').attr('question_id');
+ self.answeredQuestions.push(questionID);
+ $('.o_wslides_quiz_answer[question_id='+questionID+']:not(.o_wslides_quiz_good_answer)').addClass('o_wslides_quiz_ignored_answer');
+ $('.o_wslides_quiz_answer[question_id='+questionID+']').each(function(){
+ $(this).unbind('click')
+ });
+ $('input[question_id='+questionID+']').each(function(){
+ $(this).prop('disabled',true);
+ });
+ }
+ for (i = 0; i < answers.badAnswers.length; i++){
+ $('#answer'+ answers.badAnswers[i]).removeClass('o_wslides_quiz_good_answer')
+ .addClass('o_wslides_quiz_bad_answer')
+ .unbind('click');
+ $('#answer'+ answers.badAnswers[i] +' .o_wslides_quiz_radio_box span').replaceWith($('<i class="fa fa-times "></i>'));
+ $('#answer'+ answers.badAnswers[i] +' .o_wslides_quiz_radio_box input').prop('checked', false);
+ }
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+ _onAnswerClick: function (ev){
+ var self = this;
+ var target = $(ev.currentTarget);
+ if ((self.answeredQuestions.indexOf(target.attr('question_id'))) === -1){
+ var id = target.attr('id');
+ var question_id = target.attr('question_id');
+ $('.o_wslides_quiz_answer[question_id='+question_id+']').removeClass('o_wslides_quiz_good_answer');
+ $('#'+id+' input[type=radio]').prop('checked', true);
+ }
+ },
+ _onSubmitQuiz: function (){
+ var self = this;
+ var inputs = $('input[type=radio]:checked');
+ var values = [];
+ for (var i = 0; i < inputs.length; i++){
+ values.push(parseInt($(inputs[i]).val()));
+ }
+ if (values.length === self.slide.quiz.questions.length){
+ $('.quiz-danger').remove();
+ self._rpc({
+ route: "/slide/quiz/submit",
+ params: {
+ slide_id: self.slide.id,
+ answer_ids: values,
+ quiz_id: self.slide.quiz_id
+ }
+ }).then(function(data){
+ self._highlightAnswers(data);
+ self.slide.quiz.nb_attempts = data.attempts_count;
+ if (data.passed){
+ self.channelCompletion = data.channel_completion;
+ self._updateProgressbar();
+ $('#check-'+self.slide.id).replaceWith($('<i class="check-done o_wslides_slide_completed fa fa-check-circle"></i>'));
+ self.slide.done = true;
+ self._renderSuccessModal();
+ }
+ else {
+ $('#quiz-points').text(self.slide.quiz.nb_attempts < 3 ? self.slide.quiz.possible_rewards[self.slide.quiz.nb_attempts] : self.slide.quiz.possible_rewards[self.slide.quiz.possible_rewards.length-1]);
+ }
+ });
+ } else {
+ $('.o_wslides_fullscreen_player').append($('<p class="quiz-danger text-danger mt-1">All questions must be answered !</p>'));
+ }
+ },
+});
+
+ sAnimations.registry.websiteSlidesQuizNoFullscreen = Widget.extend({
+ selector: '.o_w_slides_quiz_no_fullscreen',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides_fullscreen.xml'],
+ init: function (el){
+ this._super.apply(this, arguments);
+ },
+ start: function (){
+ this._super.apply(this, arguments);
+ var slideID = parseInt(this.$el.attr('slide_id'),10);
+ var slideDone = this.$el.attr('slide_done');
+ var nbAttempts = parseInt(this.$el.attr('nb_attempts'), 10);
+ var firstAttemptReward = this.$el.attr('first_reward');
+ var secondAttemptReward = this.$el.attr('second_reward');
+ var thirdAttemptReward = this.$el.attr('third_reward');
+ var fourthAttemptReward = this.$el.attr('fourth_reward');
+ var possibleRewards = [firstAttemptReward,secondAttemptReward,thirdAttemptReward,fourthAttemptReward]
+ var data = {
+ id: slideID,
+ done: slideDone,
+ quiz: {
+ questions: [],
+ nb_attempts: nbAttempts,
+ possible_rewards: possibleRewards,
+ reward: nbAttempts < possibleRewards.length ? possibleRewards[nbAttempts] : possibleRewards[possibleRewards.length-1]
+ }
+ }
+ if(!slideDone){
+ var NewQuiz = new Quiz(this, data);
+ NewQuiz.appendTo(".o_w_slides_quiz_no_fullscreen");
+ }
+ }
+ });
+
+ return Quiz;
+}); \ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_course_sidebar_list.js b/addons/website_slides/static/src/js/slides_course_sidebar_list.js
new file mode 100644
index 00000000000..11b61d4e5ec
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_course_sidebar_list.js
@@ -0,0 +1,34 @@
+odoo.define('website_slides.sidebar', function (require) {
+ 'use strict';
+ var sAnimations = require('website.content.snippets.animation');
+ var core = require('web.core');
+ var Widget = require('web.Widget');
+
+ var SideBar = Widget.extend({
+ init: function (el){
+ this._super.apply(this,arguments);
+ },
+ start: function (){
+ $('.o_wslides_fullscreen_toggle_sidebar').click(function (ev){
+ ev.preventDefault();
+ $(ev.currentTarget).toggleClass('active');
+ $('.o_wslides_fullscreen_sidebar').toggleClass('o_wslides_fullscreen_sidebar_hidden');
+ $('.o_wslides_fullscreen_player').toggleClass('o_wslides_fullscreen_player_no_sidebar')
+ })
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ sAnimations.registry.websiteSlidesSidebarList = Widget.extend({
+ selector: '.o_wslides_fullscreen_toggle_sidebar',
+ // xmlDependencies: ['/website_slides/static/src/xml/website_slides.xml'],
+ init: function (el){
+ this._super.apply(this, arguments);
+ },
+ start: function (){
+ this._super.apply(this, arguments);
+ var sideBar = new SideBar(this);
+ sideBar.appendTo(".oe_js_side_bar_list");
+ }
+ });
+}); \ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_course_slides_list.js b/addons/website_slides/static/src/js/slides_course_slides_list.js
new file mode 100644
index 00000000000..bf634f542e3
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_course_slides_list.js
@@ -0,0 +1,251 @@
+odoo.define('website_slides.slideslist', function (require) {
+ 'use strict';
+ var sAnimations = require('website.content.snippets.animation');
+ var Widget = require('web.Widget');
+
+ var SlideUpload = require('website_slides.upload_modal');
+
+ var List = Widget.extend({
+ init: function (el){
+ this._super.apply(this,arguments);
+ this.draggedElement = undefined;
+ this.dropTarget = undefined;
+ this.slideCount = undefined;
+ this.slides = [];
+ this.categories = [];
+ },
+ start: function (){
+ this._super.apply(this,arguments);
+ this.slideCount = $('li.content-slide').length;
+ //Change links HREF to fullscreen mode for SEO
+ var links = $(".link-to-slide");
+ for (var i = 0; i < links.length; i++){
+ $(links[i]).attr('href', $(links[i]).attr('href') + "?fullscreen=1");
+ }
+ this._bindEvents();
+ },
+ _bindEvents: function (){
+ var self = this;
+ $('.slide-draggable').each(function (){
+ self._addSlideDragAndDropHandlers($(this));
+ });
+ $('.section-draggable').each(function (){
+ self._addSectionDragAndDropHandlers($(this));
+ });
+ $('.course-section').each(function (){
+ self._addDropSlideOnSectionHandler($(this));
+ });
+ },
+ _unbind: function (className){
+ $("."+className).each(function (){
+ $(this).unbind();
+ });
+ },
+ _unbindAll: function (){
+ this._unbind('slide-draggable');
+ this._unbind('section-draggable');
+ this._unbind('course-section');
+ },
+ _getSlides: function (){
+ var self = this;
+ var slides = $('li.content-slide');
+ for(var i = 0; i < slides.length;i++){
+ var slide = $(slides[i]);
+ self.slides.push({
+ id: parseInt(slide.attr('slide_id')),
+ category_id: parseInt(slide.attr('category_id')),
+ sequence: i
+ });
+ }
+ },
+ _getCategories: function (){
+ var self = this;
+ self.categories = [];
+ var categories = $('.course-section');
+ for (var i = 0; i < categories.length;i++){
+ var category = $(categories[i]);
+ self.categories.push(parseInt(category.attr('category_id')));
+ }
+ },
+ _addDropSlideOnSectionHandler: function (target){
+ var self = this;
+ target.on('drop', function (ev){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ self.dropTarget = $(ev.currentTarget);
+ self.draggedElement[0].parentNode.removeChild(self.draggedElement[0]);
+ $('ul[category_id='+target.attr('category_id')+']').append(self.draggedElement)
+ self._addSlideDragAndDropHandlers(self.draggedElement);
+ self._reorderSlides();
+ });
+ target.on('dragover', function (ev){
+ if(ev.preventDefault){
+ ev.preventDefault();
+ }
+ });
+ },
+ _addSlideDragAndDropHandlers: function (target){
+ var self = this;
+ target.on('dragstart', function (ev){
+ $('.section-draggable').removeClass('hold')
+ self._unbind('section-draggable');
+ ev.originalEvent.dataTransfer.effectAllowed = 'move';
+ ev.originalEvent.dataTransfer.setData('text/html', this.outerHTML);
+ self.draggedElement = target;
+ self.draggedElement.addClass('hold');
+ });
+ target.on('dragover', function (ev){
+ if ($(ev.currentTarget) !== self.draggedElement){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.addClass('slide-hovered');
+ }
+ });
+ target.on('dragleave', function (ev){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.removeClass('slide-hovered');
+ });
+ target.on('drop', function (ev){
+ if (self.draggedElement.hasClass('slide-draggable') && target.hasClass('slide-draggable')){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.removeClass('slide-hovered');
+ target.removeClass('hold');
+ if (target !== self.draggedElement){
+ self.dropTarget = $(ev.currentTarget);
+ self.draggedElement[0].parentNode.removeChild(self.draggedElement[0]);
+ var dropHTML = ev.originalEvent.dataTransfer.getData('text/html');
+ target[0].insertAdjacentHTML('beforebegin',dropHTML);
+ self.draggedElement = $(target[0].previousSibling);
+ self._reorderSlides();
+ }
+ self._unbindAll();
+ self._bindEvents();
+ }
+ });
+ target.on('dragend', function (ev){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.removeClass('slide-hovered');
+ target.removeClass('hold');
+ });
+ },
+ _addSectionDragAndDropHandlers: function(target){
+ var self = this;
+ target.on('dragstart', function (ev){
+ self._unbind('slide-draggable');
+ self._unbind('course-section');
+ ev.originalEvent.dataTransfer.effectAllowed = 'move';
+ ev.originalEvent.dataTransfer.setData('text/html', this.outerHTML);
+ self.draggedElement = target;
+ self.draggedElement.addClass('hold');
+ });
+ target.on('dragover', function (ev){
+ if (target.hasClass('section-draggable') && self.draggedElement.hasClass('section-draggable')){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.addClass('slide-hovered');
+ }
+ });
+ target.on('dragleave', function (ev){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.removeClass('slide-hovered');
+ });
+ target.on('drop', function (ev){
+ if(ev.preventDefault){
+ ev.preventDefault();
+ }
+ if(self.draggedElement.hasClass('section-draggable') && target.hasClass('section-draggable')){
+ target.removeClass('slide-hovered');
+ target.removeClass('hold');
+ self.dropTarget = $(ev.currentTarget);
+ if(target !== self.draggedElement && $(ev.currentTarget).hasClass('section-draggable')){
+ self.draggedElement[0].parentNode.removeChild(self.draggedElement[0]);
+ var dropHTML = ev.originalEvent.dataTransfer.getData('text/html');
+ target[0].insertAdjacentHTML('beforebegin',dropHTML);
+ self.draggedElement = $(target[0].previousSibling);
+ self._reorderCategories();
+ self._reorderSlides();
+ self._rebindUploadButton(self.draggedElement.attr('category_id'));
+ }
+ self._unbindAll();
+ self._bindEvents();
+ }
+ });
+ target.on('dragend', function (ev){
+ if (ev.preventDefault){
+ ev.preventDefault();
+ }
+ target.removeClass('slide-hovered');
+ target.removeClass('hold');
+ });
+ },
+ _reorderCategories: function (){
+ var self = this;
+ self._getCategories();
+ self._rpc({
+ route: '/web/dataset/resequence',
+ params: {
+ model: "slide.category",
+ ids: self.categories
+ }
+ }).then(function (){
+ self._resetCategoriesIndex();
+ });
+ },
+ _resetCategoriesIndex: function (){
+ var categoriesIndexes = $('.section-index')
+ for (var i = 0; i < categoriesIndexes.length; i++){
+ $(categoriesIndexes[i]).text(i+1)
+ }
+ },
+ _reorderSlides: function(){
+ var self = this;
+ // In case the slide was transfered to another section
+ if (self.draggedElement.hasClass('slide-draggable')){
+ self.draggedElement.attr('category_id', parseInt(self.dropTarget.attr('category_id')))
+ }
+ self.slides = [];
+ self._getSlides();
+ self._rpc({
+ route: "/slides/resequence_slides",
+ params: {
+ slides_data: self.slides
+ }
+ }).then(function(){
+ });
+ },
+ _rebindUploadButton: function(categoryID){
+ var self = this;
+ this.$('.oe_slide_js_upload[data-category-id='+categoryID+']').click(function(ev){
+ ev.preventDefault();
+ var data = $(ev.currentTarget).data();
+ var dialog = new SlideUpload.SlideUploadDialog(self, data);
+ dialog.appendTo(document.body);
+ dialog.open();
+ })
+ }
+ })
+
+ sAnimations.registry.websiteSlidesCourseSlidesList = Widget.extend({
+ selector: '.oe_js_course_slides_list',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides_upload.xml'],
+ init: function (el){
+ this._super.apply(this, arguments);
+ },
+ start: function (){
+ this._super.apply(this, arguments);
+ var list = new List(this);
+ list.appendTo(".oe_js_course_slides_list");
+ }
+ });
+}); \ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_delete_slide.js b/addons/website_slides/static/src/js/slides_delete_slide.js
new file mode 100644
index 00000000000..e3eef38502d
--- /dev/null
+++ b/addons/website_slides/static/src/js/slides_delete_slide.js
@@ -0,0 +1,88 @@
+odoo.define('website_slides.delete.slide', function (require) {
+
+ var sAnimations = require('website.content.snippets.animation');
+ var core = require('web.core');
+ var Widget = require('web.Widget');
+
+ var _t = core._t;
+ var QWeb = core.qweb;
+
+ var DeleteSlideDialog = Widget.extend({
+ template: 'website.slide.delete.slide',
+ events: {
+ 'hidden.bs.modal': 'destroy',
+ 'click button[data-dismiss="modal"]': '_cancel',
+ 'click button.delete': '_delete'
+ },
+
+ /**
+ * @override
+ * @param {Object} el
+ * @param {number} channel_id
+ */
+ init: function (el, slideID) {
+ this._super(el, slideID);
+ this.slide_id = parseInt(slideID, 10);
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ this.$el.modal({
+ backdrop: 'static'
+ });
+ return this._super.apply(this, arguments);
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+ _delete: function (ev) {
+ var self = this;
+ // TO FIX: CallBack is not executed
+ $('[slide_id='+this.slide_id+']').remove();
+ this._rpc({
+ model: 'slide.slide',
+ method: 'unlink',
+ args: [[self.slide_id]],
+ }).then(function () {
+ $('[slide='+this.slide_id+']').remove();
+ });
+ },
+ /**
+ * @override
+ */
+ _cancel: function () {
+ this.trigger('cancel');
+ }
+ });
+
+ sAnimations.registry.websiteSlidesDeleteSlide = sAnimations.Class.extend({
+ selector: '.oe_slide_js_delete_slide',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides_upload.xml'],
+ read_events: {
+ 'click': '_onDeleteSlideClick',
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _openDialog: function (slideID) {
+ new DeleteSlideDialog(this, slideID).appendTo(document.body);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onDeleteSlideClick: function (ev) {
+ var target = $(ev.currentTarget);
+ this._openDialog(target.attr('slide_id'));
+ },
+ });
+ return DeleteSlideDialog;
+ });
diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js
index 855b7e52932..7b0a2964bf8 100644
--- a/addons/website_slides/static/src/js/slides_upload.js
+++ b/addons/website_slides/static/src/js/slides_upload.js
@@ -30,6 +30,7 @@ var SlideUploadDialog = Dialog.extend({
this._setup();
this.channelID = parseInt(options.channelId, 10);
+ this.defaultCategoryID = parseInt(options.categoryId,10)
this.canUpload = options.canUpload === 'True';
this.canPublish = options.canPublish === 'True';
@@ -198,6 +199,7 @@ var SlideUploadDialog = Dialog.extend({
*/
_getSelect2DropdownValues: function (){
var result = {};
+ var self = this;
// tags
var tagValues = [];
_.each(this.$('#tag_ids').select2('data'), function (val) {
@@ -211,11 +213,17 @@ var SlideUploadDialog = Dialog.extend({
result['tag_ids'] = tagValues;
}
// category
- var categoryValue = this.$('#category_id').select2('data');
- if (categoryValue && categoryValue.create) {
- result['category_id'] = [0, {'name': categoryValue.text}];
- } else if (categoryValue) {
- result['category_id'] = [categoryValue.id];
+ if(!self.defaultCategoryID){
+ var categoryValue = this.$('#category_id').select2('data');
+ if (categoryValue && categoryValue.create) {
+ result['category_id'] = [0, {'name': categoryValue.text}];
+ } else if (categoryValue) {
+ result['category_id'] = [categoryValue.id];
+ this.categoryID = categoryValue.id;
+ }
+ } else {
+ result['category_id'] = [self.defaultCategoryID];
+ this.categoryID = self.defaultCategoryID;
}
return result;
},
@@ -303,6 +311,25 @@ var SlideUploadDialog = Dialog.extend({
return values;
},
+ _reorderSlidesSequence: function(){
+ var self = this;
+ var slidesElement = $('li.content-slide');
+ var slides = [];
+ for(var i = 0; i < slidesElement.length;i++){
+ slides.push({
+ id: parseInt($(slidesElement[i]).attr('slide_id')),
+ category_id: parseInt($(slidesElement[i]).attr('category_id')),
+ sequence: i
+ })
+ }
+ self._rpc({
+ route: '/slides/resequence_slides',
+ params: {
+ slides_data: slides
+ }
+ }).then(function(){
+ })
+ },
/**
* Init the data relative to the support slide type to upload
*
@@ -325,6 +352,11 @@ var SlideUploadDialog = Dialog.extend({
label: _t('Video'),
template: 'website.slide.upload.modal.video',
},
+ quiz: {
+ icon: 'fa-question-circle',
+ label: _t('Quiz'),
+ template: 'website.slide.upload.quiz'
+ }
};
},
/**
@@ -472,12 +504,11 @@ var SlideUploadDialog = Dialog.extend({
_onChangeSlideUrl: function (ev) {
var self = this;
var url = $(ev.target).val();
-
this._alertRemove();
this.isValidUrl = false;
this.set('can_submit_form', false);
this._fetchUrlPreview(url).then(function (data) {
- this.set('can_submit_form', true);
+ self.set('can_submit_form', true);
if (data.error) {
self._alertDisplay(data.error);
} else {
@@ -508,6 +539,12 @@ var SlideUploadDialog = Dialog.extend({
self.set('state', oldType);
self._alertDisplay(data.error);
} else {
+ //Quick and really dirty fix for reordering issues
+ if(data.channel_type == 'training' && self.categoryID){
+ var categoryElement = $('ul[category_id='+self.categoryID+']');
+ $('<li hidden class="content-slide" slide_id="'+data.slide_id+'" category_id="'+self.categoryID+'">temp</li>').appendTo(categoryElement)
+ self._reorderSlidesSequence();
+ }
window.location = data.url;
}
});
diff --git a/addons/website_slides/static/src/js/website_slides.editor.js b/addons/website_slides/static/src/js/website_slides.editor.js
index 40513e785e2..72a18bb93ee 100644
--- a/addons/website_slides/static/src/js/website_slides.editor.js
+++ b/addons/website_slides/static/src/js/website_slides.editor.js
@@ -5,6 +5,7 @@ var core = require('web.core');
var Dialog = require('web.Dialog');
var QWeb = core.qweb;
var WebsiteNewMenu = require('website.newMenu');
+var wUtils = require('website.utils');
var _t = core._t;
diff --git a/addons/website_slides/static/src/scss/slide_course.scss b/addons/website_slides/static/src/scss/slide_course.scss
new file mode 100644
index 00000000000..38179498415
--- /dev/null
+++ b/addons/website_slides/static/src/scss/slide_course.scss
@@ -0,0 +1,536 @@
+
+.banner{
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 20%;
+ background-color: $primary;
+ width: 256px;
+ opacity: 0;
+ color: #fff;
+ transition: all .3s ease-out;
+ z-index: 2;
+ visibility: hidden;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ margin-left: 15px;
+}
+
+.banner a {
+ font-size: 1.5rem;
+ text-align: center;
+ padding: 20px;
+}
+
+.banner a:hover{
+ cursor: pointer;
+}
+
+.fill {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden
+}
+.fill img {
+ flex-shrink: 0;
+ min-width: 100%;
+ min-height: 100%
+}
+
+.main_image{
+ position: relative
+}
+.main_image:hover{
+ .banner{
+ opacity: 1;
+ visibility: visible;
+ }
+
+}
+
+.course-content {
+ padding: 0;
+
+ ul {
+ list-style: none;
+ padding: 0
+ }
+}
+
+.course-section {
+ margin: 0;
+ background-color: #ddd;
+ display: flex;
+ list-style: none;
+ font-size: 1.05rem;
+ border-bottom: 1px solid #ccc
+}
+
+.content-type {
+ width: 30%;
+}
+
+.content-type:hover{
+ cursor: pointer;
+}
+
+.course-progress-bar{
+ height: 10px;
+ width: 80%;
+ box-sizing: border-box;
+ border-radius: 5px;
+ background-color: rgba(0,0,0,.2);
+ overflow: hidden;
+
+ .progress-gauge{
+ height: 100%;
+ width: 0;
+ background-color: $primary;
+
+ transition: all .8s ease-out;
+ }
+}
+
+.course-rating{
+ color:$primary;
+}
+.course-banner{
+ border-bottom: 1px solid $primary;
+}
+
+.content-tab{
+ .active {
+
+ border: none;
+ border-bottom: 1px solid $secondary;
+ }
+}
+
+.content-tab a:hover{
+ border:none;
+ border-bottom: 1px solid $secondary;
+}
+
+.content-container{
+ border:none;
+}
+
+.content-slide:nth-child(odd){
+ background-color: #f6f6f6;
+}
+
+.content-slide:nth-child(even){
+ background-color: #f9f9f9;
+}
+
+.content-slide-controls {
+ i:hover{
+ color: $primary !important;
+ cursor: pointer;
+ }
+}
+
+.viewer-container {
+ display: flex;
+ align-items: stretch;
+ height: 500px;
+ width: 100%;
+ background-color: #ccc;
+ justify-content: flex-start;
+}
+
+
+
+.slide-infos {
+ margin-top: 1rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: start;
+}
+
+.oe_js_player {
+
+}
+
+.slide-deactivated {
+ pointer-events: none;
+}
+
+.slide-draggable {
+ user-select: none;
+ -khtml-user-drag: element;
+ -webkit-user-drag: element;
+}
+
+.slide-hovered{
+ margin-top: 10px;
+}
+
+.section-draggable {
+ user-select: none;
+ -khtml-user-drag: element;
+ -webkit-user-drag: element;
+}
+
+.hold{
+ border: solid #ccc 4px;
+}
+
+
+.fullscreen {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100%;
+ z-index: 1000;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+
+.sidebar-list{
+ position: fixed;
+ top: 46px;
+ bottom: 0;
+ left: 0;
+ width: 300px;
+ z-index: 2000;
+}
+
+
+
+.sidebar-list-visible {
+ left: 50px;
+}
+
+.show-list {
+ position: absolute;
+ top: 15%;
+ left: 50px;
+ font-size: 2rem;
+ z-index: 10000;
+ color: #a0a0a0;
+ border: 2px solid #ccc;
+ border-radius: 10px;
+ padding: 5px 10px;
+}
+
+.hover-background {
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 3000;
+}
+
+.hover-background:hover {
+ opacity: 1;
+}
+
+
+.show-list:hover {
+ cursor: pointer;
+}
+
+.change-small-screen {
+ font-size: 1.5rem;
+ z-index: 10000;
+ color: #a0a0a0;
+}
+
+.change-small-screen:hover {
+ cursor: pointer;
+ border-color: $primary;
+ color: $primary;
+}
+
+.sidebar-header {
+ padding: 10px 15px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 1.5rem;
+ border-bottom: 1px solid #ccc;
+ height: 80px;
+
+ a {
+ color: black;
+ }
+
+ a:hover {
+ color: $primary;
+ }
+
+ i:hover{
+ color: $primary;
+ }
+}
+
+.close-list:hover {
+ cursor: pointer;
+}
+
+.fullscreen-btn{
+ font-size: 2rem;
+ display: inline-block;
+ a {
+ text-decoration: none;
+ color: $text-muted;
+ }
+}
+
+.fullscreen-btn:hover{
+ cursor: pointer;
+
+ a {
+ color: $primary;
+ }
+}
+
+.sidebar-fullscreen {
+ position: relative;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ height: auto;
+ transform: translateX(-100%);
+ width: 0;
+}
+
+.fullscreen-question-container{
+ background-color: #fff;
+ width: 100%;
+ padding-top: 20px;
+ overflow: auto;
+}
+
+.fullscreen-question{
+ border-radius: 10px;
+ padding: 10px 20px;
+ box-shadow: 0px 1px 4px rgba(0,0,0,.5);
+ margin-top: 50px;
+}
+
+.question-title {
+ font-size: 1.5rem;
+}
+
+.buttons-container{
+ width: 80%;
+ display: flex;
+ justify-content: space-between;
+ flex-direction: row-reverse;
+ margin-top: 40px;
+}
+
+// .slide-resources {
+// border-bottom: 1px solid #ccc;
+// }
+
+.slide-resource {
+ padding: 5px 50px;
+ width: 100%;
+ i{
+ margin-right: 10px;
+ }
+}
+
+.list-cell {
+}
+
+
+.quiz-header{
+ border-bottom: 2px solid #CBCBCB;
+ margin-bottom: 50px;
+}
+
+.quiz-header-container{
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ h1 {
+ width: 80%;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+}
+
+.quiz-good-answer{
+ background-color: #C7EAE9;
+}
+
+.quiz-bad-answer{
+ background-color: #FEBEBE;
+}
+
+.quiz-bad-answer label.radio-box,
+.quiz-good-answer label.radio-box{
+ border: none;
+}
+
+.quiz-bad-answer label.radio-box i{
+ background-color: #FD0606;
+ color: white;
+ height: 100%;
+ width: 100%;
+ font-size: 1.5rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 50px;
+}
+
+.quiz-ignored-answer {
+ color: $text-muted;
+}
+
+
+.quiz-good-answer label.radio-box input:checked + i{
+ height: 100%;
+ width: 100%;
+ background-color: #fff;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 2.4rem;
+ border: 10px solid $primary;
+ border-radius: 50px;
+}
+
+.quiz-answer {
+ border-radius: 10px;
+ padding: 5px 10px;
+ transition: all .2s ease-in-out;
+ display: flex;
+ align-items: center;
+ margin-bottom: 5px;
+}
+
+.quiz-answer:not(.quiz-good-answer,.quiz-bad-answer,.quiz-ignored-answer):hover{
+ background-color: #E5E5E5;
+ cursor: pointer;
+}
+
+label.radio-box{
+ border: 2px solid #CBCBCB;
+ background-color: #fff;
+ width: 50px;
+ height: 50px;
+ display: inline-flex;
+ border-radius: 50%;
+ overflow: hidden;
+ justify-content: center;
+ align-items: center;
+ margin: 0;
+ margin-right: 20px;
+ font-size: 1.2rem;
+ outline: none;
+}
+
+.quiz-answer:not(.quiz-good-answer,.quiz-bad-answer,.quiz-ignored-answer) label.radio-box:hover{
+ cursor: pointer;
+}
+
+label.radio-box input{
+ display:none;
+ outline: none;
+ border: none;
+}
+
+
+label.radio-box span{
+ color: inherit;
+ padding: 20px;
+}
+
+label.radio-box input:checked + span{
+ background-color: $primary;
+ color: #fff;
+}
+
+label.radio-box input:checked{
+ background-color: #C7EAE9;
+}
+
+.quiz-question {
+ border-bottom: 2px solid #CBCBCB;
+ padding-bottom: 20px;
+ margin-bottom: 20px;
+}
+
+.quiz-question-answers {
+ list-style: none;
+ margin: 0;
+ margin-top: 20px;
+ padding: 0;
+ font-size: 1rem;
+}
+
+.submit-quiz {
+ margin-top: 20px;
+}
+
+
+.quiz-modal-background{
+ position: absolute;
+ top: 0;
+ left: 0;
+ background-color: rgba(0,0,0,.5);
+ width: 100%;
+ height: 100%;
+}
+
+.quiz-modal-container{
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.quiz-modal{
+ position: absolute;
+ width: 30%;
+ height: 500px;
+ background-color: #fff;
+ top: 50%;
+ left: 50%;
+ transform: translateX(-50%) translateY(-50%);
+ border-radius: 10px;
+ z-index: 2000;
+}
+.quiz-points-container{
+ font-size: 1.2rem;
+}
+
+.quiz-points {
+ background-color: #C4C4C4;
+ padding: 0 4px ;
+ border-radius: 10px;
+ color: #fff;
+}
+
+
+.quiz-points-won{
+ background-color: $primary;
+}
+
+.webpage-container{
+ background-color: #fff;
+ width: 100%;
+}
+
+.webpage-content {
+ background-color: #fff;
+ height: 100%;
+}
+
+
+
+
diff --git a/addons/website_slides/static/src/scss/slide_slide.scss b/addons/website_slides/static/src/scss/slide_slide.scss
new file mode 100644
index 00000000000..d99aaea101a
--- /dev/null
+++ b/addons/website_slides/static/src/scss/slide_slide.scss
@@ -0,0 +1,156 @@
+.slide-header {
+ background-color: #62495B;
+ height: 200px;
+}
+
+.slide-header-container {
+ width: 1000px;
+ margin: 0 auto;
+ height: 100%;
+}
+
+.slide-header-box{
+ display: flex;
+ height: 100%;
+ width: 50%;
+ flex-direction: column;
+ justify-content: flex-end;
+ padding-bottom: 50px;
+
+ a {
+ color: #fff;
+ font-size: 2.5rem;
+ text-decoration: none !important;
+ }
+}
+
+
+.slide-content-list {
+ position: absolute;
+ top: 140px;
+ left: 80px;
+ background-color: #fff;
+ height: 500px;
+ z-index: 200;
+}
+
+.slide-list{
+ background-color: #fff;
+ list-style: none;
+ height: 100%;
+ padding: 0;
+ overflow: auto;
+ border: 1px solid #ccc;
+ border-left: none;
+ box-sizing: border-box;
+ flex: 1;
+
+ a {
+ text-decoration: none;
+ color: $text-muted;
+ }
+
+ a .active{
+ background-color: #eee !important;
+ }
+}
+
+.slide-content-list-section{
+ border-bottom: 1px solid #fff;
+ color: #9B9B9B;
+ text-transform: uppercase;
+ padding: 10px 15px;
+}
+
+.slide-content-list-slide{
+ color: #666666;
+ padding: 10px 15px;
+}
+
+.slide-list-cell{
+ word-wrap: none;
+ padding: 0.5rem 1rem;;
+ height: 40px;
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ text-decoration: none !important;
+}
+
+.slide-list-cell:hover{
+ background-color: #eee;
+ cursor: pointer;
+}
+
+.slide-list-cell:active{
+ background-color: #eee;
+ cursor: pointer;
+}
+
+
+.slide-content-list-header {
+ padding: 10px 15px;
+ font-size: 1.2rem;
+ background-color: #F7F7F7;
+ color: #6F6F6F;
+}
+
+.slide-button {
+ color: #666;
+ text-decoration: none;
+ border:1px solid #B9B9B9;
+ padding: 5px 10px;
+ width: 50px;
+ text-align: center;
+ text-transform: uppercase;
+ margin: 0;
+ border-radius: 3px;
+}
+
+.slide-button-fullscreen {
+ color: #666;
+ text-decoration: none;
+ border:1px solid #B9B9B9;
+ padding: 5px 10px;
+ text-align: center;
+ text-transform: uppercase;
+ margin: 0;
+ border-radius: 3px;
+}
+
+.slide-button-done {
+ color: #fff;
+ text-transform: uppercase;
+ background-color: $primary;
+ text-decoration: none;
+ padding: 10px 15px;
+ width: 50px;
+ text-align: center;
+ border-radius: 3px;
+ margin: 0;
+}
+
+.slide-title {
+ width: 60%;
+ display: flex;
+ align-items: center;
+
+ h1 {
+ font-size: 1.5rem;
+ }
+
+ .slide-points {
+ margin-left: 20px;
+ padding: 5px 10px;
+ background-color: #DC9D45;
+ border-radius: 10px;
+ color: #fff;
+ font-weight: bold;
+ }
+}
+
+.slide-documentation-sidebar {
+ position: absolute;
+ top: 300px;
+ left: 30px;
+} \ No newline at end of file
diff --git a/addons/website_slides/static/src/scss/slides_slide_fullscreen.scss b/addons/website_slides/static/src/scss/slides_slide_fullscreen.scss
new file mode 100644
index 00000000000..de5493d2f7e
--- /dev/null
+++ b/addons/website_slides/static/src/scss/slides_slide_fullscreen.scss
@@ -0,0 +1,303 @@
+.o_wslides {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 2000;
+
+ .o_wslides_slide_fullscreen_header {
+ align-items: center;
+ background-color: #313A44;
+ color: #AEB0B2;
+ display: flex;
+ height: 50px;
+ justify-content: space-between;
+ width: 100%;
+
+ .o_wslides_fullscreen_slide_title {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ padding: 0 20px;
+ color: #D5D7D9;
+ font-weight: bold;
+
+ i.fa-flag-checkered{
+ color: #D39B4B;
+ margin-right: 10px;
+ }
+ }
+
+ div {
+ display: flex;
+ height: 100%;
+
+ a {
+ align-items: center;
+ background-color: #1F242C;
+ color: inherit;
+ display: flex;
+ font-size: 0.8rem;
+ font-weight: bold;
+ height: 100%;
+ justify-content: center;
+ padding: 0 20px;
+ text-decoration: none !important;
+ text-transform: uppercase;
+
+ i {
+ align-items: center;
+ display: flex;
+ height: 100%;
+ margin: 0;
+ margin-right: 5px;
+ }
+ }
+
+ a:hover,
+ a.active{
+ background-color: #313A44;
+ color: #fff;
+ }
+ }
+ }
+
+ .o_wslides_fullscreen_container {
+ display: flex;
+ align-items: stretch;
+ height: 100%;
+ position: relative;
+ background-color: #313A44;
+ }
+
+ .o_wslides_fullscreen_sidebar_hidden{
+ transform: translateX(-100%);
+ }
+
+ .o_wslides_fullscreen_sidebar{
+ width: 400px;
+ min-width: 400px;
+ background-color: #313A44;
+ color: #fff;
+ transition: all .2s ease-in;
+ overflow: auto;
+
+ a {
+ text-decoration: none !important;
+ color: inherit;
+ }
+
+ ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ }
+
+ li {
+ padding-left: 20px;
+ }
+
+ .o_wslides_fullscreen_sidebar_header{
+ height: 100px;
+ padding: 20px 0;
+ display: flex;
+ flex-direction: column;
+
+ .o_wslides_slide_fullscreen_progress_box{
+ display: flex;
+ align-items: center;
+ font-size: .9rem;
+ .o_wslides_fullscreen_sidebar_progressbar{
+ height: 5px;
+ border-radius: 10px;
+ width: 70%;
+ background-color: rgba(0,0,0,.3);
+ margin-right: 40px;
+ overflow: hidden;
+
+ }
+
+ .o_wslides_fullscreen_sidebar_progress_gauge {
+ background-color: $primary;
+ height: 100%;
+ width: 0;
+ transition: all 1.5s ease-in;
+ }
+
+ span {
+ color: #BABDC0;
+ }
+
+ }
+
+ a {
+ font-size: 1.5rem;
+ font-weight: bold;
+ }
+
+ }
+
+ .o_wslides_fullscreen_sidebar_section {
+ margin-bottom: 20px;
+ background-color: #283038;
+ padding: 10px 0;
+
+ }
+
+ .o_wslides_fullscreen_sidebar_section_tab {
+ color: #656B72;
+ font-size: .8rem;
+ text-transform: uppercase;
+ font-weight: bold;
+ padding: 5px 0 5px 15px;
+ }
+
+ .o_wslides_fullscreen_sidebar_section_slides{
+ padding: 0;
+ margin-bottom: 15px;
+
+
+
+ li {
+ margin: 0;
+ padding: 0;
+ border-left: 2px solid transparent;
+ display: flex;
+
+ a {
+ flex: 1;
+ }
+ }
+
+ .o_wslides_top_line,
+ .o_wslides_bottom_line{
+ width: 1px;
+ display: flex;
+ flex-grow: 1;
+ background-color: #787D82;
+ }
+
+ li:first-child .o_wslides_top_line{
+ background-color: transparent;
+ }
+
+ li:last-child .o_wslides_bottom_line{
+ background-color: transparent;
+ }
+
+ li:hover,
+ li.active {
+ border-left: 2px solid $primary;
+ cursor: pointer;
+ background-color: #1D2228;
+ }
+
+ .o_wslides_fullscreen_sidebar_slide_tab {
+ padding:5px 0 5px 15px;
+ font-size: .8rem;
+ color: #8A8F93;
+ font-weight: bold;
+ flex: 1;
+
+ }
+
+ .o_wslides_fullscreen_sidebar_slide_tab.active{
+ color: #fff;
+ }
+
+ .o_wslides_fullscreen_slide_tab_line{
+ width: 15px;
+ padding: 0;
+ margin: 0;
+ margin-left: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ i {
+ z-index: 100;
+ padding: 0;
+ margin: 0;
+ }
+
+ i.o_wslides_slide_completed{
+ color: #00A04A;
+ border-radius: 50%;
+ overflow: hidden;
+ background-color: #fff;
+ height: 12px;
+ width: 12px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid #00A04A;
+ }
+
+ .o_wslides_full_line{
+ width: 1px;
+ height: 100%;
+ background-color: #787D82;
+ }
+ }
+
+ .o_wslides_slide_link {
+ color: #098586;
+ font-size: .8rem;
+ margin-left: 15px;
+ flex: 1;
+
+ i {
+ margin-right: 10px;
+ }
+ }
+
+ .o_wslides_slide_quiz {
+ font-size: .8rem;
+ margin-left: 15px;
+ color: #8A8F93;
+ flex: 1;
+ i {
+ color: #D39B4B;
+ margin-right: 10px;
+ }
+ }
+ }
+
+
+ }
+
+ .o_wslides_fullscreen_player {
+ display: flex;
+ align-items: stretch;
+ max-width: calc(100% - 400px);
+ height: 100%;
+ background-color: #283038;
+ transition: all .2s ease-in;
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 100%;
+ width: 80%;
+
+ iframe {
+ height: 100%;
+ width: 100%;
+ }
+ }
+
+ .o_wslides_fullscreen_webpage {
+ background-color: #fff;
+ width: 100%;
+ height: 100%;
+ overflow-y: scroll;
+ padding: 20px 0;
+ }
+
+ .o_wslides_fullscreen_player_no_sidebar {
+ max-width: 100%;
+ width: 100%;
+ }
+
+
+} \ No newline at end of file
diff --git a/addons/website_slides/static/src/scss/website_slides_quiz.scss b/addons/website_slides/static/src/scss/website_slides_quiz.scss
new file mode 100644
index 00000000000..9fe4438ee57
--- /dev/null
+++ b/addons/website_slides/static/src/scss/website_slides_quiz.scss
@@ -0,0 +1,237 @@
+
+ .o_wslides_fullscreen_quiz {
+ background-color: #F6F6F6;
+ width: 100%;
+ height: 100%;
+ overflow: scroll;
+ overflow-x: hidden;
+ padding-bottom: 50px;
+
+ }
+
+ .o_wslides_quiz_question {
+ margin-top: 50px;
+ width: 100%;
+ .o_wslides_quiz_question_title {
+ font-size: 1.5rem;
+ margin-bottom: 20px;
+ .o_wslides_quiz_question_title_number {
+ color: #8C8C8C;
+ font-size: 1.3rem;
+ font-weight: bold;
+ }
+
+ .o_wslides_quiz_question_title_text {
+ margin-left: 2px;
+ color: #2F2F2F;
+ }
+ }
+
+ .o_wslides_quiz_question_answers{
+ background-color: #fff;
+ list-style: none;
+ padding: 0;
+
+ .o_wslides_quiz_answer {
+ padding: 10px 20px;
+ border-bottom: 1px solid #B6B6B6;
+ font-size: 1.2rem;
+ display: flex;
+ align-items: center;
+
+ label.o_wslides_quiz_radio_box{
+ background-color: #f6f6f6;
+ width: 35px;
+ height: 35px;
+ display: inline-flex;
+ border-radius: 50%;
+ overflow: hidden;
+ justify-content: center;
+ align-items: center;
+ margin: 0;
+ margin-right: 20px;
+ font-size: 1.2rem;
+ outline: none;
+ border: none;
+ padding: 0;
+ }
+
+ label.o_wslides_quiz_radio_box input{
+ display:none;
+ outline: none;
+ border: none;
+ }
+
+
+ label.o_wslides_quiz_radio_box span{
+ width: 18px;
+ height: 18px;
+ margin: 0;
+ }
+
+ label.o_wslides_quiz_radio_box input:checked + span{
+ background-color: $primary;
+ border-radius: 50%;
+ overflow: hidden;
+ }
+
+ label.o_wslides_quiz_radio_box input:checked{
+ background-color: #C7EAE9;
+ }
+ }
+
+ .o_wslides_quiz_answer:not(.o_wslides_quiz_good_answer,.o_wslides_quiz_bad_answer,.o_wslides_quiz_ignored_answer):hover {
+ cursor: pointer;
+ }
+
+ .o_wslides_quiz_good_answer{
+ border: 2px solid #28A745;
+ label.o_wslides_quiz_radio_box input:checked + i{
+ height: 100%;
+ width: 100%;
+ background-color: #fff;
+ color: #28A745;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 1.4rem;
+ border: 10px solid #28A745;
+ border-radius: 50px;
+ }
+ }
+
+ .o_wslides_quiz_bad_answer{
+ border: 2px solid #A94442;
+
+ label.o_wslides_quiz_radio_box i{
+ background-color: #A94442;
+ color: white;
+ height: 100%;
+ width: 100%;
+ font-size: 1rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ }
+
+
+ .quiz-ignored-answer {
+ color: $text-muted;
+ }
+ }
+ }
+
+ .o_wslides_quiz_modal_background{
+ position: absolute;
+ top: 0;
+ left: 0;
+ background-color: rgba(0,0,0,.2);
+ width: 100%;
+ height: 100%;
+
+ }
+
+ .o_wslides_quiz_success_modal {
+ display: flex;
+ position: absolute;
+ width: 40%;
+ max-width: 600px;
+ height: 450px;
+ background-color: #fff;
+ top: 50%;
+ left: 50%;
+ transform: translateX(-50%) translateY(-50%);
+ z-index: 2000;
+ }
+
+ .o_wslides_quiz_success_modal_left_panel {
+ width: 50%;
+ background-color: #855B79;
+
+ }
+
+ .o_wslides_quiz_success_modal_right_panel{
+ width: 50%;
+ display: flex;
+ flex-direction: column;
+ padding: 10px 20px 10px 50px;
+ position: relative;
+
+ .o_wslides_quiz_success_modal_close {
+ position: absolute;
+ top: 10px;
+ right: 15px;
+ text-transform: uppercase;
+ color: #787878;
+ font-size: 1.2rem;
+ }
+
+ .o_wslides_quiz_success_modal_close:hover{
+ cursor: pointer;
+ }
+
+ h1 {
+ color: #21272B;
+ font-weight: bold;
+ font-size: 2.3rem;
+ padding: 20px 0;
+ letter-spacing: 1px;
+ }
+
+ .o_wslides_quiz_success_progress_bar{
+ height: 10px;
+ width: 100%;
+ background-color: rgba(0,0,0,.1);
+
+ .o_wslides_quiz_success_progress_gauge{
+ width: 75%;
+ height: 100%;
+ background-color: #01ADAB;
+ }
+ }
+
+ .o_wslides_quiz_success_progress_bounds{
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .o_wslides_quiz_success_progress_bounds{
+ font-weight: bold;
+ span:first-child {
+ color: #019F9D;
+ }
+ span:last-child{
+ color: #787878;
+ }
+ }
+
+ .o_wslides_quiz_success_reward {
+ height: 80px;
+ width: 100%;
+ border: 1px dashed #ccc;
+ margin-top: 70px;
+ }
+
+ .o_wslides_quiz_success_button{
+ flex: 1;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-end;
+
+ a {
+ color: #787878;
+ text-transform: uppercase;
+ background-color: #fff;
+ border-radius: 3px;
+ border: 1px solid #C4C4C4;
+ font-weight: bold;
+ padding: 5px 15px;
+ text-align: center;
+ }
+
+ a:hover {
+ cursor: pointer;
+ }
+ }
+ } \ No newline at end of file
diff --git a/addons/website_slides/static/src/xml/website_slides_fullscreen.xml b/addons/website_slides/static/src/xml/website_slides_fullscreen.xml
new file mode 100644
index 00000000000..a9aff0d2ec7
--- /dev/null
+++ b/addons/website_slides/static/src/xml/website_slides_fullscreen.xml
@@ -0,0 +1,111 @@
+<templates id="template" xml:space="preserve">
+ <t t-name="website.slides.fullscreen">
+ <div t-if="slide.slide_type == 'video' &amp;&amp; !showMiniQuiz" class="player embed-responsive embed-responsive-16by9 embed-responsive-item">
+ <iframe id="youtube-player" t-att-src="embed_url" allowFullScreen="true" frameborder="0" enablejsapi="1" autoplay="1" allow="autoplay"></iframe>
+ </div>
+ <div t-if="slide.slide_type in ['presentation', 'document'] &amp;&amp; !showMiniQuiz" class="embed-responsive embed-responsive-4by3 embed-responsive-item ">
+ <iframe t-att-src="embed_url" class="o_wslides_iframe_viewer" allowFullScreen="true" height="315" width="420" frameborder="0"></iframe>
+ </div>
+ <div style="width:100%;height:100%;" t-if="slide.slide_type == 'infographic' &amp;&amp; !showMiniQuiz">
+ <img t-attf-src="/web/image/slide.slide/#{slide.id}/datas" class="img-fluid" style="width: 100%" alt="Slide image"/>
+ </div>
+ <div t-if="(slide.slide_type == 'quiz' || showMiniQuiz) &amp;&amp; questions " class="o_wslides_fullscreen_quiz">
+ <div>
+ <t t-call="website.slide.quiz"/>
+ <div class="container">
+ <button t-if="!slide.done" class="btn btn-primary submit-quiz" >Check your answers</button>
+ <button t-if="embed_url" class="btn btn-primary back-to-video" >Watch again</button>
+ <button t-if="slide.done &amp;&amp; nextSlide" class="btn btn-primary next-slide" >Continue</button>
+ </div>
+ </div>
+ </div>
+ <div t-if="slide.slide_type == 'webpage'" class="o_wslides_fullscreen_webpage">
+ <div class="o_wslides_fullscreen_webpage_content container"/>
+ </div>
+ <div class="o_wslides_fullscreen_content"/>
+ </t>
+
+ <t t-name="website.slide.quiz">
+ <div class="container quiz-questions">
+ <t t-set="i" t-value="1"/>
+ <t t-foreach="questions" t-as="question">
+ <t t-set="j" t-value="0"/>
+ <div class="o_wslides_quiz_question">
+ <div>
+ <div class="o_wslides_quiz_question_title">
+ <span class="o_wslides_quiz_question_title_number"><span t-esc="i"/>. </span>
+ <span class="o_wslides_quiz_question_title_text" t-esc="question.title"/>
+ </div>
+ <ul class="o_wslides_quiz_question_answers">
+ <t t-foreach="question.answers" t-as="answer">
+ <li t-attf-id="answer#{answer.id}" t-att-question_id="question.id" t-att-class="(slide.done &amp;&amp; answer.correct) ? 'o_wslides_quiz_answer o_wslides_quiz_good_answer': slide.done ? 'o_wslides_quiz_answer o_wslides_quiz_ignored_answer' : 'o_wslides_quiz_answer'">
+ <label class="o_wslides_quiz_radio_box">
+ <input t-att-answer_id="answer.id" type="radio" t-att-name="question.id" t-att-question_id="question.id" t-att-value="answer.id" t-att-checked="(slide.done &amp;&amp; answer.correct) ? 'checked' : undefined" t-att-disabled="slide.done"/>
+ <span t-if="!(slide.done &amp;&amp; answer.correct)"/>
+ <i t-if="(slide.done &amp;&amp; answer.correct)" class="fa fa-check-circle"></i>
+ </label>
+ <span t-esc="answer.text"/>
+ </li>
+ <t t-set="j" t-value="j+1"/>
+ </t>
+ </ul>
+ </div>
+ </div>
+ <t t-set="i" t-value="i+1"/>
+ </t>
+ </div>
+ </t>
+
+ <t t-name="website.course.player.infos">
+ <div class="text-box">
+ <h1><t t-esc="slide.name"/></h1>
+ <a t-att-href="url" class="oe_js_show_comments">Show comments</a>
+ </div>
+ <div>
+ <button class="oe_js_slide_full_screen btn btn-secondary">Full Screen</button>
+ <button t-att-current_slide_id="slide.id" class="btn btn-primary oe_js_slide_completed">Mark as completed<i class="fa fa-check-circle ml-1"></i></button>
+ </div>
+ </t>
+
+ <t t-name="website.course.quiz.success">
+ <div class="o_wslides_quiz_modal_background">
+ </div>
+ <div class="o_wslides_quiz_success_modal">
+ <div class="o_wslides_quiz_success_modal_left_panel"></div>
+ <div class="o_wslides_quiz_success_modal_right_panel">
+ <div class="o_wslides_quiz_success_modal_close"><i class="fa fa-times"></i></div>
+ <h1>Amazing!</h1>
+ <div class="o_wslides_quiz_success_xp">
+ <p>You gained <span t-esc="data.points"/> !</p>
+ <div class="o_wslides_quiz_success_progress_bar">
+ <div class="o_wslides_quiz_success_progress_gauge"/>
+ </div>
+ <div class="o_wslides_quiz_success_progress_bounds">
+ <span>600</span>
+ <span>1000</span>
+ </div>
+ </div>
+ <div class="o_wslides_quiz_success_reward"></div>
+ <div class="o_wslides_quiz_success_button">
+ <a class="next-slide">Next &gt;</a>
+ </div>
+ </div>
+ </div>
+ </t>
+
+ <t t-name="website.course.fullscreen.title">
+ <t t-if="!miniQuiz">
+ <i t-if="slide.slide_type == 'document'" class="fa fa-file-pdf-o mr-2"></i>
+ <i t-if="slide.slide_type == 'infographic'" class="fa fa-file-picture-o mr-2"></i>
+ <i t-if="slide.slide_type == 'video'" class="fa fa-play-circle mr-2"></i>
+ <i t-if="slide.slide_type == 'link'" class="fa fa-file-code-o mr-2"></i>
+ <i t-if="slide.slide_type == 'webpage'" class="fa fa-file-text mr-2"></i>
+ <i t-if="slide.slide_type == 'quiz'" class="fa fa-question-circle mr-2 text"></i>
+ <span class="o_wslides_fullscreen_slide_title_span" t-esc="slide.name"/>
+ </t>
+ <t t-else="">
+ <span><i class="fa fa-flag-checkered"></i>Quiz: <span t-esc="slide.name"/></span>
+ </t>
+ </t>
+
+</templates>
diff --git a/addons/website_slides/static/src/xml/website_slides_upload.xml b/addons/website_slides/static/src/xml/website_slides_upload.xml
index 966ff3362cd..d57923c561b 100644
--- a/addons/website_slides/static/src/xml/website_slides_upload.xml
+++ b/addons/website_slides/static/src/xml/website_slides_upload.xml
@@ -47,7 +47,7 @@
<input id="name" name="name" placeholder="Title" class="form-control" required="required"/>
</div>
</div>
- <div class="form-group row">
+ <div t-if="!widget.defaultCategoryID" class="form-group row">
<label for="category_id" class="col-form-label col-md-3">Category</label>
<div class="controls col-md-9">
<input class="form-control" id="category_id"/>
@@ -155,4 +155,107 @@
</div>
</t>
+ <t t-name="website.slide.upload.quiz">
+ <div>
+ <form class="clearfix">
+ <canvas id="data_canvas" class="d-none"></canvas>
+ <t t-call="website.slide.upload.modal.common"/>
+ </form>
+ </div>
+ </t>
+
+ <t t-name="website.slide.image.upload">
+ <div role="dialog" class="modal" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <header class="modal-header">
+ <h3 class="modal-title">Upload Image</h3>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+ </header>
+ <div class="oe_slides_upload_loading text-center" style="display:none" aria-hidden="true" role="status">
+ <h4><i class='fa fa-spinner fa-spin'></i> Uploading Image... </h4>
+ </div>
+ <main class="modal-body">
+ <form class="clearfix">
+ <div class="form-group row">
+ <div class="col-md-4">
+ <div class="img-thumbnail">
+ <div class="o_slide_preview">
+ <img src="/website_slides/static/src/img/document.png" id="slide-image" title="Content Preview" alt="Content Preview" class="img-fluid"/>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-8">
+ <ul class="list-group">
+ <li class="list-group-item">
+ <h5 class="list-group-item-heading">
+ <label for="upload" class="col-form-label">Image File</label>
+ </h5>
+ <input id="upload" name="file" class="form-control" accept="image/*,application/pdf" type="file"/>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <canvas id="data_canvas" style="display: none;"></canvas>
+ </form>
+ </main>
+ <footer class="modal-footer">
+ <button type="button" data-loading-text="Loading..." data-published="true" class="btn btn-primary save">Upload</button>
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Discard</button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </t>
+
+ <t t-name="website.slide.delete.slide">
+ <div role="dialog" class="modal" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <header class="modal-header">
+ <h3 class="modal-title">Delete Slide</h3>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+ </header>
+ <main class="modal-body">
+ <div>
+ <p>Are you sure you want to remove this slide ? </p>
+ </div>
+ </main>
+ <footer class="modal-footer">
+ <button type="button" class="btn btn-primary delete" data-dismiss="modal">Delete</button>
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </t>
+
+ <t t-name="website.slide.add.section">
+ <div role="dialog" class="modal" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <header class="modal-header">
+ <h3 class="modal-title">Add a section</h3>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+ </header>
+ <main class="modal-body modal-content">
+ <form class="clearfix">
+ <div class="form-group row">
+ <label for="section_name" class="col-form-label col-md-3">Section name</label>
+ <div class="col-md-9">
+ <input type="text" class="form-control" id="section_name"/>
+ </div>
+ </div>
+ <canvas id="data_canvas" style="display: none;"></canvas>
+ </form>
+ </main>
+ <footer class="modal-footer">
+ <button type="button" data-loading-text="Loading..." data-published="true" class="btn btn-primary save">Add</button>
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Discard</button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </t>
+
</templates>