diff --git a/block_iagora.php b/block_iagora.php index b983c5a..b54f9b7 100644 --- a/block_iagora.php +++ b/block_iagora.php @@ -59,18 +59,20 @@ public function get_content() { return $this->content; } + /** - * Retrieves the progress of a student in the current course. + * Retrieve the progress of a student in the current course. * * This function returns an array containing the names of activities the student has completed * based on their activity completion status within the course. * - * @return array An array of completed activities. + * @return array An array of completed and uncompleted activities. */ private function get_student_progress() { global $COURSE, $USER; $completedactivities = []; + $uncompletedactivities = []; $completion = new completion_info($COURSE); $modinfo = get_fast_modinfo($COURSE, $USER->id); $cms = $modinfo->get_cms(); @@ -86,11 +88,15 @@ private function get_student_progress() { if ($completiondata->completionstate == COMPLETION_COMPLETE || $completiondata->completionstate == COMPLETION_COMPLETE_PASS) { $completedactivities[] = $cm->name; + } else { + $uncompletedactivities[] = $cm->name; } } - // Return the array of completed activities. - return $completedactivities; + return [ + 'completedActivities' => $completedactivities, + 'uncompletedActivities' => $uncompletedactivities, + ]; } /** @@ -100,17 +106,75 @@ private function get_student_progress() { * @return string The generated HTML content for the chat. */ private function generate_chat_content($copilotendpointurl) { - global $OUTPUT, $USER, $COURSE; + global $OUTPUT, $USER; + + $username = $USER->firstname . ' ' . $USER->lastname; + $useravatarinitials = $this->get_user_initials($username); + // Get the user's profile picture URL. + $useravatarimage = $this->get_profile_picture_url($USER); + // If there is no profile picture, use the initials. + if (!empty($useravatarimage)) { + $useravatarinitials = ''; // Clear initials if image exists. + } // Generate a unique identifier for the chat container. $chatid = uniqid('iagora_chat_'); + $studentprogress = $this->get_student_progress(); $context = [ 'chatId' => $chatid, 'tokenEndpointURL' => $copilotendpointurl, - 'completedactivities' => json_encode($this->get_student_progress()), + 'completedActivities' => json_encode($this->get_student_progress()), + 'uncompletedActivities' => json_encode($this->get_student_progress()), + 'userAvatarImage' => $useravatarimage, + 'userAvatarInitials' => $useravatarinitials , ]; return $OUTPUT->render_from_template('block_iagora/chat', $context); } + /** + * Get the initials of a username. + * + * @param string $username The full name of the user. + * @return string The initials of the user. + */ + private function get_user_initials($username) { + $initials = ''; + foreach (explode(' ', $username) as $name) { + $initials .= strtoupper($name[0]); + } + return $initials; + } + + /** + * Retrieve the profile picture URL of the user. + * + * @param stdClass $user The user object. + * @return string The URL of the user's profile picture, or an empty string if not available. + */ + private function get_profile_picture_url($user) { + global $OUTPUT; + + // Check if the user is logged in, not a guest, and has a profile picture. + if (isloggedin() && !isguestuser() && $user->picture > 0) { + // Get the user context. + $usercontext = context_user::instance($user->id, IGNORE_MISSING); + + // Generate the URL for the profile picture. + $url = moodle_url::make_pluginfile_url( + $usercontext->id, // Context ID. + 'user', // Component name (user). + 'icon', // File area (icon). + null, // Item ID (not needed here). + '/', // File path (root). + "f$1" // File name. + ) . '?rev=' . $user->picture; // Add a revision parameter to avoid caching issues. + + return $url; + } + + // Return empty string if no profile picture. + return ''; + } + /** * Define in which pages this block can be added. * diff --git a/templates/chat.mustache b/templates/chat.mustache index 7d37786..a59361d 100644 --- a/templates/chat.mustache +++ b/templates/chat.mustache @@ -28,11 +28,19 @@ Context variables required for this template: * chatId: The ID of the chat div element where to render the chat block. * tokenEndpointURL: The Copilot Token Endpoint URL for native apps. + * completedActivities: A JSON string containing the list of activities the user has already completed. + * uncompletedActivities: A JSON string containing the list of activities the user has not yet completed. + * userAvatarImage: The URL to the user's profile image, or an empty string if not available. + * userAvatarInitials: The initials of the user's name, used as an avatar if no image is available. Example context (json): { "chatId": "iagora_chat_55a6cad25a0f6", - "tokenEndpointURL": "https://insert/your/copilot/endpoint/url" + "tokenEndpointURL": "https://insert/your/copilot/endpoint/url", + "completedActivities": ["INTRODUCTION PARTIE 1", "QUIZ 1"], + "uncompletedActivities": ["QUIZ 2", "CONCLUSION PARTIE 1"], + "userAvatarImage": "https://example.com/path/to/avatar.jpg", + "userAvatarInitials": "AN" } }} {{#pix}} t/message, core {{/pix}} @@ -44,15 +52,19 @@ /* global WebChat */ /* eslint-disable promise/no-native */ (async function() { + // Function to decode HTML entities + function decodeHtml(html) { + var txt = document.createElement("textarea"); + txt.innerHTML = html; + return txt.value; + } const styleOptions = { hideUploadButton: true, - botAvatarImage: "/image/iagora.jpg", - botAvatarInitials: 'BF', - userAvatarImage: 'https://github.com/compulim.png?size=64', - userAvatarInitials: 'WC' + userAvatarImage: '{{userAvatarImage}}', + userAvatarInitials: '{{userAvatarInitials}}', }; const styleSet = window.WebChat.createStyleSet({ - bubbleBackground: 'rgba(0, 0, 255, .1)', + bubbleBackground: 'rgba(18, 124, 162, .1)', bubbleFromUserBackground: 'rgba(0, 255, 0, .1)' }); @@ -82,7 +94,8 @@ }) .then(({token}) => token) ]); - const completedactivities = []; + const completedActivities = JSON.parse(decodeHtml(`{{{completedActivities}}}`)); + const uncompletedActivities = JSON.parse(decodeHtml(`{{{uncompletedActivities}}}`)); const directLine = WebChat.createDirectLine({domain: new URL('v3/directline', directLineURL), token}); const subscription = directLine.connectionStatus$.subscribe({ @@ -95,7 +108,8 @@ name: 'startConversation', type: 'event', value: { - completedactivities: completedactivities + completedActivities: completedActivities, + uncompletedActivities: uncompletedActivities } }) .subscribe();