PluginProbe
Extendify / trunk
Extendify vtrunk
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
← All changes | src/Agent/components/messages/StatusIndicator.jsx +37 -41 3.1.3 → trunk View file →
@@ -1,62 +1,58 @@
1 -import { AnimateChunks } from '@agent/components/messages/AnimateChunks';
2 1 import { useStatusStore } from '@agent/state/status';
3 2 import { useEffect, useMemo, useState } from '@wordpress/element';
4 3 import { decodeEntities } from '@wordpress/html-entities';
5 4 import { __ } from '@wordpress/i18n';
6 -import classNames from 'classnames';
7 5
8 -const canAnimateTypes = ['calling-agent', 'agent-working', 'tool-started'];
6 +const linesFor = (label) => ({
7 + 'calling-agent': __('Thinking...', 'extendify-local'),
8 + 'agent-working': [
9 + __('Working on it...', 'extendify-local'),
10 + __('Interpreting message...', 'extendify-local'),
11 + __('Formulating a response...', 'extendify-local'),
12 + __('Reviewing logic...', 'extendify-local'),
13 + ],
14 + 'workflow-tool-processing': __('Processing...', 'extendify-local'),
15 + 'tool-started': label || __('Gathering data...', 'extendify-local'),
16 + 'credits-exhausted': __('Usage limit reached', 'extendify-local'),
17 + 'credits-restored': __('Usage limit restored', 'extendify-local'),
18 +});
9 19
10 -export const StatusIndicator = () => {
11 - const status = useStatusStore((s) => s.statuses.at(-1));
12 - const { type, label } = status ?? {};
20 +// Randomized 3-5s beat so a long wait never looks stuck or syncs across sites.
21 +const useCurrentLine = (lines) => {
13 22 const [index, setIndex] = useState(0);
14 - const statusContent = useMemo(
15 - () => ({
16 - 'calling-agent': __('Thinking...', 'extendify-local'),
17 - 'agent-working': [
18 - __('Working on it...', 'extendify-local'),
19 - __('Interpreting message...', 'extendify-local'),
20 - __('Formulating a response...', 'extendify-local'),
21 - __('Reviewing logic...', 'extendify-local'),
22 - ],
23 - 'workflow-tool-processing': __('Processing...', 'extendify-local'),
24 - 'tool-started': label || __('Gathering data...', 'extendify-local'),
25 - 'tool-completed': label || __('Analyzing...', 'extendify-local'),
26 - 'credits-exhausted': __('Usage limit reached', 'extendify-local'),
27 - 'credits-restored': __('Usage limit restored', 'extendify-local'),
28 - }),
29 - [label],
30 - );
31 - const content = statusContent[type];
32 - const isList = Array.isArray(content);
23 + const isList = Array.isArray(lines);
33 24
34 - useEffect(() => setIndex(0), [type]);
25 + useEffect(() => setIndex(0), [lines]);
35 26
36 27 useEffect(() => {
37 28 if (!isList) return;
38 - // Cycle verbs on a randomized 3-5s beat so it never looks stuck.
39 29 const timer = setTimeout(
40 - () => setIndex((i) => (i + 1) % content.length),
30 + () => setIndex((i) => (i + 1) % lines.length),
41 31 3000 + Math.random() * 2000,
42 32 );
43 33 return () => clearTimeout(timer);
44 - }, [isList, content, index]);
34 + }, [isList, lines, index]);
45 35
46 - if (!type || !content) return null;
47 - const text = isList ? content[index] : content;
36 + return isList ? lines[index] : lines;
37 +};
48 38
39 +export const StatusIndicator = () => {
40 + const leavingPage = useStatusStore((s) => s.leavingPage);
41 + const { type, label } = useStatusStore((s) => s.statuses.at(-1)) ?? {};
42 + const lines = useMemo(() => linesFor(label)[type], [label, type]);
43 + const currentLine = useCurrentLine(lines);
44 + const text = leavingPage
45 + ? __('Refreshing the page to show your changes…', 'extendify-local')
46 + : currentLine;
47 +
48 + if (!text) return null;
49 +
49 50 return (
50 - <div
51 - className={classNames('p-2 text-center text-xs italic text-gray-700', {
52 - 'status-animation': canAnimateTypes.includes(type),
53 - })}
54 - >
55 - <AnimateChunks
56 - key={`${type}-${index}`}
57 - words={decodeEntities(text).split('')}
58 - delay={0.02}
59 - />
51 + <div className="p-2 text-center text-xs italic text-gray-700">
52 + {/* Reusing the node drops the new line mid-sweep. */}
53 + <span key={text} className="status-animation">
54 + {decodeEntities(text)}
55 + </span>
60 56 </div>
61 57 );
62 58 };