-
Notifications
You must be signed in to change notification settings - Fork 92
gcoai-stream-loading-text-animation.php: Added a new snippet for customizing the Steam field's loading text.
#1187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…stomizing the Steam field's loading text.
|
Caution Review failedThe pull request is closed. WalkthroughAdds a new PHP class Changes
Sequence Diagram(s)sequenceDiagram
participant WP as WordPress
participant GF as Gravity Forms
participant GCOAI as GCOAI_Loading_Animation
participant Browser as Browser JS
WP->>GCOAI: instantiate(config)
GCOAI->>WP: add_filter(gform_gcoai_field_loading_text)
GCOAI->>WP: add_action(gform_register_init_scripts)
GF->>GCOAI: filter_loading_text(placeholder, field, form)
alt target matches
GCOAI->>GF: return shimmer + optional spinner markup
else
GCOAI->>GF: return original placeholder
end
WP->>GCOAI: gform_register_init_scripts(form, is_ajax)
GCOAI->>Browser: inject CSS & init script (idempotent)
Browser->>Browser: apply/animate shimmer and spinner
Browser->>Browser: on AJAXComplete / regenerate -> reapply markup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…stomizing the Steam field's loading text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
gc-openai/gcoai-stream-loading-text-animation.php (1)
30-91: JS init script is solid; consider handling$is_ajaxandgformtimingThe script injection, use of
wp_json_encode, and re-applying the shimmer after clicks/AJAX all look correct for the intended UX.Two minor points:
$is_ajaxis never used, which PHPMD has flagged. If you want a clean run, either:
- Prefix the parameter (e.g.,
$_is_ajax) or- Add a small no-op reference (
$unused = $is_ajax;) or PHPMD suppression, while keeping the signature compatible with the hook.
window.gform.addFilteris checked at script-evaluation time. Ifgformis sometimes defined later, you might prefer to move that block into the$(function() { ... })callback so the filter registration runs after the Gravity Forms scripts are loaded.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
gc-openai/gcoai-stream-loading-text-animation.php(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: PHP Lint (PR)
gc-openai/gcoai-stream-loading-text-animation.php
[error] 5-5: Whitespace found at end of line (Squiz.WhiteSpace.SuperfluousWhitespace.EndLine).
🪛 GitHub Check: PHPCS (Files Changed)
gc-openai/gcoai-stream-loading-text-animation.php
[failure] 147-147:
Whitespace found at end of line
[failure] 139-139:
Whitespace found at end of line
[failure] 131-131:
Whitespace found at end of line
[failure] 123-123:
Whitespace found at end of line
[failure] 110-110:
Whitespace found at end of line
[failure] 95-95:
Whitespace found at end of line
[failure] 45-45:
Whitespace found at end of line
[failure] 34-34:
Whitespace found at end of line
[failure] 6-6:
Whitespace found at end of line
[failure] 5-5:
Whitespace found at end of line
🪛 PHPMD (2.15.0)
gc-openai/gcoai-stream-loading-text-animation.php
30-30: Avoid unused parameters such as '$is_ajax'. (undefined)
(UnusedFormalParameter)
🔇 Additional comments (4)
gc-openai/gcoai-stream-loading-text-animation.php (4)
13-28: Constructor defaults and hook registration look goodDefaults are sensible, and hooking into
gform_gcoai_field_loading_textandgform_register_init_scriptswith the correct argument counts is appropriate for this behavior.
93-117: Shimmer markup generation and escaping look correct
get_shimmer_markup()builds predictable markup, and the use ofesc_attrfor SVG attributes andesc_htmlfor the text protects against accidental injection from configuration values. Behavior matches the documented options for shimmer and spinner.
143-158: CSS generation is reasonable and properly parameterized
get_styles_css()correctly threads through the configurable base color, shimmer color, and duration into the CSS string, and the resulting rules cover both the spinner and shimmer text. Given that the inputs come from trusted configuration and are escaped, this looks good for the intended snippet use case.
163-173: Default configuration block is clear and matches documented behaviorThe example instantiation with comments for
form_idandfield_idmakes it easy to copy/paste and scope the animation, and the defaults (text + shimmer + spinner) align with the PR description.
| public function filter_loading_text( $placeholder, $field, $form = null ) { | ||
| if ( ! class_exists( '\\GC_OpenAI\\Fields\\Stream' ) || ! $field instanceof \GC_OpenAI\Fields\Stream ) { | ||
| return $placeholder; | ||
| } | ||
|
|
||
| // If form_id is specified, only apply to those forms | ||
| if ( $this->args['form_id'] !== null ) { | ||
| $form_ids = is_array( $this->args['form_id'] ) ? $this->args['form_id'] : array( $this->args['form_id'] ); | ||
| if ( $form && ! in_array( rgar( $form, 'id' ), $form_ids ) ) { | ||
| return $placeholder; | ||
| } | ||
| } | ||
|
|
||
| // If field_id is specified, only apply to those fields | ||
| if ( $this->args['field_id'] !== null ) { | ||
| $field_ids = is_array( $this->args['field_id'] ) ? $this->args['field_id'] : array( $this->args['field_id'] ); | ||
| if ( ! in_array( rgar( $field, 'id' ), $field_ids ) ) { | ||
| return $placeholder; | ||
| } | ||
| } | ||
|
|
||
| return $this->get_shimmer_markup(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
field_id targeting is broken due to use of rgar on a field object
In filter_loading_text(), the form scoping uses rgar( $form, 'id' ), which is fine because $form is an array. For fields, however, you already check $field instanceof \GC_OpenAI\Fields\Stream, so $field is an object. Passing it to rgar( $field, 'id' ) will always produce an empty string, meaning the field_id filter never matches and the shimmer is never applied when field_id is configured.
You can fix this by reading $field->id directly and normalizing types for comparison:
- // If field_id is specified, only apply to those fields
- if ( $this->args['field_id'] !== null ) {
- $field_ids = is_array( $this->args['field_id'] ) ? $this->args['field_id'] : array( $this->args['field_id'] );
- if ( ! in_array( rgar( $field, 'id' ), $field_ids ) ) {
- return $placeholder;
- }
- }
+ // If field_id is specified, only apply to those fields
+ if ( $this->args['field_id'] !== null && isset( $field->id ) ) {
+ $field_ids = is_array( $this->args['field_id'] ) ? $this->args['field_id'] : array( $this->args['field_id'] );
+ // Normalize IDs to strings for consistent comparison.
+ $field_ids = array_map( 'strval', $field_ids );
+
+ if ( ! in_array( (string) $field->id, $field_ids, true ) ) {
+ return $placeholder;
+ }
+ }Also, if there are code paths where this filter is called without a $form value, form_id scoping will be skipped entirely; it’s worth confirming the filter’s usage in GC OpenAI to ensure that’s acceptable.
I'll verify the review comment by examining the codebase to understand the issue with rgar() function and the field object handling.
I've confirmed from Gravity Forms documentation that the rgar() function is used to retrieve a value from an array, while rgobj() is used to retrieve a property value from an object. This validates the core of the review comment. Now I need to verify the codebase specifics.
---
🏁 Script executed:
```shell
#!/bin/bash
# Search for filter_loading_text calls and hook registration
rg -n "filter_loading_text" --type=php
Length of output: 279
🏁 Script executed:
#!/bin/bash
# Find the Stream class to check if it has an 'id' property
fd -e php | xargs grep -l "class Stream" | head -5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for add_filter/add_action calls that might register this filter
rg -n "add_filter.*placeholder" --type=php -B2 -A2Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for gcoai-stream-loading-text-animation.php to understand filter registration
fd "gcoai-stream-loading-text-animation.php"Length of output: 49
Let me examine the file content and find the Stream class definition:
---
🏁 Script executed:
```shell
#!/bin/bash
# Read the full file to understand context and the filter registration
cat gc-openai/gcoai-stream-loading-text-animation.php
Length of output: 6227
🏁 Script executed:
#!/bin/bash
# Search for Stream class more broadly
rg -n "class.*Stream" --type=php -A5Length of output: 560
🏁 Script executed:
#!/bin/bash
# Search for where the filter gform_gcoai_field_loading_text is called/applied
rg -n "gform_gcoai_field_loading_text" --type=php -B3 -A3Length of output: 603
🏁 Script executed:
#!/bin/bash
# Check if rgar function is defined in codebase or if it's from Gravity Forms
rg -n "function rgar\|function rgobj" --type=phpLength of output: 0
Now I need to verify the behavior of rgar() when passed an object, and confirm the Stream class structure. Let me search for more context:
🏁 Script executed:
#!/bin/bash
# Search for any composer.json or dependency declarations to understand GC_OpenAI origin
fd "composer.json\|package.json\|requirements.php" -type fLength of output: 170
🏁 Script executed:
#!/bin/bash
# Look for any GC_OpenAI class definitions or where Stream is defined
rg -n "GC_OpenAI.*Fields.*Stream" --type=php -B2 -A10Length of output: 1226
🏁 Script executed:
#!/bin/bash
# Check if there are any other files that reference Stream or use field->id directly
rg -n "\$field->id" --type=php -C2Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for filter callers to understand who calls gform_gcoai_field_loading_text
rg -n "apply_filters.*gform_gcoai_field_loading_text\|do_filter.*gform_gcoai_field_loading_text" --type=php -B3 -A3Length of output: 0
🌐 Web query:
Gravity Forms rgar function behavior with objects instead of arrays
💡 Result:
Short answer: rgar() expects arrays — it checks array keys and will not read object properties. For Gravity Forms objects (fields, etc.) use rgobj() or object property access (->), or cast the object to an array first.
Why and examples:
- rgar() is documented as “Get a specific property of an array” and is intended for associative arrays (returns null if key missing). [1]
- For objects Gravity Forms provides rgobj() to get an object property. Many GF structures (fields since v1.9) use object notation ($field->inputs). [2][3]
Examples:
-
Array (use rgar):
$value = rgar($array, 'key'); // works. [1] -
Object (use rgobj or ->):
$value = rgobj($field, 'inputs'); // recommended. [2]
// or
$value = isset($field->inputs) ? $field->inputs : null; // direct object access. [3]
Alternative: cast object to array if you must use rgar:
$value = rgar((array)$obj, 'property');
References:
[1] rgar() docs.
[2] rgobj() docs.
[3] Gravity Forms v1.9 developer notes (object notation / field objects).
Fix the field_id targeting by accessing the field object property directly, not via rgar()
The review comment is accurate. The rgar() function is designed for arrays and will not properly read object properties. Since $field is confirmed to be an instance of \GC_OpenAI\Fields\Stream (an object), using rgar($field, 'id') will fail to access the id property. This means field_id targeting never matches.
The suggested fix is correct:
- Replace
rgar($field, 'id')with$field->id - Add type normalization and strict comparison as shown
- The form parameter concern is also valid (can be null, so form_id filtering is skipped when form is not provided)
Apply the exact diff from the review comment to fix the bug at lines 131–140.
🧰 Tools
🪛 GitHub Check: PHPCS (Files Changed)
[failure] 139-139:
Whitespace found at end of line
[failure] 131-131:
Whitespace found at end of line
[failure] 123-123:
Whitespace found at end of line
🤖 Prompt for AI Agents
In gc-openai/gcoai-stream-loading-text-animation.php around lines 119 to 141,
the field_id targeting uses rgar($field, 'id') which fails because $field is an
object; replace the rgar() call with direct object property access ($field->id),
normalize field_id(s) to an array and compare using strict comparison (===) to
ensure types match, and keep the existing guard that skips field_id filtering if
$this->args['field_id'] is null so behavior when $form is null remains
unchanged.
…stomizing the Steam field's loading text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (4)
gc-openai/gcoai-stream-loading-text-animation.php (4)
32-95: Fix trailing whitespace to pass PHPCS/pipeline checks.Lines 34, 45, and 95 contain trailing whitespace causing the pipeline to fail. Remove all spaces/tabs at the end of these lines.
Based on static analysis hints and pipeline failures.
Note: Unused parameters are required by the WordPress hook signature.
PHPMD flags
$field_valuesand$is_ajaxas unused, but they're part of thegform_register_init_scriptshook signature and cannot be removed. You can suppress this warning with a PHPDoc comment if desired:/** * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function register_init_script( $form, $field_values, $is_ajax ) {Based on static analysis hints.
97-107: Fix trailing whitespace to pass PHPCS/pipeline checks.Line 105 contains trailing whitespace causing the pipeline to fail. Remove all spaces/tabs at the end of this line.
Based on static analysis hints and pipeline failures.
109-133: Fix trailing whitespace to pass PHPCS/pipeline checks.Lines 110, 123, and 131 contain trailing whitespace causing PHPCS failures. Remove all spaces/tabs at the end of these lines.
Based on static analysis hints.
135-149: Fix trailing whitespace to pass PHPCS/pipeline checks.Lines 139 and 147 contain trailing whitespace causing PHPCS failures. Remove all spaces/tabs at the end of these lines.
Based on static analysis hints.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
gc-openai/gcoai-stream-loading-text-animation.php(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: PHP Lint (PR)
gc-openai/gcoai-stream-loading-text-animation.php
[error] 105-105: Whitespace found at end of line. Squiz.WhiteSpace.SuperfluousWhitespace.EndLine.
🪛 GitHub Check: PHPCS (Files Changed)
gc-openai/gcoai-stream-loading-text-animation.php
[failure] 165-165:
String "@Keyframes shimmer { 0% { background-position: -4rem top; } 70%, 100% { background-position: 12.5rem top; } }" does not require double quotes; use single quotes instead
[failure] 162-162:
String "@Keyframes spinner-stroke { 0% { stroke-dasharray: 0 150; stroke-dashoffset: 0; } 47.5% { stroke-dasharray: 42 150; stroke-dashoffset: -16; } 95%, 100% { stroke-dasharray: 42 150; stroke-dashoffset: -59; } } " does not require double quotes; use single quotes instead
[failure] 161-161:
String "@Keyframes spinner-rotation { 100% { transform: rotate(360deg); } } " does not require double quotes; use single quotes instead
[failure] 160-160:
String ".spinner-rotate circle { stroke-linecap: round; animation: spinner-stroke 1.5s ease-in-out infinite; } " does not require double quotes; use single quotes instead
[failure] 159-159:
String ".spinner-rotate { transform-origin: center; animation: spinner-rotation 2s linear infinite; } " does not require double quotes; use single quotes instead
[failure] 158-158:
String ".shimmer-spinner { flex-shrink: 0; } " does not require double quotes; use single quotes instead
[failure] 157-157:
String ".shimmer-wrapper { display: inline-flex; align-items: center; gap: 8px; } " does not require double quotes; use single quotes instead
[failure] 156-156:
Whitespace found at end of line
[failure] 105-105:
Whitespace found at end of line
🪛 PHPMD (2.15.0)
gc-openai/gcoai-stream-loading-text-animation.php
32-32: Avoid unused parameters such as '$field_values'. (undefined)
(UnusedFormalParameter)
32-32: Avoid unused parameters such as '$is_ajax'. (undefined)
(UnusedFormalParameter)
🔇 Additional comments (3)
gc-openai/gcoai-stream-loading-text-animation.php (3)
1-13: LGTM!The class structure is clean with appropriate property visibility and a static flag to prevent duplicate style output.
14-30: LGTM!The constructor properly initializes configurable arguments with sensible defaults and registers appropriate WordPress hooks for loading text filtering, script initialization, and style output.
169-180: LGTM!The default configuration provides sensible production-ready values with clear inline documentation for form targeting. The "Thinking..." text and subtle animation parameters create a polished loading experience.
…stomizing the Steam field's loading text.
Context
⛑️ Ticket(s): No active tickets currently, but I've helped multiple customers with similar requests in the past, so there's definitely demand for this.
Summary
Adds a customizable shimmer animation and optional rotating SVG spinner to the GCOAI's Stream field loading placeholder. This replaces the static "Loading..." text with a more polished, animated loading indicator.
This is especially helpful now that we support GPT-5 models with reasoning capabilities, which take significantly longer to respond. An animated loading indicator provides better user feedback during these longer wait times compared to static text.
Before:

After:
