Conversation
- Introduced a new question type 'draw_image' in the curriculum components. - Updated Question, QuestionConditions, QuestionForm, and QuestionList to support the new question type. - Implemented DrawImage component for handling drawing on images. - Enhanced Quiz class to process answers for draw_image questions. - Added necessary translations and icons for the new question type.
- Added support for 'draw_image' question type in the quiz, allowing users to draw on images. - Updated JavaScript logic to handle answer validation and reveal mode for draw_image questions. - Enhanced PHP classes to save and process the drawn image mask. - Improved UI to display student submissions and instructor references for draw_image questions. - Added necessary translations and updated quiz attempt details to reflect new functionality.
- Removed "(R&D)" from the label of the 'draw_image' question type in both QuestionConditions and QuestionList components for clarity and consistency. - Ensured translations are updated accordingly in the 'tutor' text domain.
- Streamlined the logic for handling student-submitted masks in the 'draw_image' question type. - Removed redundant code and ensured that the answer is processed correctly from the nested structure. - Improved code readability and maintainability by consolidating answer extraction logic.
- Updated comments for clarity on handling raw base64 or URL inputs in the 'draw_image' question type. - Ensured that the URL returned from saving the drawn image mask is properly sanitized using esc_url_raw. - Enhanced code readability by clarifying the sanitization process for different input types.
- Improved handling of base64 and URL inputs for the 'draw_image' question type. - Added security checks to ensure only local uploads are accepted, rejecting external URLs. - Clarified comments and improved code readability regarding image saving and processing. - Ensured that the saved image is always stored with a .png extension for consistency.
… type - Updated comments to specify that masks are stored as local file URLs only. - Improved condition checks to ensure only valid local URLs are processed for student and instructor submitted drawings. - Enhanced code readability by removing redundant checks and ensuring consistent use of esc_url for outputting image URLs.
- Refactored the draw image mask functionality by moving the saving logic from Utils to QuizModel for better organization. - Updated references in Quiz and QuizBuilder classes to utilize the new QuizModel method. - Improved code clarity by enhancing comments and ensuring consistent handling of base64 and URL inputs. - Removed deprecated save_quiz_draw_image_mask method from Utils to streamline the codebase.
- Updated the URL validation logic for student and instructor submitted drawing masks to use wp_http_validate_url for enhanced security. - Ensured consistent handling of URLs across the quiz attempt details view. - Improved code clarity by maintaining a uniform approach to URL checks.
- Updated the upload_base64_image method to include an optional parameter for adding the uploaded file to the WordPress media library. - Improved documentation to clarify the behavior of the method when the new parameter is set to false, ensuring it returns an ID of 0. - Streamlined the image upload process in QuizModel by utilizing the updated method for handling base64 images.
- Added a new filter for processing draw image answers in the Quiz class to allow for custom handling. - Introduced a method in QuizModel to retrieve the full image URL for quiz answers, improving code reusability and clarity. - Updated the quiz attempt details view to utilize the new method for fetching image URLs, streamlining the code and enhancing maintainability.
- Enhanced the deletion process for draw image files by collecting file paths before removing quiz attempts and questions, ensuring no orphaned files remain. - Introduced methods in QuizModel to retrieve and delete draw image file paths associated with quiz attempts and questions, improving code organization and maintainability. - Updated the DrawImage component to integrate with the shared draw-on-image API, enhancing the drawing functionality for instructors.
- Simplified the process of resolving draw image URLs to absolute file paths by introducing a dedicated method, improving code organization and readability. - Enhanced the handling of quiz attempt IDs to ensure only valid IDs are processed, reducing potential errors. - Updated the logic to utilize a single query for fetching relevant data, streamlining the retrieval of draw image answers and improving performance.
- Introduced a new filter to collect file paths for deletion from all question types that store files, improving the flexibility of the deletion process. - Updated comments for clarity, specifying that file paths are collected from various question types, not just draw_image. - Refactored methods in QuizModel to streamline the retrieval of file paths for deletion, enhancing code organization and maintainability.
- Refactored the DrawImage component to simplify its structure and improve integration with the shared draw-on-image API. - Introduced a new FormDrawImage component to encapsulate the drawing functionality, enhancing code organization and reusability. - Updated state management and effect hooks for better performance and clarity in handling drawing interactions. - Removed deprecated code and unnecessary complexity, focusing on a cleaner implementation for image drawing in quizzes.
…rawImage component - Added type definitions for the TutorDrawOnImage API to enhance type safety and integration with the drawing functionality. - Removed deprecated interface definitions from FormDrawImage component, streamlining the code and improving clarity. - Updated the FormDrawImage component to better utilize the shared draw-on-image API, enhancing overall code organization and maintainability.
… and drawing state - Added logic to clear previous drawings when an image is replaced, ensuring the new image displays correctly without old masks. - Implemented cleanup for the drawing instance and canvas to improve user experience during image updates. - Updated comments for better clarity on the functionality related to image handling in the quiz question component.
|
|
||
| const getDefaultOption = (questionId: ID): QuizQuestionOption => ({ | ||
| _data_status: QuizDataStatus.NEW, | ||
| is_saved: true, |
There was a problem hiding this comment.
is_saved should not be true by default. It must be programmatically toggled to true when the user saves the question.
|
|
||
| const INSTRUCTOR_STROKE_STYLE = 'rgba(255, 0, 0, 0.9)'; | ||
|
|
||
| interface FormDrawImageProps extends FormControllerProps<QuizQuestionOption | undefined> { |
There was a problem hiding this comment.
No need to pass undefined as generic.
| interface FormDrawImageProps extends FormControllerProps<QuizQuestionOption | undefined> { | |
| interface FormDrawImageProps extends FormControllerProps<QuizQuestionOption> { |
| useEffect(() => { | ||
| if (isDrawModeActive) { | ||
| return; | ||
| } | ||
| syncCanvasDisplay(option?.answer_two_gap_match || undefined); | ||
| }, [isDrawModeActive, option?.image_url, option?.answer_two_gap_match, syncCanvasDisplay]); | ||
|
|
||
| useEffect(() => { | ||
| if (isDrawModeActive) { | ||
| return; | ||
| } | ||
| const img = imageRef.current; | ||
| if (!img) { | ||
| return; | ||
| } | ||
| const handleLoad = () => { | ||
| syncCanvasDisplay(option?.answer_two_gap_match || undefined); | ||
| }; | ||
| img.addEventListener('load', handleLoad); | ||
| return () => { | ||
| img.removeEventListener('load', handleLoad); | ||
| }; | ||
| }, [isDrawModeActive, option?.answer_two_gap_match, syncCanvasDisplay]); | ||
|
|
||
| useEffect(() => { | ||
| if (isDrawModeActive) { | ||
| return; | ||
| } | ||
| const img = imageRef.current; | ||
| const canvas = canvasRef.current; | ||
| if (!img || !canvas) { | ||
| return; | ||
| } | ||
| const container = img.parentElement; | ||
| if (!container) { | ||
| return; | ||
| } | ||
| const resizeObserver = new ResizeObserver(() => { | ||
| syncCanvasDisplay(option?.answer_two_gap_match || undefined); | ||
| }); | ||
| resizeObserver.observe(container); | ||
| return () => { | ||
| resizeObserver.disconnect(); | ||
| }; | ||
| }, [isDrawModeActive, option?.image_url, option?.answer_two_gap_match, syncCanvasDisplay]); | ||
|
|
||
| // Wire to shared draw-on-image module when draw mode is active (Tutor Pro). | ||
| useEffect(() => { | ||
| if (!isDrawModeActive || !option?.image_url) { | ||
| return; | ||
| } | ||
| const img = imageRef.current; | ||
| const canvas = canvasRef.current; | ||
| const api = typeof window !== 'undefined' ? window.TutorDrawOnImage : undefined; | ||
| if (!img || !canvas || !api?.init) { | ||
| return; | ||
| } | ||
| if (drawInstanceRef.current) { | ||
| drawInstanceRef.current.destroy(); | ||
| drawInstanceRef.current = null; | ||
| } | ||
| const brushSize = api.DEFAULT_BRUSH_SIZE ?? 15; | ||
| const instance = api.init({ | ||
| image: img, | ||
| canvas, | ||
| brushSize, | ||
| strokeStyle: INSTRUCTOR_STROKE_STYLE, | ||
| initialMaskUrl: option.answer_two_gap_match || undefined, | ||
| }); | ||
| drawInstanceRef.current = instance; | ||
| return () => { | ||
| instance.destroy(); | ||
| drawInstanceRef.current = null; | ||
| }; | ||
| }, [isDrawModeActive, option?.image_url, option?.answer_two_gap_match]); |
There was a problem hiding this comment.
Why use multiple useEffect with the same dependency array?
| } | ||
|
|
||
| const rect = container.getBoundingClientRect(); | ||
| const w = Math.round(rect.width); |
There was a problem hiding this comment.
Please use readable names.
| } | ||
| const baseAnswer: QuizQuestionOption = { | ||
| _data_status: QuizDataStatus.NEW, | ||
| is_saved: true, |
There was a problem hiding this comment.
is_saved should not be true by default. It must be programmatically toggled to true when the user saves the question.
| $answer_two_gap_match = Input::sanitize( $input['answer_two_gap_match'] ?? '' ); | ||
| // Draw image: pass raw base64 or URL to QuizModel::save_quiz_draw_image_mask (Input::sanitize would corrupt base64 | ||
| // and sanitize_text_field can strip URL chars); it returns a URL—sanitize that with esc_url_raw. | ||
| if ( 'draw_image' === $question_type && isset( $input['answer_two_gap_match'] ) ) { |
There was a problem hiding this comment.
Instead of hard-coding, we can create & use constants.
| @@ -525,18 +525,38 @@ public function delete_course_data( $post_id ) { | |||
| * Delete Quiz data | |||
| */ | |||
| if ( get_post_type( $content_id ) === 'tutor_quiz' ) { | |||
There was a problem hiding this comment.
Instead of this 'tutor_quiz'
we can use this tutor()->quiz_post_type
No description provided.