From 60334ca04ac1fe06c0e6927096ca72699bdade4b Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 30 May 2025 13:00:00 +0530 Subject: [PATCH 1/5] feat: show quiz in between videos --- frontend/components.d.ts | 1 + .../src/components/Modals/QuizInVideo.vue | 167 +++++++++++++++++ frontend/src/components/VideoBlock.vue | 169 ++++++++++-------- frontend/src/utils/index.js | 11 +- frontend/src/utils/upload.js | 7 + lms/patches/v2_0/move_zoom_settings.py | 4 + 6 files changed, 284 insertions(+), 75 deletions(-) create mode 100644 frontend/src/components/Modals/QuizInVideo.vue diff --git a/frontend/components.d.ts b/frontend/components.d.ts index c2c899fa..2212eb18 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -81,6 +81,7 @@ declare module 'vue' { Question: typeof import('./src/components/Modals/Question.vue')['default'] Quiz: typeof import('./src/components/Quiz.vue')['default'] QuizBlock: typeof import('./src/components/QuizBlock.vue')['default'] + QuizInVideo: typeof import('./src/components/Modals/QuizInVideo.vue')['default'] Rating: typeof import('./src/components/Controls/Rating.vue')['default'] ReviewModal: typeof import('./src/components/Modals/ReviewModal.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/frontend/src/components/Modals/QuizInVideo.vue b/frontend/src/components/Modals/QuizInVideo.vue new file mode 100644 index 00000000..889a3c39 --- /dev/null +++ b/frontend/src/components/Modals/QuizInVideo.vue @@ -0,0 +1,167 @@ + + diff --git a/frontend/src/components/VideoBlock.vue b/frontend/src/components/VideoBlock.vue index f5b3ac45..7e75e16b 100644 --- a/frontend/src/components/VideoBlock.vue +++ b/frontend/src/components/VideoBlock.vue @@ -1,80 +1,103 @@ diff --git a/frontend/src/components/DiscussionReplies.vue b/frontend/src/components/DiscussionReplies.vue index 9e328587..10ae9a08 100644 --- a/frontend/src/components/DiscussionReplies.vue +++ b/frontend/src/components/DiscussionReplies.vue @@ -97,7 +97,7 @@ import { createResource, TextEditor, Button, Dropdown, toast } from 'frappe-ui' import { timeAgo } from '../utils' import UserAvatar from '@/components/UserAvatar.vue' import { ChevronLeft, MoreHorizontal } from 'lucide-vue-next' -import { ref, inject, onMounted } from 'vue' +import { ref, inject, onMounted, onUnmounted } from 'vue' const showTopics = defineModel('showTopics') const newReply = ref('') @@ -251,4 +251,10 @@ const deleteReply = (reply) => { } ) } + +onUnmounted(() => { + socket.off('publish_message') + socket.off('update_message') + socket.off('delete_message') +}) diff --git a/frontend/src/components/Discussions.vue b/frontend/src/components/Discussions.vue index 95e47efd..04747bba 100644 --- a/frontend/src/components/Discussions.vue +++ b/frontend/src/components/Discussions.vue @@ -70,7 +70,7 @@ import { createResource, Button } from 'frappe-ui' import UserAvatar from '@/components/UserAvatar.vue' import { singularize, timeAgo } from '../utils' -import { ref, onMounted, inject } from 'vue' +import { ref, onMounted, inject, onUnmounted } from 'vue' import DiscussionReplies from '@/components/DiscussionReplies.vue' import DiscussionModal from '@/components/Modals/DiscussionModal.vue' import { MessageSquareText } from 'lucide-vue-next' @@ -153,4 +153,8 @@ const showReplies = (topic) => { const openTopicModal = () => { showTopicModal.value = true } + +onUnmounted(() => { + socket.off('new_discussion_topic') +}) diff --git a/frontend/src/components/Modals/QuizInVideo.vue b/frontend/src/components/Modals/QuizInVideo.vue index 3d12ea15..18575fa3 100644 --- a/frontend/src/components/Modals/QuizInVideo.vue +++ b/frontend/src/components/Modals/QuizInVideo.vue @@ -10,10 +10,10 @@
{{ quiz.data.title }}
- + +
+
- - {{ __('Start') }} - - -
{{ __( 'You have already exceeded the maximum number of attempts allowed for this quiz.' @@ -263,7 +274,7 @@ {{ __('Try Again') }} -
@@ -316,7 +327,6 @@ let questions = reactive([]) const possibleAnswer = ref(null) const timer = ref(0) let timerInterval = null -const router = useRouter() const props = defineProps({ quizName: { @@ -327,7 +337,7 @@ const props = defineProps({ type: Boolean, default: false, }, - onSubmit: { + backToVideo: { type: Function, default: () => {}, }, @@ -627,11 +637,15 @@ const getInstructions = (question) => { } const markLessonProgress = () => { - if (router.currentRoute.value.name == 'Lesson') { + let pathname = window.location.pathname.split('/') + if (pathname[2] != 'courses') return + let lessonIndex = pathname.pop().split('-') + + if (lessonIndex.length == 2) { call('lms.lms.api.mark_lesson_progress', { - course: router.currentRoute.value.params.courseName, - chapter_number: router.currentRoute.value.params.chapterNumber, - lesson_number: router.currentRoute.value.params.lessonNumber, + course: pathname[3], + chapter_number: lessonIndex[0], + lesson_number: lessonIndex[1], }) } } diff --git a/frontend/src/components/VideoBlock.vue b/frontend/src/components/VideoBlock.vue index 692195af..e5c06a76 100644 --- a/frontend/src/components/VideoBlock.vue +++ b/frontend/src/components/VideoBlock.vue @@ -1,11 +1,11 @@