Skip to content

Toolbox install: report crawl progress and explain an empty install list - #44

Open
mojie126 wants to merge 4 commits into
TypesettingTools:mainfrom
mojie126:toolbox-install-progress-feedback
Open

Toolbox install: report crawl progress and explain an empty install list#44
mojie126 wants to merge 4 commits into
TypesettingTools:mainfrom
mojie126:toolbox-install-progress-feedback

Conversation

@mojie126

Copy link
Copy Markdown

Fixes #43.

What

Two small UX fixes for the Toolbox Install Script macro:

  1. Progress feedback during the feed crawl. The macro now calls aegisub.progress.task with "Scanning available feeds..." before crawlWithPrompt buildFeedInventory! and "Loading feed data..." before loading the feeds, so the background-script progress dialog shows what is happening instead of sitting blank for the whole crawl (~9 s with the default feed set). logger\log alone doesn't help here since it only writes to the DependencyControl log file.

  2. Explain an empty install list. When both macros and modules are empty — the common case, since installed scripts are registered automatically and addAvailableToInstall filters them out — the macro now shows a small notice dialog ("All available scripts are already installed; nothing new to install.") and returns, instead of popping the script list dialog with only a Cancel button.

Messages go through the existing msgs.install table, and the notice dialog reuses the label-dialog shape of confirmDialog.

Testing

Verified against v0.9.0 running in Aegisub (Windows): the progress dialog shows both task messages during the crawl, and with everything already installed the notice appears instead of the empty list.

Fixes TypesettingTools#43

- Call aegisub.progress.task before crawling feeds and before loading feed
  data, so the background script progress dialog no longer sits blank for
  the whole crawl.
- When nothing new can be installed, show a notice dialog instead of the
  script list dialog with only a Cancel button.

@line0 line0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks you for the contribution, please have a look at my findings.

Comment on lines +278 to +282
unless next(modules) or next(macros)
aegisub.dialog.display {{class: "label", x: 0, y: 0, width: 1, height: 1, label: msgs.install.empty}},
{buttons.close}, {ok: buttons.close, cancel: buttons.close}
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did you test that? I don't think it can actually work because addAvailableToInstall() adds a channel table to modules or macros for each available package, installed or not. The only situation in which the "All available scripts are already installed; nothing new to install." message dialog would actually show is when no scripts are (currently) available to install at all (no internet and no feed cache, all known feeds blocked, other freak occurrences).

At the very least, you'll have to do this check on the length of the flattened moduleList and macroList below, but even then you can't just draw the conclusion that all available feeds must be installed. You also want to collect metadata from FeedInventory.crawl() that tells you if any feed wasn't fetched and for what reason. If we couldn't crawl all feeds that should have been crawled we should point out as such, because that may be the reason why there's nothing to install.

scanning: "Scanning %d available feeds...",
scanningTask: "Scanning available feeds..."
loadingTask: "Loading feed data..."
empty: "All available scripts are already installed; nothing new to install."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the second clause just restates what obviously follows from the first one, so just drop it.

-- FeedInventory crawls the known feeds, which are trust-gated and bounded. The shared feed loader then
-- serves each reachable feed's data from the cache the crawl just populated.
macros, modules = {}, {}
aegisub.progress.task msgs.install.scanningTask

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it would be even better if this one actually displayed a moving progress bar but that would involve adding a progress callback to FeedInventory.crawl(), so if you'd rather keep it simple, leave it is and I'll add it to my TODO list as a low priority item.

aegisub.progress.task msgs.install.scanningTask
entries = crawlWithPrompt buildFeedInventory!

aegisub.progress.task msgs.install.loadingTask

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

does this one show for any appreciable time for you? It doesn't hurt to have this, but if loading the feeds after fetching is near-instant for you and you haven't disabled the feed cache then it's worth investigating why.

addAvailableToInstall creates a (possibly empty) table for every known
package regardless of install state, so next(modules)/next(macros) is
almost always truthy and the empty notice could never fire. Check the
flattened moduleList/macroList lengths instead, and when some feeds
weren't fetched say so, since that may be why there is nothing to
install. Also drop the redundant second clause of the empty message.
@mojie126

Copy link
Copy Markdown
Author

Thanks for the review! Pushed 0b2d72a addressing the findings:

  • Empty-list check (line 282): You're right — I hadn't tested that branch, and it could never fire, since addAvailableToInstall() creates a (possibly empty) table for every known package regardless of install state. The check now runs on the flattened moduleList/macroList lengths after buildDlgList, and when some feeds weren't fetched the notice says how many of how many couldn't be fetched (emptyUnfetched), since that may be why there is nothing to install, rather than claiming everything is installed.
  • Message wording (line 31): Dropped the redundant second clause.
  • Progress bar (line 267): Keeping it simple for now — thanks for adding the crawl progress callback to your TODO.
  • "Loading feed data..." (line 270): In my testing the crawl takes ~9 s for 21 feeds and the load phase right after is indeed near-instant with the feed cache enabled, so this task only shows briefly. I've kept it to cover the no-persistent-cache case (first run), where the loader has more to do — happy to drop it if you'd rather not have a task that usually doesn't show.

Called after each feed is fetched, with the running fetch count and the
number of feeds currently known to the crawl. The crawl discovers more
feeds as it goes, so the known count may grow over time.
Drive aegisub.progress.set from the new crawl callback so the scan shows
actual progress, and abort the crawl when the user cancels: the callback
raises, crawlWithPrompt traps it (resetting the prompter), re-raises real
errors, and install returns quietly on cancellation.
@mojie126

Copy link
Copy Markdown
Author

Went ahead and implemented the crawl progress callback after all (ff02a113 + 8cbd650c), so the install scan now shows a moving progress bar instead of a static task:

  • FeedInventory:crawl(onProgress): optional callback invoked after each feed is fetched, with the running fetch count and the number of feeds currently known to the crawl. The crawl keeps discovering feeds as it goes, so the known count (the denominator) can grow — the bar may occasionally step back a little. Feeds that fail to fetch or get truncated by a crawl budget don't fire the callback, so the install macro tops the bar up to 100% once the crawl returns.
  • Cancellation: the progress callback raises when aegisub.progress.is_cancelled() reports the user hit Cancel. crawlWithPrompt wraps the crawl in a pcall so the prompter still gets reset, re-raises anything that isn't the cancellation, and returns nil; install then returns quietly. Previously Cancel just sat on "Cancelling..." while the crawl kept downloading.

One structural limitation remains, which I don't think the script can do anything about: while the (modal) script-list dialog is up, the background progress dialog's Cancel button has no one to poll it, so it stays on "Cancelling..." until the dialog is dismissed — closing the list dialog is the way out there.

Tested on Windows against v0.9.0 with the feed cache cleared: the bar advances over the ~9 s crawl, tops up at the end, and cancelling mid-crawl aborts immediately.

@mojie126
mojie126 requested a review from line0 August 22, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toolbox "Install Script": no progress feedback while crawling feeds, and silent empty list when everything is already installed

2 participants