From 45b8256faefb49e7764eb49384aebd5bc64700bc Mon Sep 17 00:00:00 2001
From: SebastianWiz <165194375+SebastianWiz@users.noreply.github.com>
Date: Fri, 14 Nov 2025 20:17:46 -0800
Subject: [PATCH 1/4] `gcoai-stream-loading-text-animation.php`: Added a new
snippet for customizing the Steam field's loading text.
---
.../gcoai-stream-loading-text-animation.php | 173 ++++++++++++++++++
1 file changed, 173 insertions(+)
create mode 100644 gc-openai/gcoai-stream-loading-text-animation.php
diff --git a/gc-openai/gcoai-stream-loading-text-animation.php b/gc-openai/gcoai-stream-loading-text-animation.php
new file mode 100644
index 000000000..e7aa02dcb
--- /dev/null
+++ b/gc-openai/gcoai-stream-loading-text-animation.php
@@ -0,0 +1,173 @@
+args = wp_parse_args( $args, array(
+ 'text' => 'Thinking...',
+ 'base_color' => '#000',
+ 'shimmer_color' => '#fff',
+ 'shimmer_duration' => '2.2s',
+ 'show_shimmer' => true,
+ 'show_spinner' => false,
+ 'spinner_size' => '24',
+ 'form_id' => null,
+ 'field_id' => null,
+ ) );
+
+ add_filter( 'gform_gcoai_field_loading_text', array( $this, 'filter_loading_text' ), 10, 3 );
+ add_action( 'gform_register_init_scripts', array( $this, 'register_init_script' ), 10, 2 );
+ }
+
+ public function register_init_script( $form, $is_ajax ) {
+ if ( empty( $form['id'] ) ) {
+ return;
+ }
+
+ // If form_id is specified, only run scripts on 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 ( ! in_array( $form['id'], $form_ids ) ) {
+ return;
+ }
+ }
+
+ $markup = $this->get_shimmer_markup();
+ $css = $this->get_styles_css();
+
+ ?>
+
+ args['show_spinner'] ) {
+ $spinner = sprintf(
+ '',
+ esc_attr( $this->args['spinner_size'] ),
+ esc_attr( $this->args['spinner_size'] ),
+ esc_attr( $this->args['base_color'] )
+ );
+ }
+
+ $text_class = $this->args['show_shimmer'] ? 'shimmer' : 'shimmer-text';
+
+ return sprintf(
+ '%s%s',
+ $spinner,
+ $text_class,
+ esc_html( $this->args['text'] )
+ );
+ }
+
+ 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();
+ }
+
+ private function get_styles_css() {
+ $base = esc_attr( $this->args['base_color'] );
+ $shimmer = esc_attr( $this->args['shimmer_color'] );
+ $dur = esc_attr( $this->args['shimmer_duration'] );
+
+ return
+ ".shimmer-wrapper { display: inline-flex; align-items: center; gap: 8px; } " .
+ ".shimmer-spinner { flex-shrink: 0; } " .
+ ".spinner-rotate { transform-origin: center; animation: spinner-rotation 2s linear infinite; } " .
+ ".spinner-rotate circle { stroke-linecap: round; animation: spinner-stroke 1.5s ease-in-out infinite; } " .
+ "@keyframes spinner-rotation { 100% { transform: rotate(360deg); } } " .
+ "@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; } } " .
+ ".shimmer-text { display: inline-block; color: {$base}; line-height: 1.2; } " .
+ ".shimmer { display: inline-block; color: {$base}; line-height: 1.2; background: {$base} linear-gradient(to left, {$base}, {$shimmer} 50%, {$base}); background-position: -4rem top; background-repeat: no-repeat; background-size: 4rem 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; animation: shimmer {$dur} infinite; } " .
+ "@keyframes shimmer { 0% { background-position: -4rem top; } 70%, 100% { background-position: 12.5rem top; } }";
+ }
+}
+
+# Configuration
+
+new GCOAI_Loading_Animation( array(
+ 'text' => 'Thinking...',
+ 'base_color' => '#292929',
+ 'shimmer_color' => '#fff',
+ 'shimmer_duration' => '2.2s',
+ 'show_shimmer' => true,
+ 'show_spinner' => true,
+ 'spinner_size' => '16',
+ // 'form_id' => 123, // Uncomment and set to target specific form(s): 123 or array( 18, 22, 35 )
+ // 'field_id' => 4, // Uncomment and set to target specific field(s): 5 or array( 5, 7, 12 )
+) );
From 2f63853703f9d71a7930a3555a86583b6bbaaabb Mon Sep 17 00:00:00 2001
From: SebastianWiz <165194375+SebastianWiz@users.noreply.github.com>
Date: Fri, 14 Nov 2025 21:20:05 -0800
Subject: [PATCH 2/4] `gcoai-stream-loading-text-animation.php`: Added a new
snippet for customizing the Steam field's loading text.
---
.../gcoai-stream-loading-text-animation.php | 125 +++++++++---------
1 file changed, 66 insertions(+), 59 deletions(-)
diff --git a/gc-openai/gcoai-stream-loading-text-animation.php b/gc-openai/gcoai-stream-loading-text-animation.php
index e7aa02dcb..0f9899450 100644
--- a/gc-openai/gcoai-stream-loading-text-animation.php
+++ b/gc-openai/gcoai-stream-loading-text-animation.php
@@ -2,13 +2,14 @@
/**
* Gravity Connect // OpenAI // Stream Loading Text Animation
*
- * Adds a customizable shimmer animation and rotating spinner icon to the Stream field's
- * loading placeholders. Replaces the static "Loading..." text with animated text and/or
+ * Adds a customizable shimmer animation and rotating spinner icon to the Stream field's
+ * loading placeholders. Replaces the static "Loading..." text with animated text and/or
* a rotating spinner icon.
*/
class GCOAI_Loading_Animation {
private $args;
+ private static $styles_output = false;
public function __construct( $args = array() ) {
$this->args = wp_parse_args( $args, array(
@@ -20,18 +21,19 @@ public function __construct( $args = array() ) {
'show_spinner' => false,
'spinner_size' => '24',
'form_id' => null,
- 'field_id' => null,
) );
add_filter( 'gform_gcoai_field_loading_text', array( $this, 'filter_loading_text' ), 10, 3 );
- add_action( 'gform_register_init_scripts', array( $this, 'register_init_script' ), 10, 2 );
+ add_action( 'gform_register_init_scripts', array( $this, 'register_init_script' ), 10, 3 );
+ add_action( 'wp_head', array( $this, 'output_styles' ) );
+ add_action( 'admin_head', array( $this, 'output_styles' ) );
}
- public function register_init_script( $form, $is_ajax ) {
+ public function register_init_script( $form, $field_values, $is_ajax ) {
if ( empty( $form['id'] ) ) {
return;
}
-
+
// If form_id is specified, only run scripts on 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'] );
@@ -42,57 +44,71 @@ public function register_init_script( $form, $is_ajax ) {
$markup = $this->get_shimmer_markup();
$css = $this->get_styles_css();
-
- ?>
-
- get_styles_css();
+ echo '';
+
+ self::$styles_output = true;
}
public function get_shimmer_markup() {
$spinner = '';
-
+
if ( $this->args['show_spinner'] ) {
$spinner = sprintf(
'