From cabb9210384225f3fb8bee2c95e3d7eec070a1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janosch=20Mu=CC=88ller?= Date: Sat, 6 Jul 2024 19:48:03 +0200 Subject: [PATCH] Add loading animation, closes #1 --- javascript/src/app.tsx | 7 +++-- javascript/src/hooks/index.ts | 1 + .../src/hooks/use_delayed_loading_style.tsx | 26 +++++++++++++++++++ package.json | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 javascript/src/hooks/use_delayed_loading_style.tsx diff --git a/javascript/src/app.tsx b/javascript/src/app.tsx index 375c58c..c5916de 100644 --- a/javascript/src/app.tsx +++ b/javascript/src/app.tsx @@ -2,7 +2,7 @@ import React, {FunctionComponent, render} from "preact" import habitat from "preact-habitat" import Omnibar, {buildItemStyle} from "omnibar2" import {Globals} from "csstype" -import {useItemAction, useOmnibarExtensions} from "./hooks" +import {useDelayedLoadingStyle, useItemAction, useOmnibarExtensions} from "./hooks" import {useHotkey, useModal, useToggleFocus} from "./hooks" import {AppArgs, INPUT_DATA_ID, Item, ModalArg} from "./types" import {iconClass} from "./icon" @@ -27,6 +27,7 @@ const App: FunctionComponent = (args) => { const RailsOmnibar: FunctionComponent = (args) => { const extensions = useOmnibarExtensions(args) const itemAction = useItemAction(args.itemModal) + const loadingStyle = useDelayedLoadingStyle(); return ( <> @@ -35,10 +36,12 @@ const RailsOmnibar: FunctionComponent = (args) => { extensions={extensions} maxResults={args.maxResults} onAction={itemAction} + onQueryStart={() => loadingStyle.startTimer()} + onQueryEnd={() => loadingStyle.stop()} placeholder={args.placeholder} children={(props) => renderItem({...props, modal: args.modal})} showEmpty - style={args.modal ? MODAL_ROW_STYLE : ROW_STYLE} + style={{...(args.modal ? MODAL_ROW_STYLE : ROW_STYLE), ...loadingStyle.style}} /> {args.itemModal.modal} diff --git a/javascript/src/hooks/index.ts b/javascript/src/hooks/index.ts index e60b706..c35c6aa 100644 --- a/javascript/src/hooks/index.ts +++ b/javascript/src/hooks/index.ts @@ -1,3 +1,4 @@ +export * from "./use_delayed_loading_style" export * from "./use_hotkey" export * from "./use_item_action" export * from "./use_modal" diff --git a/javascript/src/hooks/use_delayed_loading_style.tsx b/javascript/src/hooks/use_delayed_loading_style.tsx new file mode 100644 index 0000000..7ab1e56 --- /dev/null +++ b/javascript/src/hooks/use_delayed_loading_style.tsx @@ -0,0 +1,26 @@ +import {useState} from "preact/hooks" + +export const useDelayedLoadingStyle = () => { + const [enabled, setEnabled] = useState(false) + const [timer, setTimer] = useState(null) + + const startTimer = () => { + if (timer) clearTimeout(timer) + setTimer(setTimeout(() => setEnabled(true), 100)) + } + + const stop = () => { + if (timer) clearTimeout(timer) + setEnabled(false) + } + + return { style : enabled ? LOADING_STYLE : {}, startTimer, stop } +} + +const LOADING_STYLE = { + background: "repeating-linear-gradient(90deg, #000F, #0004 50%, #000F)", + backgroundClip: "text", + backgroundPosition: "40000px", + color: "#0001", + transition: "background 100s ease-out, color 0.15s ease-in", +} diff --git a/package.json b/package.json index 634cdff..efcdc39 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dependencies": { "@heroicons/react": "^2.0.14", "fuzzysort": "^2.0.4", - "omnibar2": "^2.4.5", + "omnibar2": "^2.5.0", "preact": "^10.11.3", "preact-habitat": "^3.3.0", "react-modal": "^3.16.1",