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

Added global appstate object to track article and asset Loading #1310

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

THEBOSS0369
Copy link
Collaborator

This PR Fixes #1126

This PR implements a centralized loading state management system using the global appState object, i have also added an universal messaging without direct DOM manipulation.

Test

I have done all the necessary test

  1. Checked in both "Restricted" and "ServiceWorker" Everything is working fine.
  2. Unit tests npm test no issue
  3. End-to-end (e2e) tests-e2e-firefox-> All tests Passed.
  4. extension versions with production code tested
  5. Browser Test -> Microsoft Edge.

@Jaifroid
Copy link
Member

@THEBOSS0369 Could you take a look at the Codefactor issues, and try to fix?

@THEBOSS0369
Copy link
Collaborator Author

@Jaifroid out of curiosity, i was wondering if the codefactor checker has been updated recently or any other module related to it? as this codefactor test didn't failed last time i pushed the changes

@Jaifroid
Copy link
Member

No, nothing has changed, but I do find codefactor to be a bit "inconsistent" 😅 !

@Jaifroid
Copy link
Member

@THEBOSS0369 Sorry it's taken so long to test this one. I'm seeing a repeated error in console with this branch. See screenshot. Please check and debug it carefully! Also, branch needs updating again. Thanks!

image

@Jaifroid Jaifroid self-requested a review March 23, 2025 10:40
Copy link
Member

@Jaifroid Jaifroid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix error clickedAnchor is not defined.

@THEBOSS0369
Copy link
Collaborator Author

THEBOSS0369 commented Mar 23, 2025

@Jaifroid Sir can you please help me to recreate that error because i am not able to recreate it in my system. i have made sure that my branch is updated with the latest changes and i am checking this on the global-appstate branch (this pr branch) please check the video below for reference

Recording.2025-03-23.173217.mp4

@Jaifroid
Copy link
Member

@THEBOSS0369 You need to view debug logs! Click on "Default levels" (top-right of Console) and add "Verbose" debugging. It should then show as "All levels".

image

@THEBOSS0369
Copy link
Collaborator Author

THEBOSS0369 commented Mar 23, 2025

@Jaifroid My sincere apologies sir i am consuming your time but i still not able to recreate after turning verbose
here is the video

i have ensured that i am on correct branch and i have pulled the latest changes in my branch

verbose.mode.mp4

These are my setting in my config if it is causing any issue
image
image
image

@THEBOSS0369
Copy link
Collaborator Author

Also sir if you think this pr demand more time of yours then we can come to this pr later whenever you want if it is not an urgent requirement.

@Jaifroid
Copy link
Member

OK, let me check.

Unrelated, but just so you know, testing on the library previews is not a valid test, as that code is nothing to do with Kiwix JS -- that's Kiwix Serve running on a different server library.kiwix.org. The only valid tests are those done on local ZIMs loaded in the app (like your Wikivoyage test).

I'll see if I can isolate this discrepancy.

@Jaifroid
Copy link
Member

@THEBOSS0369 My apologies, after puzzling over this for a while, I realized that there was a conditional breakpoint in my DevTools that was somehow only being evaluated on your branch, but not on main. The error was being produced by the attempt to evaluate a value that no longer exists at that spot in the code.

So, nothing to do with your PR. 🙏😊

I'm just doing some last tests...

Copy link
Member

@Jaifroid Jaifroid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this PR is on the right tracks, it doesn't really achieve what the issue was envisaging. All this PR does is replace a simple uiUtil.spinnerDisplay with some "helper" functions that do exactly the same thing, ultimately making the code more complicated.

The display of asset loading is the new feature, but this only works in Restricted mode, as there is no similar code added for ServiceWorker mode. I'll explain in another post how this needs to be handled.

www/js/app.js Outdated
Comment on lines 3231 to 3239
// eslint-disable-next-line no-unused-vars
function updateUI () {
if (appstate.isLoadingArticle || appstate.isLoadingAsset) {
uiUtil.spinnerDisplay(true, appstate.loadingMessage);
} else {
uiUtil.spinnerDisplay(false);
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of this function if it's not used? You've disabled eslint errorchecking for it, but that doesn't fix the underlying issue that we have unused code... You should just remove it if it is of no use.

Copy link
Collaborator Author

@THEBOSS0369 THEBOSS0369 Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this section i initially thought that i can directly add the spinner display logic in this instead of stop or start loading. But i think start and stop logic is working fine so its not required anymore i will remove it.

www/js/app.js Outdated
*/
var appstate = {};
* @type Object */
var appstate = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we try to modernize code as we work on it, I suggest you change this var to const.

www/js/app.js Outdated
@@ -3023,6 +3058,8 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
}
// Get the image URL
var imageUrl = image.getAttribute('data-kiwixurl');
// Start Loading the imaeg and update appstate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo ;-) You want "image", not "imaeg"

www/js/app.js Outdated
@@ -3023,6 +3058,8 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
}
// Get the image URL
var imageUrl = image.getAttribute('data-kiwixurl');
// Start Loading the imaeg and update appstate
startLoadingAsset('Loading Image: ' + imageUrl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This string isn't translated! All strings to be displayed in the UI must be passed through the translation system.

@Jaifroid
Copy link
Member

Jaifroid commented Mar 23, 2025

OK, so the idea of the issue was to add a global state object that would be available for use in the backend (e.g. in zimArchive, where HTML and binary files are loaded at a low level, and also in zimArchive.callLibzimWorker, and potentially other parts of the backend.

The tricky part is working out how to do this without creating a dependency of the backend on the UI, which is a no-no.

So, we just want a global variable that can be updated in zimArchive (but defined elsewhere). Elsewhere in the code, probably in uiUtil, while the spinner is showing, a timer process would check the variable's state and if it has changed, would update the UI. This way we don't break the architecture of the app, while still allowing for cross-module communication.

One possibility would be to define appstate in init.js, alongside params as a true global variable. But I think this could create problems for how we use appstate for search. So it might be better to define a different object there, maybe just appMessages. The main problem here is that the app can have more than one window open, and all requests from different windows are trapped by the Service Worker, so we could end up with cross-contamination if two windows happened to be getting assets or articles at the same time.

So, the architecture of this needs more thought... I don't have enough time to plan this out fully right now. Let me know if you have any ideas.

@Jaifroid
Copy link
Member

As you say, this isn't an urgent PR. I thought it would be fairly simple, but turns out to have a few complications and needs more thought to re-architecture. I think we should focus on the Wikipedia Dark Mode first, while thinking about this.

@THEBOSS0369
Copy link
Collaborator Author

THEBOSS0369 commented Mar 24, 2025

@Jaifroid Sir this is the solution i can think of. it may not be perfect but at least it can give us some ideas to explore

so i am thinking that instead of using a global variable we can create something like a specific message system in init.js and then zimArchive can send the updates and then ui can get that without direct ui dependency.

For multiple window we can add a system such that every window will have its own unique id when it starts and when sending the request the id can tell from which window the request is coming and then sw mode can handle it properly before showing it to user. although i've not work on window functionality very much so after researching about it for a while this is what i was able to come up with.

Let me know if any of the above ideas i mentioned can help us in any way.

As you say, this isn't an urgent PR. I thought it would be fairly simple, but turns out to have a few complications and needs more thought to re-architecture. I think we should focus on the Wikipedia Dark Mode first, while thinking about this.

No objection from my side sir and i'm getting a feeling that this is gonna be a real complex one so it will demand more time of yours and mine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use global appState object to track article and asset loading, and provide spinner messaging accordingly
2 participants