PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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.23.2.1 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 };