Skip to content

Commit

Permalink
feat: load trip history gracefully (#53)
Browse files Browse the repository at this point in the history
* feat: load trip history gracefully

* fix: remove unnecessary request

* Added spinners, improved alert styling and improved isScrolledToBottom

* chore: remove var and move function

* fix: make scroll immediate

* fixed isScrolledToBottom function for firefox

---------

Co-authored-by: Afonso Hermenegildo <afonsosousah@hotmail.com>
  • Loading branch information
ImRodry and afonsosousah authored Nov 13, 2024
1 parent 16daaeb commit af413c9
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 48 deletions.
23 changes: 13 additions & 10 deletions assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
width: 100px;
height: 100px;
position: absolute;
top: calc(50% - 40px);
left: calc(50% - 40px);
top: calc(50% - 50px);
left: calc(50% - 50px);
object-fit: contain;
/*animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;*/
}
Expand Down Expand Up @@ -2101,6 +2101,7 @@ input[type=number] {
min-height: 10%;
border-radius: 20px;
background-color: #fff;
padding: 1rem;
}

#modalContainer > #alertBox {
Expand All @@ -2121,7 +2122,7 @@ input[type=number] {
}

#alertBox p {
padding: 0.5rem 1.5rem 1.5rem 1.5rem;
padding: 0.5rem;
margin: 0;
font-size: 0.9rem;
}
Expand All @@ -2144,7 +2145,6 @@ input[type=number] {
#alertBox #closeBtn {
display: block;
position: relative;
padding: 7px;
width: 20%;
text-transform: uppercase;
text-align: center;
Expand All @@ -2155,34 +2155,31 @@ input[type=number] {
margin-bottom: 10px;
margin-right: 10px;
padding: 10px 40px;
margin-top: 1rem;
}
#alertBox #yesBtn {
display: block;
position: relative;
padding: 7px;
width: 30%;
text-align: center;
color: #fff;
background-color: var(--green);
border-radius: 999px;
float: left;
margin-bottom: 10px;
margin-left: 10px;
padding: 10px 20px;
margin-top: 1rem;
}
#alertBox #noBtn {
display: block;
position: relative;
padding: 7px;
width: 30%;
text-align: center;
color: #fff;
background-color: var(--black);
border-radius: 999px;
float: right;
margin-bottom: 10px;
margin-right: 10px;
padding: 10px 20px;
margin-top: 1rem;
}
#alertBox ul {
padding-left: 20px;
Expand Down Expand Up @@ -2353,6 +2350,12 @@ input[type=number] {
width: 80%;
text-align: right;
}
#tripHistorySpinner {
display: inline-block;
width: 100px;
height: 100px;
object-fit: contain;
}
/* #endregion */

