Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: leaderboard JS fixes #457

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 80 additions & 79 deletions lms/static/js/dashboard/leaderboard.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,86 @@
// Function to fetch data from the API
async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
return data; // Assuming the API response is in JSON format
} catch (error) {
console.error('Error fetching data:', error);
}
}

// Function to render a single user item
function renderUserListItem(data) {
const listItem = document.createElement('li');
listItem.className = 'user-item';

const avatarDiv = document.createElement('div');
avatarDiv.className = 'avatar';
const avatarImg = document.createElement('img');
avatarImg.src = data.user.profile_image_url;
avatarImg.alt = 'User Avatar';
avatarDiv.appendChild(avatarImg);

const userInfoDiv = document.createElement('div');
userInfoDiv.className = 'user-info';
const userNameDiv = document.createElement('div');
userNameDiv.className = 'user-name';
userNameDiv.textContent = data.user.name;
userInfoDiv.appendChild(userNameDiv);

const userScoreDiv = document.createElement('div');
userScoreDiv.className = 'user-score';
userScoreDiv.textContent = data.score;

listItem.appendChild(avatarDiv);
listItem.appendChild(userInfoDiv);
listItem.appendChild(userScoreDiv);

return listItem;
}

// Function to render user list
async function renderUserList() {
const userListElement = document.getElementById('userList');
let nextPageUrl = '/api/badges/v1/leaderboard/';

// Variable to track if data is currently being fetched to avoid multiple simultaneous requests
let fetchingData = false;

async function fetchAndRenderNextPage() {
fetchingData = true;

// Fetch the next set of data
if (nextPageUrl){
const nextPageData = await fetchData(nextPageUrl);

if (nextPageData.results && Array.isArray(nextPageData.results)) {
nextPageData.results.forEach(user => {
// Create and append list items for the next set of data
const listItem = renderUserListItem(user);
userListElement.appendChild(listItem);
var edx = edx || {};

(function ($) {
'use strict';

edx.dashboard = edx.dashboard || {};
edx.dashboard.leaderboard = {};

edx.dashboard.leaderboard.fetchData = function (url) {
return new Promise(function (resolve, reject) {
fetch(url)
.then(function (response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function (data) {
resolve(data);
})
.catch(function (error) {
reject(error);
});
});
};

edx.dashboard.leaderboard.renderUserListItem = function (data) {
var listItem = $('<li>').addClass('user-item');

var avatarDiv = $('<div>').addClass('avatar');
var avatarImg = $('<img>').attr('src', data.user.profile_image_url).attr('alt', 'User Avatar');
avatarDiv.append(avatarImg);

var userInfoDiv = $('<div>').addClass('user-info');
var userNameDiv = $('<div>').addClass('user-name').text(data.user.name);
userInfoDiv.append(userNameDiv);

var userScoreDiv = $('<div>').addClass('user-score').text(data.score);

listItem.append(avatarDiv, userInfoDiv, userScoreDiv);

return listItem;
};

edx.dashboard.leaderboard.renderUserList = function () {
var userListElement = $('#userList');
var nextPageUrl = '/api/badges/v1/leaderboard/';
var fetchingData = false;

var fetchAndRenderNextPage = function () {
if (nextPageUrl && !fetchingData) {
fetchingData = true;
edx.dashboard.leaderboard.fetchData(nextPageUrl)
.then(function (nextPageData) {
if (nextPageData.results && Array.isArray(nextPageData.results)) {
nextPageData.results.forEach(function (user) {
var listItem = edx.dashboard.leaderboard.renderUserListItem(user);
userListElement.append(listItem);
});

nextPageUrl = nextPageData.next;
}
})
.catch(function (error) {
console.error('Error fetching and rendering data:', error);
})
.finally(function () {
fetchingData = false;
});
}
};

// Update the next page URL
nextPageUrl = nextPageData.next;
userListElement.scroll(function() {
if ($(this).scrollTop() + $(this).innerHeight() >= this.scrollHeight - 1000 && !fetchingData) {
fetchAndRenderNextPage();
}
});

fetchAndRenderNextPage();
};

fetchingData = false;
}
edx.dashboard.leaderboard.init = function() {
edx.dashboard.leaderboard.renderUserList();
}

// Initial rendering
await fetchAndRenderNextPage();

// Add event listener to window scroll
window.addEventListener('scroll', async () => {
// Check if user has scrolled to the bottom
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 1000 && !fetchingData) {
await fetchAndRenderNextPage();
}
});
}

// Call the function to render the initial user list when the page loads
document.addEventListener('DOMContentLoaded', renderUserList);
}(jQuery));
3 changes: 1 addition & 2 deletions lms/templates/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<%static:js group='dashboard'/>
<script type="text/javascript">
$(document).ready(function() {
edx.dashboard.leaderboard.init();
edx.dashboard.legacy.init({
dashboard: "${reverse('dashboard') | n, js_escaped_string}",
signInUser: "${reverse('signin_user') | n, js_escaped_string}",
Expand Down Expand Up @@ -420,6 +421,4 @@ <h2 id="unenrollment-modal-title">
</div>
</div>

<script src="lms/static/js/dashboard/leaderboard.js"></script>

<%include file="dashboard/_dashboard_entitlement_unenrollment_modal.html"/>
Loading