From 6dde4061814856fc178569dce14ef189ede284bc Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Wed, 4 Dec 2019 10:04:26 +0100 Subject: [PATCH 001/161] Started prototype --- js/InteractiveVideoPlayerFunctions.js | 12 ++++++++++++ plugin.php | 2 +- templates/default/tpl.video_config.html | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/js/InteractiveVideoPlayerFunctions.js b/js/InteractiveVideoPlayerFunctions.js index efdac9b0f..7019fc5f1 100644 --- a/js/InteractiveVideoPlayerFunctions.js +++ b/js/InteractiveVideoPlayerFunctions.js @@ -50,6 +50,7 @@ il.InteractiveVideoPlayerFunction = (function (scope) { if (!isNaN(current_time) && current_time > 0) { + pri.checkForCompulsoryQuestion(player_id, current_time); pri.utils.clearCommentsWhereTimeEndEndded(player_id, current_time); for (j = player_data.stopPoints.length - 1; j >= 0; j--) { @@ -78,6 +79,17 @@ il.InteractiveVideoPlayerFunction = (function (scope) { } }; + pri.checkForCompulsoryQuestion = function(player_id, current_time) + { + let compulsory_question = il.InteractiveVideo[player_id].compulsoryQuestions; + $.each(compulsory_question, function (time, comment_id) { + if(current_time >= time) { + il.InteractiveVideoPlayerAbstract.setCurrentTime(time - 0.6, player_id); + //Todo: remove compulsory question after answer + } + }); + }; + pub.appendInteractionEvents = function(player_id) { pro.addAjaxFunctionForCommentPosting(player_id); diff --git a/plugin.php b/plugin.php index e7c19897e..187493ecc 100644 --- a/plugin.php +++ b/plugin.php @@ -3,7 +3,7 @@ $id = 'xvid'; // code version; must be changed for all code changes -$version = '2.0.25'; +$version = '2.0.51'; // ilias min and max version; must always reflect the versions that should // run with the plugin diff --git a/templates/default/tpl.video_config.html b/templates/default/tpl.video_config.html index 3d5989990..1a3bcc732 100644 --- a/templates/default/tpl.video_config.html +++ b/templates/default/tpl.video_config.html @@ -30,6 +30,7 @@ interactive_video_ref_id: '{INTERACTIVE_VIDEO_REF_ID}', installation_client_id : '{INTERACTIVE_INSTALLATION_CLIENT_ID}', stopPoints: {STOP_POINTS}, + compulsoryQuestions: {"1": 212, "3": 312}, ignore_questions: {IGNORE_QUESTIONS}, username: "{USERNAME}", user_image: "{USER_IMAGE}", From 532093ca131845e704426cacf19f7739f1955bbc Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Tue, 10 Dec 2019 09:39:15 +0100 Subject: [PATCH 002/161] WiP --- js/InteractiveVideoPlayerFunctions.js | 9 ++++++--- templates/default/tpl.video_config.html | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/js/InteractiveVideoPlayerFunctions.js b/js/InteractiveVideoPlayerFunctions.js index 7019fc5f1..2d60e76a3 100644 --- a/js/InteractiveVideoPlayerFunctions.js +++ b/js/InteractiveVideoPlayerFunctions.js @@ -82,11 +82,14 @@ il.InteractiveVideoPlayerFunction = (function (scope) { pri.checkForCompulsoryQuestion = function(player_id, current_time) { let compulsory_question = il.InteractiveVideo[player_id].compulsoryQuestions; - $.each(compulsory_question, function (time, comment_id) { - if(current_time >= time) { - il.InteractiveVideoPlayerAbstract.setCurrentTime(time - 0.6, player_id); + $.each(compulsory_question, function (key, object) { + console.log(object) + if(object.answered == false){ + if(current_time >= object.time) { + il.InteractiveVideoPlayerAbstract.setCurrentTime(object.time - 0.6, player_id); //Todo: remove compulsory question after answer } + } }); }; diff --git a/templates/default/tpl.video_config.html b/templates/default/tpl.video_config.html index 1a3bcc732..2305ebefd 100644 --- a/templates/default/tpl.video_config.html +++ b/templates/default/tpl.video_config.html @@ -30,7 +30,7 @@ interactive_video_ref_id: '{INTERACTIVE_VIDEO_REF_ID}', installation_client_id : '{INTERACTIVE_INSTALLATION_CLIENT_ID}', stopPoints: {STOP_POINTS}, - compulsoryQuestions: {"1": 212, "3": 312}, + compulsoryQuestions: [{"time" : 1, "comment_id" : 233, "answered": false}, {"time" : 3, "comment_id" : 234, "answered": true}], ignore_questions: {IGNORE_QUESTIONS}, username: "{USERNAME}", user_image: "{USER_IMAGE}", From fa18129c35919225e4424b9b4f03401edfc9abf2 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Fri, 13 Mar 2020 11:18:43 +0100 Subject: [PATCH 003/161] Add form elements for compulsory questions --- classes/class.SimpleChoiceQuestion.php | 54 ++++++++++++++++++++++ classes/class.ilObjInteractiveVideoGUI.php | 15 ++++-- lang/ilias_de.lang | 3 +- lang/ilias_en.lang | 4 +- plugin.php | 2 +- sql/dbupdate.php | 16 +++++++ templates/default/tpl.video_config.html | 3 +- 7 files changed, 90 insertions(+), 7 deletions(-) diff --git a/classes/class.SimpleChoiceQuestion.php b/classes/class.SimpleChoiceQuestion.php index 5cc12b516..5840eb358 100644 --- a/classes/class.SimpleChoiceQuestion.php +++ b/classes/class.SimpleChoiceQuestion.php @@ -123,6 +123,11 @@ class SimpleChoiceQuestion */ protected $question_image = ''; + /** + * @var int + */ + protected $compulsory_question = 0; + /** * @var string */ @@ -172,6 +177,7 @@ public function read() $this->setIsJumpWrong($row['is_jump_wrong']); $this->setShowWrongIcon($row['show_wrong_icon']); $this->setJumpWrongTs($row['jump_wrong_ts']); + $this->setCompulsoryQuestion($row['compulsory_question']); $this->setShowResponseFrequency($row['show_response_frequency']); $this->setFeedbackCorrectId($row['feedback_correct_ref_id']); $this->setFeedbackWrongId($row['feedback_wrong_ref_id']); @@ -394,6 +400,7 @@ public function cloneQuestionObject($old_comment_id, $new_comment_id) $this->setIsJumpWrong($row['is_jump_wrong']); $this->setShowWrongIcon($row['show_wrong_icon']); $this->setJumpWrongTs($row['jump_wrong_ts']); + $this->setCompulsoryQuestion($row['compulsory_question']); $this->setShowResponseFrequency($row['show_response_frequency']); $this->setFeedbackCorrectId($row['feedback_correct_ref_id']); $this->setFeedbackWrongId($row['feedback_wrong_ref_id']); @@ -447,6 +454,7 @@ public function create() 'show_wrong_icon' => array('integer', $this->getShowWrongIcon()), 'is_jump_wrong' => array('integer', $this->getIsJumpWrong()), 'jump_wrong_ts' => array('integer', $this->getJumpWrongTs()), + 'compulsory_question' => array('integer', $this->getCompulsoryQuestion()), 'show_response_frequency' => array('integer', $this->getShowResponseFrequency()), 'feedback_correct_ref_id' => array('integer', $this->getFeedbackCorrectId()), 'feedback_wrong_ref_id' => array('integer', $this->getFeedbackWrongId()), @@ -864,6 +872,36 @@ public function getAllNonRepeatAnsweredQuestion($user_id) return $results; } + /** + * @param int $obj_id + * @return array + */ + public static function getAllCompulsoryQuestions($obj_id) + { + global $ilDB; + $res = $ilDB->queryF(' + SELECT * + FROM ' . self::TABLE_NAME_COMMENTS . ' comments, + ' . self::TABLE_NAME_QUESTION . ' questions + LEFT JOIN rep_robj_xvid_score ON questions.question_id = rep_robj_xvid_score.question_id + WHERE comments.comment_id = questions.comment_id + AND questions.compulsory_question = 1 + AND comments.obj_id = %s', + array('integer'), + array((int)$obj_id) + ); + $results = array(); + while($row = $ilDB->fetchAssoc($res)) + { + $results[] = [ + 'time' => $row['comment_time'], + 'comment_id' => $row['comment_id'], + 'answered' => $row['points'] != null ? true : false + ]; + } + return $results; + } + /** * @param int $user_id * @return array @@ -1257,4 +1295,20 @@ public function setQuestionImage($question_image) { $this->question_image = $question_image; } + + /** + * @return int + */ + public function getCompulsoryQuestion() + { + return $this->compulsory_question; + } + + /** + * @param int $compulsory_question + */ + public function setCompulsoryQuestion($compulsory_question) + { + $this->compulsory_question = $compulsory_question; + } } diff --git a/classes/class.ilObjInteractiveVideoGUI.php b/classes/class.ilObjInteractiveVideoGUI.php index f3a520230..602cffeb9 100644 --- a/classes/class.ilObjInteractiveVideoGUI.php +++ b/classes/class.ilObjInteractiveVideoGUI.php @@ -539,17 +539,20 @@ protected function initPlayerConfig($player_id, $video_type, $edit_screen = fals $config_tpl->setVariable('USER_IMAGE', ilObjComment::getUserImageInBase64($ilUser->getId())); } - $stop_points = array(); - $comments = array(); - $image_cache = array(); + $stop_points = array(); + $comments = array(); + $image_cache = array(); + $compulsory_questions = array(); if( ! $edit_screen) { $stop_points = $this->objComment->getStopPoints(); $comments = $this->objComment->getContentComments(); $image_cache = ilObjComment::getUserImageCache(); + $compulsory_questions = SimpleChoiceQuestion::getAllCompulsoryQuestions($this->obj_id); } $config_tpl->setVariable('STOP_POINTS', json_encode($stop_points)); + $config_tpl->setVariable('COMPULSORY_QUESTIONS', json_encode($compulsory_questions)); $config_tpl->setVariable('COMMENTS', json_encode($comments)); $config_tpl->setVariable('USER_IMAGES_CACHE', json_encode($image_cache)); $config_tpl->setVariable('INTERACTIVE_VIDEO_REF_ID', $this->object->getRefId()); @@ -2000,6 +2003,10 @@ public function initQuestionForm() $repeat_question->setInfo($plugin->txt('repeat_question_info')); $form->addItem($repeat_question); + $compulsory_question = new ilCheckboxInputGUI($plugin->txt('compulsory_question'), 'compulsory_question'); + $compulsory_question->setInfo($plugin->txt('compulsory_question_info')); + $form->addItem($compulsory_question); + $limit_attempts = new ilCheckboxInputGUI($plugin->txt('limit_attempts'), 'limit_attempts'); $limit_attempts->setInfo($plugin->txt('limit_attempts_info')); $form->addItem($limit_attempts); @@ -2274,6 +2281,7 @@ private function getQuestionFormValues($comment_id = 0) $values['jump_wrong_ts'] = $question_data['question_data']['jump_wrong_ts']; $values['limit_attempts'] = $question_data['question_data']['limit_attempts']; $values['repeat_question'] = $question_data['question_data']['repeat_question']; + $values['compulsory_question'] = $question_data['question_data']['compulsory_question']; $values['feedback_correct_obj'] = $question_data['question_data']['feedback_correct_ref_id']; $values['feedback_wrong_obj'] = $question_data['question_data']['feedback_wrong_ref_id']; $values['show_comment_field'] = $question_data['question_data']['reflection_question_comment']; @@ -2404,6 +2412,7 @@ private function performQuestionRefresh($comment_id, $form) $question->setShowResponseFrequency((int)$form->getInput('show_response_frequency')); $question->setRepeatQuestion((int)$form->getInput('repeat_question')); + $question->setCompulsoryQuestion((int)$form->getInput('compulsory_question')); $question->setReflectionQuestionComment((int)$form->getInput('show_comment_field')); $question->setNeutralAnswer((int)$form->getInput('neutral_type')); $question->deleteQuestionsIdByCommentId($comment_id); diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 5f5d7da06..541b5af2e 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -197,4 +197,5 @@ sure_delete_subtitle#:#Sind Sie sicher das sie diesen Untertitle löschen wollen you_need_a_short_title#:#Sie müssen einen Kurztitle eintragen! no_toolbar#:#Toolbar deaktivieren no_toolbar_info#:#Es wird keine Toolbar mit Filtern angezeigt - +compulsory_question#:#Verpfilchtende Frage +compulsory_question_info#:#Diese Frage muss beantwortet werden, bevor das Video weiter geschaut werden kann diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 39b16bfd9..2fca54f8c 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -196,4 +196,6 @@ subtitle_removed#:#Subtitle removed sure_delete_subtitle#:#Are you sure you want to remove this subtitle? you_need_a_short_title#:#You need to provide a short title! no_toolbar#:#Deactivate toolbar -no_toolbar_info#:#No toolbar with filters will be shown \ No newline at end of file +no_toolbar_info#:#No toolbar with filters will be shown +compulsory_question#:#Compulsory question +compulsory_question_info#:#This question must be answered \ No newline at end of file diff --git a/plugin.php b/plugin.php index 187493ecc..e3fb26210 100644 --- a/plugin.php +++ b/plugin.php @@ -3,7 +3,7 @@ $id = 'xvid'; // code version; must be changed for all code changes -$version = '2.0.51'; +$version = '2.0.52'; // ilias min and max version; must always reflect the versions that should // run with the plugin diff --git a/sql/dbupdate.php b/sql/dbupdate.php index 23ac09f6e..23e5ba3f8 100644 --- a/sql/dbupdate.php +++ b/sql/dbupdate.php @@ -952,3 +952,19 @@ ); } ?> +<#51> +tableExists('rep_robj_xvid_question')) +{ + if(!$ilDB->tableColumnExists('rep_robj_xvid_question', 'compulsory_question')) + { + $ilDB->addTableColumn('rep_robj_xvid_question', 'compulsory_question', + array( + 'type' => 'integer', + 'length' => '1', + 'notnull' => false, + 'default' => null + )); + } +} +?> diff --git a/templates/default/tpl.video_config.html b/templates/default/tpl.video_config.html index 2305ebefd..f7756925c 100644 --- a/templates/default/tpl.video_config.html +++ b/templates/default/tpl.video_config.html @@ -30,7 +30,8 @@ interactive_video_ref_id: '{INTERACTIVE_VIDEO_REF_ID}', installation_client_id : '{INTERACTIVE_INSTALLATION_CLIENT_ID}', stopPoints: {STOP_POINTS}, - compulsoryQuestions: [{"time" : 1, "comment_id" : 233, "answered": false}, {"time" : 3, "comment_id" : 234, "answered": true}], + compulsoryQuestions: {COMPULSORY_QUESTIONS}, + //compulsoryQuestions: [{"time" : 1, "comment_id" : 233, "answered": false}, {"time" : 3, "comment_id" : 234, "answered": true}], ignore_questions: {IGNORE_QUESTIONS}, username: "{USERNAME}", user_image: "{USER_IMAGE}", From abea61109d3100980d35f411ad056549c3f04ebe Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 10:07:37 +0100 Subject: [PATCH 004/161] Implement more logic for compulsory question --- classes/class.SimpleChoiceQuestion.php | 2 +- .../class.SimpleChoiceQuestionAjaxHandler.php | 2 ++ classes/class.ilObjInteractiveVideoGUI.php | 1 + js/InteractiveVideoPlayerFunctions.js | 4 +-- js/jquery.InteractiveVideoQuestionViewer.js | 27 +++++++++++++++---- templates/default/tpl.video_config.html | 4 +-- templates/default/xvid.css | 10 +++++++ 7 files changed, 40 insertions(+), 10 deletions(-) diff --git a/classes/class.SimpleChoiceQuestion.php b/classes/class.SimpleChoiceQuestion.php index 5840eb358..0db1877b8 100644 --- a/classes/class.SimpleChoiceQuestion.php +++ b/classes/class.SimpleChoiceQuestion.php @@ -893,7 +893,7 @@ public static function getAllCompulsoryQuestions($obj_id) $results = array(); while($row = $ilDB->fetchAssoc($res)) { - $results[] = [ + $results[$row['comment_id']] = [ 'time' => $row['comment_time'], 'comment_id' => $row['comment_id'], 'answered' => $row['points'] != null ? true : false diff --git a/classes/class.SimpleChoiceQuestionAjaxHandler.php b/classes/class.SimpleChoiceQuestionAjaxHandler.php index fb7baa755..ee8b36d50 100644 --- a/classes/class.SimpleChoiceQuestionAjaxHandler.php +++ b/classes/class.SimpleChoiceQuestionAjaxHandler.php @@ -192,6 +192,7 @@ public function getJsonForCommentId($cid) $repeat_question = $row['repeat_question']; $show_reflection_question_comment = $row['reflection_question_comment']; $question_image = $row['question_image']; + $compulsory = $row['compulsory_question']; #$neutral_answer = $row['neutral_answer']; $counter++; } @@ -227,6 +228,7 @@ public function getJsonForCommentId($cid) $build_json['jump_wrong_ts'] = $jump_wrong_ts; $build_json['show_response_frequency'] = $show_response_frequency; $build_json['reflection_question_comment'] = $show_reflection_question_comment; + $build_json['compulsory_question'] = $compulsory; $build_json['repeat_question'] = $repeat_question; if($question_image != null) { diff --git a/classes/class.ilObjInteractiveVideoGUI.php b/classes/class.ilObjInteractiveVideoGUI.php index 602cffeb9..f223de94b 100644 --- a/classes/class.ilObjInteractiveVideoGUI.php +++ b/classes/class.ilObjInteractiveVideoGUI.php @@ -496,6 +496,7 @@ protected function initPlayerConfig($player_id, $video_type, $edit_screen = fals $config_tpl->setVariable('LEARNING_RECOMMENDATION_TEXT', $plugin->txt('learning_recommendation')); $config_tpl->setVariable('MORE_INFORMATION_TEXT', $plugin->txt('more_informations')); $config_tpl->setVariable('ALREADY_ANSWERED_TEXT', $plugin->txt('already_answered')); + $config_tpl->setVariable('COMPULSORY', $plugin->txt('compulsory_question')); $config_tpl->setVariable('QUESTION_TEXT', $plugin->txt('question')); $config_tpl->setVariable('PRIVATE_TEXT', $plugin->txt('is_private_comment')); $config_tpl->setVariable('RESET_TEXT', $plugin->txt('reset')); diff --git a/js/InteractiveVideoPlayerFunctions.js b/js/InteractiveVideoPlayerFunctions.js index 2d60e76a3..064b8789c 100644 --- a/js/InteractiveVideoPlayerFunctions.js +++ b/js/InteractiveVideoPlayerFunctions.js @@ -83,11 +83,11 @@ il.InteractiveVideoPlayerFunction = (function (scope) { { let compulsory_question = il.InteractiveVideo[player_id].compulsoryQuestions; $.each(compulsory_question, function (key, object) { - console.log(object) if(object.answered == false){ if(current_time >= object.time) { - il.InteractiveVideoPlayerAbstract.setCurrentTime(object.time - 0.6, player_id); + il.InteractiveVideoPlayerAbstract.setCurrentTime(object.time - 0.1, player_id); //Todo: remove compulsory question after answer + return false; } } }); diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index 697ecc2b6..538031f5b 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -18,17 +18,32 @@ var InteractiveVideoQuestionViewer = (function (scope) { }); }; + pro.addCompulsoryHeader = function(header){ + $('#ilQuestionModal .modal-header').removeClass('compulsory'); + if(pub.QuestionObject.compulsory_question === "1") { + header = '' + il.InteractiveVideo["lang"].compulsory + ''; + $('#ilQuestionModal .modal-header').addClass('compulsory'); + } + return header; + }; + pro.buildQuestionForm = function(player) { - let modal = $('.modal-body'); - let type = parseInt(pub.QuestionObject.type, 10); - let img = ''; + let modal = $('.modal-body'); + let type = parseInt(pub.QuestionObject.type, 10); + let img = ''; + let header = ''; modal.html(''); - $('.modal-title').html(pub.QuestionObject.question_title); + + header = pro.addCompulsoryHeader(); + + $('.modal-title').html(pub.QuestionObject.question_title + ' ' + header); + if(pub.QuestionObject.question_image) { img = '
'; } + modal.append(img + '

' + pub.QuestionObject.question_text + '

'); if (type === 0) { pro.addAnswerPossibilities('radio'); @@ -250,7 +265,9 @@ var InteractiveVideoQuestionViewer = (function (scope) { } var config = {}; - if(il.InteractiveVideoPlayerFunction.getPlayerDataObjectByPlayer(player).fixed_modal === "1") { + if(il.InteractiveVideoPlayerFunction.getPlayerDataObjectByPlayer(player).fixed_modal === "1" || + pub.QuestionObject.compulsory_question === "1" + ) { config = {backdrop: 'static', keyboard: false}; } $('#ilQuestionModal').modal(config, 'show'); diff --git a/templates/default/tpl.video_config.html b/templates/default/tpl.video_config.html index f7756925c..f4307cee5 100644 --- a/templates/default/tpl.video_config.html +++ b/templates/default/tpl.video_config.html @@ -17,7 +17,8 @@ author_filter: '{AUTHOR_FILTER}', save: '{SAVE}', add_comment: '{ADD_COMMENT}', - more_information: '{MORE_INFORMATION_TEXT}' + more_information: '{MORE_INFORMATION_TEXT}', + compulsory: '{COMPULSORY}' }; var player = { @@ -31,7 +32,6 @@ installation_client_id : '{INTERACTIVE_INSTALLATION_CLIENT_ID}', stopPoints: {STOP_POINTS}, compulsoryQuestions: {COMPULSORY_QUESTIONS}, - //compulsoryQuestions: [{"time" : 1, "comment_id" : 233, "answered": false}, {"time" : 3, "comment_id" : 234, "answered": true}], ignore_questions: {IGNORE_QUESTIONS}, username: "{USERNAME}", user_image: "{USER_IMAGE}", diff --git a/templates/default/xvid.css b/templates/default/xvid.css index 489867607..673f8b1f4 100644 --- a/templates/default/xvid.css +++ b/templates/default/xvid.css @@ -431,4 +431,14 @@ body.cke_editable{ .iv_light_version{ display:none !important; +} + +.compulsory_question{ + float:right; + margin-right: 10px; + font-style: italic; +} + +.modal-header.compulsory{ + background-color: khaki; } \ No newline at end of file From e6cd52b73b990c906f24e5d806f237ee4f90e69a Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 10:28:34 +0100 Subject: [PATCH 005/161] Make question modal not static if compulsory question is anwsered --- js/jquery.InteractiveVideoQuestionViewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index 538031f5b..549ed94b6 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -266,7 +266,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { var config = {}; if(il.InteractiveVideoPlayerFunction.getPlayerDataObjectByPlayer(player).fixed_modal === "1" || - pub.QuestionObject.compulsory_question === "1" + ( pub.QuestionObject.compulsory_question === "1" && ! pub.QuestionObject.feedback ) ) { config = {backdrop: 'static', keyboard: false}; } From 1f498909142cf69bf692c1322edd22185ecdb706 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 14:22:24 +0100 Subject: [PATCH 006/161] More logic for compulsory question --- classes/class.SimpleChoiceQuestion.php | 11 +++--- js/InteractiveVideoPlayerFunctions.js | 5 +-- js/jquery.InteractiveVideoQuestionViewer.js | 38 ++++++++++++++------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/classes/class.SimpleChoiceQuestion.php b/classes/class.SimpleChoiceQuestion.php index 0db1877b8..d6adb6ee1 100644 --- a/classes/class.SimpleChoiceQuestion.php +++ b/classes/class.SimpleChoiceQuestion.php @@ -880,7 +880,7 @@ public static function getAllCompulsoryQuestions($obj_id) { global $ilDB; $res = $ilDB->queryF(' - SELECT * + SELECT comments.comment_time, questions.question_id, comments.comment_id, points FROM ' . self::TABLE_NAME_COMMENTS . ' comments, ' . self::TABLE_NAME_QUESTION . ' questions LEFT JOIN rep_robj_xvid_score ON questions.question_id = rep_robj_xvid_score.question_id @@ -893,10 +893,11 @@ public static function getAllCompulsoryQuestions($obj_id) $results = array(); while($row = $ilDB->fetchAssoc($res)) { - $results[$row['comment_id']] = [ - 'time' => $row['comment_time'], - 'comment_id' => $row['comment_id'], - 'answered' => $row['points'] != null ? true : false + $results[$row['question_id']] = [ + 'time' => $row['comment_time'], + 'question_id' => $row['question_id'], + 'comment_id' => $row['comment_id'], + 'answered' => $row['points'] != null ? true : false ]; } return $results; diff --git a/js/InteractiveVideoPlayerFunctions.js b/js/InteractiveVideoPlayerFunctions.js index 064b8789c..3edad803d 100644 --- a/js/InteractiveVideoPlayerFunctions.js +++ b/js/InteractiveVideoPlayerFunctions.js @@ -85,8 +85,9 @@ il.InteractiveVideoPlayerFunction = (function (scope) { $.each(compulsory_question, function (key, object) { if(object.answered == false){ if(current_time >= object.time) { - il.InteractiveVideoPlayerAbstract.setCurrentTime(object.time - 0.1, player_id); - //Todo: remove compulsory question after answer + il.InteractiveVideoPlayerAbstract.pause(player_id); + //il.InteractiveVideoPlayerAbstract.setCurrentTime(parseInt(object.time, 10) + 0.1, player_id); + InteractiveVideoQuestionViewer.getQuestionPerAjax(object.comment_id, player_id); return false; } } diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index 549ed94b6..56c53fe14 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -1,21 +1,27 @@ var InteractiveVideoQuestionViewer = (function (scope) { 'use strict'; let pub = {}, - pro = {}; + pro = {}, + pri = { + locked : false + }; pub.QuestionObject = {}; pub.getQuestionPerAjax = function (comment_id, player) { - let player_data = il.InteractiveVideoPlayerFunction.getPlayerDataObjectByPlayer(player); - - $.when( - $.ajax({ - url: player_data.question_get_url + '&comment_id=' + comment_id, - type: 'GET', dataType: 'json' - }) - ).then(function (array) { - pro.showQuestionInteractionForm(comment_id, array, player); - }); + if(pri.locked === false) { + pri.locked = true; + let player_data = il.InteractiveVideoPlayerFunction.getPlayerDataObjectByPlayer(player); + + $.when( + $.ajax({ + url: player_data.question_get_url + '&comment_id=' + comment_id, + type: 'GET', dataType: 'json' + }) + ).then(function (array) { + pro.showQuestionInteractionForm(comment_id, array, player); + }); + } }; pro.addCompulsoryHeader = function(header){ @@ -35,7 +41,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { modal.html(''); - header = pro.addCompulsoryHeader(); + header = pro.addCompulsoryHeader(header); $('.modal-title').html(pub.QuestionObject.question_title + ' ' + header); @@ -180,7 +186,6 @@ var InteractiveVideoQuestionViewer = (function (scope) { modal.append('

' + language.learning_recommendation_text + ': ' + pro.createButtonButtons('jumpToTimeInVideo', language.feedback_button_text + ' ' + mejs.Utility.secondsToTimeCode(feedback.time)) + '
', ''); $('#jumpToTimeInVideo').on('click', function () { $('#ilQuestionModal').modal('hide'); - console.log(player) var player_id = scope.InteractiveVideoPlayerFunction.getPlayerIdFromPlayerObject(player); scope.InteractiveVideoPlayerAbstract.jumpToTimeInVideo(feedback.time, player_id); }); @@ -226,6 +231,11 @@ var InteractiveVideoQuestionViewer = (function (scope) { data: $(this).serialize(), success: function (feedback) { let obj = JSON.parse(feedback); + let question_id = InteractiveVideoQuestionViewer.QuestionObject.question_id; + console.log(question_id) + if(question_id in il.InteractiveVideo[player_id].compulsoryQuestions) { + il.InteractiveVideo[player_id].compulsoryQuestions[question_id].answered = true; + } pro.showFeedback(obj, player); pro.addToLocalIgnoreArrayIfNonRepeatable(player_id); } @@ -242,11 +252,13 @@ var InteractiveVideoQuestionViewer = (function (scope) { close_form.off('click'); close_form.on('click', function () { $('#ilQuestionModal').modal('hide'); + pri.locked = false; }); question_modal.off('hidden.bs.modal'); question_modal.on('hidden.bs.modal', function () { scope.InteractiveVideoPlayerAbstract.resumeVideo(player_id); + pri.locked = false; }) }; From f52a97def2b9bdf18b59d2a876e53efd883b44df Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 14:52:59 +0100 Subject: [PATCH 007/161] Code cleanup --- js/jquery.InteractiveVideoQuestionViewer.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index 56c53fe14..15d7bd857 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -1,9 +1,9 @@ var InteractiveVideoQuestionViewer = (function (scope) { 'use strict'; let pub = {}, - pro = {}, - pri = { - locked : false + pro = {}, + pri = { + locked : false }; pub.QuestionObject = {}; @@ -55,14 +55,11 @@ var InteractiveVideoQuestionViewer = (function (scope) { pro.addAnswerPossibilities('radio'); pro.addFeedbackDiv(); pro.addButtons(player); - } - else if (type === 1){ + } else if (type === 1) { pro.addAnswerPossibilities('checkbox'); pro.addFeedbackDiv(); pro.addButtons(player); - } - else if (type === 2) - { + } else if (type === 2) { pro.addSelfReflectionLayout(player); } pro.showPreviousAnswer(player); @@ -100,9 +97,9 @@ var InteractiveVideoQuestionViewer = (function (scope) { { return '' + '
' + @@ -232,7 +229,6 @@ var InteractiveVideoQuestionViewer = (function (scope) { success: function (feedback) { let obj = JSON.parse(feedback); let question_id = InteractiveVideoQuestionViewer.QuestionObject.question_id; - console.log(question_id) if(question_id in il.InteractiveVideo[player_id].compulsoryQuestions) { il.InteractiveVideo[player_id].compulsoryQuestions[question_id].answered = true; } @@ -269,7 +265,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { pro.showQuestionInteractionForm = function(comment_id, array, player) { pub.comment_id = comment_id; pub.QuestionObject = array; - pub.QuestionObject.player = player + pub.QuestionObject.player = player; //Todo: fix this, fullscreen isn't working pro.buildQuestionForm(player); if (pub.QuestionObject.player.isFullScreen === true) { From a9ec3fba037830715eb492f79497508290bd3d45 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 15:11:29 +0100 Subject: [PATCH 008/161] Removed possibility to close modal --- js/InteractiveVideoPlayerFunctions.js | 2 +- js/jquery.InteractiveVideoQuestionViewer.js | 34 ++++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/js/InteractiveVideoPlayerFunctions.js b/js/InteractiveVideoPlayerFunctions.js index 3edad803d..50a0184eb 100644 --- a/js/InteractiveVideoPlayerFunctions.js +++ b/js/InteractiveVideoPlayerFunctions.js @@ -86,7 +86,7 @@ il.InteractiveVideoPlayerFunction = (function (scope) { if(object.answered == false){ if(current_time >= object.time) { il.InteractiveVideoPlayerAbstract.pause(player_id); - //il.InteractiveVideoPlayerAbstract.setCurrentTime(parseInt(object.time, 10) + 0.1, player_id); + il.InteractiveVideoPlayerAbstract.setCurrentTime(parseInt(object.time, 10) + 0.1, player_id); InteractiveVideoQuestionViewer.getQuestionPerAjax(object.comment_id, player_id); return false; } diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index 15d7bd857..a43f00ddc 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -3,7 +3,8 @@ var InteractiveVideoQuestionViewer = (function (scope) { let pub = {}, pro = {}, pri = { - locked : false + locked : false, + id_modal : '#ilQuestionModal' }; pub.QuestionObject = {}; @@ -24,11 +25,23 @@ var InteractiveVideoQuestionViewer = (function (scope) { } }; + pub.toggleCloseButtons = function(show) { + if (show) { + $(pri.id_modal + ' #close_form').hide(); + $(pri.id_modal + ' .close').hide(); + } else { + $(pri.id_modal + ' #close_form').show(); + $(pri.id_modal + ' .close').show(); + } + }; + pro.addCompulsoryHeader = function(header){ - $('#ilQuestionModal .modal-header').removeClass('compulsory'); + pub.toggleCloseButtons(false); + $(pri.id_modal + ' .modal-header').removeClass('compulsory'); if(pub.QuestionObject.compulsory_question === "1") { + pub.toggleCloseButtons(true); header = '' + il.InteractiveVideo["lang"].compulsory + ''; - $('#ilQuestionModal .modal-header').addClass('compulsory'); + $(pri.id_modal + ' .modal-header').addClass('compulsory'); } return header; }; @@ -41,10 +54,6 @@ var InteractiveVideoQuestionViewer = (function (scope) { modal.html(''); - header = pro.addCompulsoryHeader(header); - - $('.modal-title').html(pub.QuestionObject.question_title + ' ' + header); - if(pub.QuestionObject.question_image) { img = '
'; @@ -62,6 +71,8 @@ var InteractiveVideoQuestionViewer = (function (scope) { } else if (type === 2) { pro.addSelfReflectionLayout(player); } + header = pro.addCompulsoryHeader(header); + $('.modal-title').html(pub.QuestionObject.question_title + ' ' + header); pro.showPreviousAnswer(player); }; @@ -182,7 +193,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { if (parseInt(feedback.is_timed, 10) === 1) { modal.append('

' + language.learning_recommendation_text + ': ' + pro.createButtonButtons('jumpToTimeInVideo', language.feedback_button_text + ' ' + mejs.Utility.secondsToTimeCode(feedback.time)) + '
', ''); $('#jumpToTimeInVideo').on('click', function () { - $('#ilQuestionModal').modal('hide'); + $(pri.id_modal).modal('hide'); var player_id = scope.InteractiveVideoPlayerFunction.getPlayerIdFromPlayerObject(player); scope.InteractiveVideoPlayerAbstract.jumpToTimeInVideo(feedback.time, player_id); }); @@ -234,6 +245,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { } pro.showFeedback(obj, player); pro.addToLocalIgnoreArrayIfNonRepeatable(player_id); + pub.toggleCloseButtons(false); } }); }); @@ -243,11 +255,11 @@ var InteractiveVideoQuestionViewer = (function (scope) { pro.appendCloseButtonListener = function(player_id) { let close_form = $('#close_form'); - let question_modal = $('#ilQuestionModal'); + let question_modal = $(pri.id_modal); close_form.off('click'); close_form.on('click', function () { - $('#ilQuestionModal').modal('hide'); + question_modal.modal('hide'); pri.locked = false; }); @@ -278,7 +290,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { ) { config = {backdrop: 'static', keyboard: false}; } - $('#ilQuestionModal').modal(config, 'show'); + $(pri.id_modal).modal(config, 'show'); }; pub.protect = pro; From d4fb2fdc8bae9c6d66fe732f34254b512200dafd Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Mon, 16 Mar 2020 15:23:46 +0100 Subject: [PATCH 009/161] Refactoring --- js/jquery.InteractiveVideoQuestionViewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index a43f00ddc..cfe63bfe0 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -239,7 +239,7 @@ var InteractiveVideoQuestionViewer = (function (scope) { data: $(this).serialize(), success: function (feedback) { let obj = JSON.parse(feedback); - let question_id = InteractiveVideoQuestionViewer.QuestionObject.question_id; + let question_id = pub.QuestionObject.question_id; if(question_id in il.InteractiveVideo[player_id].compulsoryQuestions) { il.InteractiveVideo[player_id].compulsoryQuestions[question_id].answered = true; } From 47fe2661db3e36086628d5ab483c69fe8a374324 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Tue, 17 Mar 2020 08:12:27 +0100 Subject: [PATCH 010/161] Show close button if feedback exists --- js/jquery.InteractiveVideoQuestionViewer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/jquery.InteractiveVideoQuestionViewer.js b/js/jquery.InteractiveVideoQuestionViewer.js index cfe63bfe0..168e60e74 100644 --- a/js/jquery.InteractiveVideoQuestionViewer.js +++ b/js/jquery.InteractiveVideoQuestionViewer.js @@ -39,7 +39,9 @@ var InteractiveVideoQuestionViewer = (function (scope) { pub.toggleCloseButtons(false); $(pri.id_modal + ' .modal-header').removeClass('compulsory'); if(pub.QuestionObject.compulsory_question === "1") { - pub.toggleCloseButtons(true); + if(! pub.QuestionObject.feedback) { + pub.toggleCloseButtons(true); + } header = '' + il.InteractiveVideo["lang"].compulsory + ''; $(pri.id_modal + ' .modal-header').addClass('compulsory'); } From 9afa588889d42e077ec853039ea9b9e957791f0d Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Tue, 17 Mar 2020 08:58:31 +0100 Subject: [PATCH 011/161] Fxied typo --- lang/ilias_de.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 541b5af2e..b6664561d 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -197,5 +197,5 @@ sure_delete_subtitle#:#Sind Sie sicher das sie diesen Untertitle löschen wollen you_need_a_short_title#:#Sie müssen einen Kurztitle eintragen! no_toolbar#:#Toolbar deaktivieren no_toolbar_info#:#Es wird keine Toolbar mit Filtern angezeigt -compulsory_question#:#Verpfilchtende Frage +compulsory_question#:#Verpflichtende Frage compulsory_question_info#:#Diese Frage muss beantwortet werden, bevor das Video weiter geschaut werden kann From 8dc9ac6d7aa99801f4386e5ce6f0a13ff0729105 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Tue, 17 Mar 2020 09:23:30 +0100 Subject: [PATCH 012/161] Add compulsory column to comments table --- classes/class.ilInteractiveVideoCommentsTableGUI.php | 6 ++++++ classes/class.ilObjInteractiveVideo.php | 6 +++++- lang/ilias_de.lang | 1 + lang/ilias_en.lang | 1 + templates/default/tpl.row_comments.html | 3 ++- 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/classes/class.ilInteractiveVideoCommentsTableGUI.php b/classes/class.ilInteractiveVideoCommentsTableGUI.php index 3a0c8a432..194933fc4 100644 --- a/classes/class.ilInteractiveVideoCommentsTableGUI.php +++ b/classes/class.ilInteractiveVideoCommentsTableGUI.php @@ -73,6 +73,7 @@ public function __construct($a_parent_obj, $a_parent_cmd) { $this->addColumn($a_parent_obj->plugin->txt('visibility'), 'is_private'); } + $this->addColumn($a_parent_obj->plugin->txt('compulsory'), 'compulsory', '10%'); $this->addColumn($this->lng->txt('actions'), '', '10%'); $this->setSelectAllCheckbox('comment_id'); @@ -135,6 +136,11 @@ protected function fillRow($a_set) $txt_value = $value == 1 ? 'question' : 'comment'; $value = $this->lng->txt($txt_value); } + else if($key == 'compulsory') + { + $txt_value = $value == 1 ? 'yes' : 'no'; + $value = $this->lng->txt($txt_value); + } else if($key == 'is_tutor') { continue; diff --git a/classes/class.ilObjInteractiveVideo.php b/classes/class.ilObjInteractiveVideo.php index a6ba008cc..5fdc8befc 100644 --- a/classes/class.ilObjInteractiveVideo.php +++ b/classes/class.ilObjInteractiveVideo.php @@ -490,9 +490,11 @@ public function getCommentsTableData($replace_with_text = false, $empty_string_i global $ilDB; $res = $ilDB->queryF(' - SELECT * FROM ' . self::TABLE_NAME_COMMENTS . ' + SELECT * FROM ' . self::TABLE_NAME_COMMENTS . ' comments, + ' . self::TABLE_NAME_QUESTIONS . ' questions WHERE obj_id = %s AND is_private = %s + AND comments.comment_id = questions.comment_id ORDER BY comment_time ASC', array('integer', 'integer'), array($this->getId(),0)); @@ -522,11 +524,13 @@ public function getCommentsTableData($replace_with_text = false, $empty_string_i { $table_data[$counter]['is_tutor'] = xvidUtils::yesNoString($row['is_tutor']); $table_data[$counter]['is_interactive'] = xvidUtils::yesNoString($row['is_interactive']); + $table_data[$counter]['compulsory']= xvidUtils::yesNoString($row['compulsory_question']); } else { $table_data[$counter]['is_tutor'] = $row['is_tutor']; $table_data[$counter]['is_interactive'] = $row['is_interactive']; + $table_data[$counter]['compulsory']= $row['compulsory_question']; } $counter++; diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index b6664561d..6ca43fd0a 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -198,4 +198,5 @@ you_need_a_short_title#:#Sie müssen einen Kurztitle eintragen! no_toolbar#:#Toolbar deaktivieren no_toolbar_info#:#Es wird keine Toolbar mit Filtern angezeigt compulsory_question#:#Verpflichtende Frage +compulsory#:#Verpflichtende compulsory_question_info#:#Diese Frage muss beantwortet werden, bevor das Video weiter geschaut werden kann diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 2fca54f8c..aa221dd5a 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -198,4 +198,5 @@ you_need_a_short_title#:#You need to provide a short title! no_toolbar#:#Deactivate toolbar no_toolbar_info#:#No toolbar with filters will be shown compulsory_question#:#Compulsory question +compulsory#:#Compulsory compulsory_question_info#:#This question must be answered \ No newline at end of file diff --git a/templates/default/tpl.row_comments.html b/templates/default/tpl.row_comments.html index 0ce15c3dd..cb54c3a78 100644 --- a/templates/default/tpl.row_comments.html +++ b/templates/default/tpl.row_comments.html @@ -5,7 +5,8 @@ {VAL_USER_ID} {VAL_TITLE} {VAL_COMMENT_TEXT} - {VAL_IS_INTERACTIVE} + {VAL_IS_INTERACTIVE} + {VAL_COMPULSORY} {VAL_IS_TUTOR} {VAL_IS_PRIVATE} {VAL_ACTIONS} From 051626897a1301e3ab45705a1b54697317226712 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Fri, 17 Jan 2020 11:17:12 +0100 Subject: [PATCH 013/161] implemented auto scroll for view all comments --- js/InteractiveVideoPlayerComments.js | 2 +- js/InteractiveVideoPlayerFunctions.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/js/InteractiveVideoPlayerComments.js b/js/InteractiveVideoPlayerComments.js index 3efdd402e..9c2482d2b 100644 --- a/js/InteractiveVideoPlayerComments.js +++ b/js/InteractiveVideoPlayerComments.js @@ -286,7 +286,7 @@ il.InteractiveVideoPlayerComments = (function (scope) { { time = Math.abs(Math.round(time) - 0.1); } - return '