/* #region Statistics menu */
Expand Down
10 changes: 5 additions & 5 deletions scripts/dialogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ function createCustomYesNoPrompt(message, yesHandler, noHandler, yesText = "Sim"
alertObj.id = "alertBox";

const msg = alertObj.appendChild(document.createElement("p"));
msg.innerHTML = message;
msg.innerText = message;

const yesBtn = alertObj.appendChild(document.createElement("div"));
yesBtn.id = "yesBtn";
yesBtn.appendChild(document.createTextNode(yesText));
yesBtn.addEventListener("click", () => {
yesHandler();
yesBtn.addEventListener("click", async () => {
await yesHandler();
document.getElementById("modalContainer").remove();
});

const noBtn = alertObj.appendChild(document.createElement("div"));
noBtn.id = "noBtn";
noBtn.appendChild(document.createTextNode(noText));
noBtn.addEventListener("click", () => {
noHandler();
noBtn.addEventListener("click", async () => {
await noHandler();
document.getElementById("modalContainer").remove();
});

Expand Down
14 changes: 14 additions & 0 deletions scripts/extras.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ function appendElementToElementFromHTML(htmlString, parentElement) {
parentElement.appendChild(element);
}

function createElementFromHTML(htmlString) {
const div = document.createElement("div");
div.innerHTML = htmlString.trim();

// Change this to div.childNodes to support multiple top-level nodes.
return div.firstChild;
}

function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
Expand All @@ -52,6 +60,12 @@ function getCookie(cname) {
return "";
}

// Used to check whether a scrollable element has been scrolled to the very bottom
function isScrolledToBottom(element) {
const PIXELS_ERROR_MARGIN = 1;
return element.scrollHeight - element.scrollTop <= element.clientHeight + PIXELS_ERROR_MARGIN;
}

function parseMillisecondsIntoReadableTime(milliseconds) {
// Get days from milliseconds
let days = milliseconds / (24 * 1000 * 60 * 60);
Expand Down
92 changes: 59 additions & 33 deletions scripts/user.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const TRIP_HISTORY_PAGE_SIZE = 10;
let tokenRefreshed = false;
let minimumDistanceToStation = 50;

Expand Down Expand Up @@ -149,25 +150,22 @@ async function getUserInformation() {
user = { ...user, ...response.data.client[0] };
user.activeUserSubscriptions = response.data.activeUserSubscriptions;

// Get user's trip history asynchronously
getTripHistory();

return user;
}

// get tripHistory
async function getTripHistory() {
async function getTripHistory(pageNum = 1, pageSize = TRIP_HISTORY_PAGE_SIZE) {
response = await makePostRequest(
GIRA_GRAPHQL_ENDPOINT,
JSON.stringify({
operationName: "tripHistory",
variables: { in: { _pageNum: 1, _pageSize: 1000 } },
variables: { in: { _pageNum: pageNum, _pageSize: pageSize } },
query:
"query tripHistory($in: PageInput) { tripHistory(pageInput: $in) { bikeName bikeType bonus code cost endDate endLocation rating startDate startLocation usedPoints }}",
}),
user.accessToken
);
user.tripHistory = response.data.tripHistory;
return response.data.tripHistory;
}

// Open the login menu element and populate it
Expand Down Expand Up @@ -425,18 +423,16 @@ async function openTripHistory() {
// Set status bar color in PWA
changeThemeColor("#ffffff");

if (!user.tripHistory) {
// show loading animation
menu.innerHTML = `
// show loading animation
menu.innerHTML = `
<img src="assets/images/mGira_spinning.gif" id="spinner">
<div id="backButton" onclick="hideTripHistory();"><i class="bi bi-arrow-90deg-left"></i></div>
`;

// Get user's trip history
await getTripHistory();
// Get user's trip history
const tripHistory = await getTripHistory();

if (document.querySelectorAll("#tripHistory").length === 0) hideTripHistory();
}
if (document.querySelectorAll("#tripHistory").length === 0) hideTripHistory();

// Create element
menu.innerHTML = `
Expand All @@ -446,13 +442,49 @@ async function openTripHistory() {
<ul id="tripList">
<!-- Populate with the list here -->
</ul>
<div id="downloadTripHistoryButton" onclick="downloadObjectAsJson(user.tripHistory, 'tripHistory');">
<div id="downloadTripHistoryButton" onclick="downloadTripHistory();">
<i class="bi bi-cloud-download"></i>
</div>
`.trim();

// populate the trip list
for (let trip of user.tripHistory) {
addTripsToDOM(tripHistory);

const tripList = document.getElementById("tripList");
tripList.addEventListener("scroll", async event => {
if (isScrolledToBottom(tripList)) {
const newPageNum = tripList.childElementCount / TRIP_HISTORY_PAGE_SIZE + 1;
if (newPageNum % 1 === 0) {
console.log("Loading trip history page " + newPageNum);
const spinner = createElementFromHTML(`<img src="assets/images/mGira_spinning.gif" id="tripHistorySpinner">`);
tripList.appendChild(spinner);
tripList.scrollTo({ top: tripList.scrollHeight, behavior: "auto" });
const newTripHistory = await getTripHistory(newPageNum);
spinner.remove();
addTripsToDOM(newTripHistory);
}
// If the new page number is decimal it means the last history request didn't return TRIP_HISTORY_PAGE_SIZE trips
// Therefore there are no more trips to load
}
});

// if there are no trips, put a message saying that
if (tripList.childElementCount === 0) tripList.innerHTML = "Não realizou nenhuma viagem";
}

function downloadTripHistory() {
createCustomYesNoPrompt(
"Deseja descarregar o seu histórico de viagens completo?\n⚠️ Nota: isto pode demorar algum tempo.",
async () => {
document.getElementById("alertBox").innerHTML = `<img src="assets/images/mGira_spinning.gif" id="spinner">`; // Show spinner
downloadObjectAsJson(await getTripHistory(1, 10_000), "tripHistory");
},
() => null
);
}

function addTripsToDOM(tripHistory) {
for (let trip of tripHistory) {
// create the list element
const tripListElement = document.createElement("li");
tripListElement.className = "trip-list-element";
Expand Down Expand Up @@ -509,10 +541,6 @@ async function openTripHistory() {
`.trim();
document.getElementById("tripList").appendChild(tripListElement);
}

// if there are no trips, put a message saying that
if (document.getElementById("tripList").childElementCount === 0)
document.getElementById("tripList").innerHTML = "Não realizou nenhuma viagem";
}

function hideTripHistory() {
Expand Down Expand Up @@ -544,24 +572,22 @@ async function openStatisticsMenu() {
document.body.scrollTop = document.documentElement.scrollTop = 0; // scroll to top of the page
}

if (!user.tripHistory) {
// set background to white
menu.style.backgroundColor = "var(--white)";
// set background to white
menu.style.backgroundColor = "var(--white)";

// show loading animation
menu.innerHTML = `
// show loading animation
menu.innerHTML = `
<img src="assets/images/mGira_spinning.gif" id="spinner">
<div id="backButton" onclick="hideStatisticsMenu();"><i class="bi bi-arrow-90deg-left"></i></div>
`;

// Get user's trip history
await getTripHistory();
// Get user's trip history
const tripHistory = await getTripHistory(1, 10_000);

if (document.querySelectorAll("#statisticsMenu").length === 0) hideStatisticsMenu();
if (document.querySelectorAll("#statisticsMenu").length === 0) hideStatisticsMenu();

// set background back to black
menu.style.backgroundColor = "var(--black)";
}
// set background back to black
menu.style.backgroundColor = "var(--black)";

// Set status bar color in PWA
changeThemeColor("#231f20");
Expand Down Expand Up @@ -618,7 +644,7 @@ async function openStatisticsMenu() {
document.body.appendChild(menu);

// Populate chart
updateStatisticsChart();
updateStatisticsChart(tripHistory);
}

function hideStatisticsMenu() {
Expand All @@ -634,7 +660,7 @@ function hideStatisticsMenu() {
changeThemeColor("#79c000");
}

function updateStatisticsChart() {
function updateStatisticsChart(tripHistory) {
// Get the selected options
let period = document.getElementById("periodControl").value;
let groupBy = document.getElementById("groupControl").value;
Expand Down Expand Up @@ -682,7 +708,7 @@ function updateStatisticsChart() {
: `${dayDate.getDate()}/${dayDate.getMonth() + 1}`;

// Get the trips of the day
const dayTrips = user.tripHistory.filter(trip => {
const dayTrips = tripHistory.filter(trip => {
const startDate = new Date(trip.startDate);
return (
startDate.getDate() === dayDate.getDate() && // Same day
Expand Down

0 comments on commit af413c9

Please sign in to comment.