diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button.js b/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button.js index 4b2f6a9f90..0aa9900cde 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button.js @@ -11,10 +11,12 @@ import getMeta from '../../../utils/meta' function PdfCompileButton() { const { + animateCompileDropdownArrow, autoCompile, compiling, draft, hasChanges, + setAnimateCompileDropdownArrow, setAutoCompile, setDraft, setStopOnValidationError, @@ -46,8 +48,14 @@ function PdfCompileButton() { { + setAnimateCompileDropdownArrow(false) + }} /> diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.js b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.js index c0fee73644..9e3daa8a27 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.js @@ -168,13 +168,15 @@ function TimedOutLogEntry() { const { enableStopOnFirstError } = useStopOnFirstError({ eventSource: 'timeout', }) - const { startCompile, lastCompileOptions } = useCompileContext() + const { startCompile, lastCompileOptions, setAnimateCompileDropdownArrow } = + useCompileContext() const showStopOnFirstError = getMeta('ol-showStopOnFirstError') const handleEnableStopOnFirstErrorClick = useCallback(() => { enableStopOnFirstError() startCompile({ stopOnFirstError: true }) - }, [enableStopOnFirstError, startCompile]) + setAnimateCompileDropdownArrow(true) + }, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow]) if (showStopOnFirstError) { return ( diff --git a/services/web/frontend/js/features/pdf-preview/components/stop-on-first-error-prompt.js b/services/web/frontend/js/features/pdf-preview/components/stop-on-first-error-prompt.js index 68a7bf6f81..f29d16f97e 100644 --- a/services/web/frontend/js/features/pdf-preview/components/stop-on-first-error-prompt.js +++ b/services/web/frontend/js/features/pdf-preview/components/stop-on-first-error-prompt.js @@ -7,7 +7,7 @@ import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-err export default function StopOnFirstErrorPrompt() { const { t } = useTranslation() - const { startCompile } = useCompileContext() + const { startCompile, setAnimateCompileDropdownArrow } = useCompileContext() const { disableStopOnFirstError } = useStopOnFirstError({ eventSource: 'logs-pane', }) @@ -15,7 +15,8 @@ export default function StopOnFirstErrorPrompt() { const handleDisableButtonClick = useCallback(() => { disableStopOnFirstError() startCompile({ stopOnFirstError: false }) - }, [disableStopOnFirstError, startCompile]) + setAnimateCompileDropdownArrow(true) + }, [disableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow]) return ( { enableStopOnFirstError() startCompile({ stopOnFirstError: true }) - }, [enableStopOnFirstError, startCompile]) + setAnimateCompileDropdownArrow(true) + }, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow]) return (
diff --git a/services/web/frontend/js/shared/context/detach-compile-context.js b/services/web/frontend/js/shared/context/detach-compile-context.js index 162dde9c89..c66fda8b6b 100644 --- a/services/web/frontend/js/shared/context/detach-compile-context.js +++ b/services/web/frontend/js/shared/context/detach-compile-context.js @@ -20,6 +20,7 @@ export function DetachCompileProvider({ children }) { } const { + animateCompileDropdownArrow: _animateCompileDropdownArrow, autoCompile: _autoCompile, clearingCache: _clearingCache, clsiServerId: _clsiServerId, @@ -38,6 +39,7 @@ export function DetachCompileProvider({ children }) { pdfViewer: _pdfViewer, position: _position, rawLog: _rawLog, + setAnimateCompileDropdownArrow: _setAnimateCompileDropdownArrow, setAutoCompile: _setAutoCompile, setDraft: _setDraft, setError: _setError, @@ -64,6 +66,12 @@ export function DetachCompileProvider({ children }) { clearCache: _clearCache, } = localCompileContext + const [animateCompileDropdownArrow] = useDetachStateWatcher( + 'animateCompileDropdownArrow', + _animateCompileDropdownArrow, + 'detacher', + 'detached' + ) const [autoCompile] = useDetachStateWatcher( 'autoCompile', _autoCompile, @@ -199,6 +207,12 @@ export function DetachCompileProvider({ children }) { 'detached' ) + const setAnimateCompileDropdownArrow = useDetachAction( + 'setAnimateCompileDropdownArrow', + _setAnimateCompileDropdownArrow, + 'detached', + 'detacher' + ) const setAutoCompile = useDetachAction( 'setAutoCompile', _setAutoCompile, @@ -310,6 +324,7 @@ export function DetachCompileProvider({ children }) { const value = useMemo( () => ({ + animateCompileDropdownArrow, autoCompile, clearCache, clearingCache, @@ -330,6 +345,7 @@ export function DetachCompileProvider({ children }) { position, rawLog, recompileFromScratch, + setAnimateCompileDropdownArrow, setAutoCompile, setCompiling, setDraft, @@ -354,6 +370,7 @@ export function DetachCompileProvider({ children }) { cleanupCompileResult, }), [ + animateCompileDropdownArrow, autoCompile, clearCache, clearingCache, @@ -374,6 +391,7 @@ export function DetachCompileProvider({ children }) { position, rawLog, recompileFromScratch, + setAnimateCompileDropdownArrow, setAutoCompile, setCompiling, setDraft, diff --git a/services/web/frontend/js/shared/context/local-compile-context.js b/services/web/frontend/js/shared/context/local-compile-context.js index b3deafdf15..7534ca237e 100644 --- a/services/web/frontend/js/shared/context/local-compile-context.js +++ b/services/web/frontend/js/shared/context/local-compile-context.js @@ -121,6 +121,10 @@ export function LocalCompileProvider({ children }) { // whether the logs should be visible const [showLogs, setShowLogs] = useState(false) + // whether the compile dropdown arrow should be animated + const [animateCompileDropdownArrow, setAnimateCompileDropdownArrow] = + useState(false) + const toggleLogs = useCallback(() => { setShowLogs(prev => { if (!prev) { @@ -468,6 +472,7 @@ export function LocalCompileProvider({ children }) { const value = useMemo( () => ({ + animateCompileDropdownArrow, autoCompile, clearCache, clearingCache, @@ -488,6 +493,7 @@ export function LocalCompileProvider({ children }) { position, rawLog, recompileFromScratch, + setAnimateCompileDropdownArrow, setAutoCompile, setCompiling, setDraft, @@ -512,6 +518,7 @@ export function LocalCompileProvider({ children }) { cleanupCompileResult, }), [ + animateCompileDropdownArrow, autoCompile, clearCache, clearingCache, @@ -532,6 +539,7 @@ export function LocalCompileProvider({ children }) { pdfViewer, rawLog, recompileFromScratch, + setAnimateCompileDropdownArrow, setAutoCompile, setDraft, setError, diff --git a/services/web/frontend/stylesheets/app/editor/pdf.less b/services/web/frontend/stylesheets/app/editor/pdf.less index 3e2f49d88a..f7272cad92 100644 --- a/services/web/frontend/stylesheets/app/editor/pdf.less +++ b/services/web/frontend/stylesheets/app/editor/pdf.less @@ -187,6 +187,46 @@ margin-left: @line-height-computed / 4; } +@keyframes compile-button-flash { + from, + to { + background: rgba(0, 0, 0, 0); + } + + 25%, + 75% { + background: rgba(0, 0, 0, 0.2); + } +} + +@keyframes compile-button-bounce { + from, + 50%, + to { + transform: translateY(0); + } + + 25%, + 75% { + transform: translateY(2px); + } +} + +.btn-recompile-animate { + animation-duration: 1.2s; + animation-fill-mode: both; + animation-timing-function: ease-in-out; + animation-name: compile-button-flash; +} + +.btn-recompile-animate .caret { + animation-duration: 0.6s; + animation-delay: 0.4s; + animation-fill-mode: both; + animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1); + animation-name: compile-button-bounce; +} + .toolbar-text { padding-left: @padding-xs; }