diff --git a/frontend/components/PkgTerminalView.js b/frontend/components/PkgTerminalView.js index 14f8e6277f..6c8479162e 100644 --- a/frontend/components/PkgTerminalView.js +++ b/frontend/components/PkgTerminalView.js @@ -1,12 +1,17 @@ import AnsiUp from "../imports/AnsiUp.js" import { html, Component, useState, useEffect, useRef, useLayoutEffect } from "../imports/Preact.js" +const make_spinner_spin = (original_html) => original_html.replaceAll("◐", ``) + const TerminalViewAnsiUp = ({ value }) => { const node_ref = useRef(/** @type {HTMLElement?} */ (null)) + const start_time = useRef(Date.now()) + useEffect(() => { if (!node_ref.current) return - node_ref.current.innerHTML = new AnsiUp().ansi_to_html(value) + node_ref.current.style.cssText = `--animation-delay: -${(Date.now() - start_time.current) % 1000}ms` + node_ref.current.innerHTML = make_spinner_spin(new AnsiUp().ansi_to_html(value)) const parent = node_ref.current.parentElement if (parent) parent.scrollTop = 1e5 }, [node_ref.current, value]) diff --git a/frontend/editor.css b/frontend/editor.css index 49998a2c8c..2fa1d47bb9 100644 --- a/frontend/editor.css +++ b/frontend/editor.css @@ -2006,6 +2006,13 @@ pkg-terminal pre { margin: 0; } +pkg-terminal .make-me-spin { + display: inline-block; + animation: identifier-spin 1s linear infinite; + transform-origin: 50% 59%; + animation-delay: var(--animation-delay); +} + pkg-popup pkg-terminal { display: none; } diff --git a/src/packages/IOListener.jl b/src/packages/IOListener.jl index f1dab23982..d2280e94a2 100644 --- a/src/packages/IOListener.jl +++ b/src/packages/IOListener.jl @@ -47,3 +47,8 @@ function stoplistening(listener::IOListener) trigger(listener) end end + +freeze_loading_spinners(s::AbstractString) = _replaceall(s, '◑' => '◐', '◒' => '◐', '◓' => '◐') + +_replaceall(s, p) = replace(s, p) +_replaceall(s, p, ps...) = @static VERSION >= v"1.7" ? replace(s, p, ps...) : _replaceall(replace(s, p), ps...) \ No newline at end of file diff --git a/src/packages/Packages.jl b/src/packages/Packages.jl index 86b4539caf..2e74e7cbaa 100644 --- a/src/packages/Packages.jl +++ b/src/packages/Packages.jl @@ -112,7 +112,7 @@ function sync_nbpkg_core( iolistener = let busy_packages = notebook.nbpkg_ctx_instantiated ? added : new_packages report_to = ["nbpkg_sync", busy_packages...] - IOListener(callback=(s -> on_terminal_output(report_to, s))) + IOListener(callback=(s -> on_terminal_output(report_to, freeze_loading_spinners(s)))) end cleanup[] = () -> stoplistening(iolistener) @@ -553,7 +553,7 @@ function update_nbpkg_core( iolistener = let # we don't know which packages will be updated, so we send terminal output to all installed packages report_to = ["nbpkg_update", old_packages...] - IOListener(callback=(s -> on_terminal_output(report_to, s))) + IOListener(callback=(s -> on_terminal_output(report_to, freeze_loading_spinners(s)))) end cleanup[] = () -> stoplistening(iolistener)