@capillarytech/creatives-library 9.0.34 → 9.0.35-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -169,12 +169,11 @@ export const SmsTraiEdit = (props) => {
169
169
  return traiDltEnabled || hasTraiDltFeature() || isRcsEditFlow;
170
170
  }, [isRcsSmsFallback, traiDltEnabled, isRcsEditFlow]);
171
171
 
172
- /**
173
- * RCS SMS fallback: always show character count vs TRAI max (`SMS_TRAI_CONTENT_MAX_LENGTH`).
174
- * Do not use `totalCharacters` ({smsCount} SMS via length/160) here: resolved template + variable
175
- * values can exceed one GSM segment while DLT still shows a single registered template — length/160
176
- * is only a rough segment hint and reads as “wrong SMS count” in campaigns.
177
- */
172
+
173
+ const [rcsFallbackVarSegmentModeActive, setRcsFallbackVarSegmentModeActive] = useState(false);
174
+ const useRcsFallbackVarSegmentForCurrentText = isRcsSmsFallback && rcsFallbackVarSegmentModeActive;
175
+
176
+
178
177
  const renderDescriptionCharacterCount = (className = "rcs-character-count") => (
179
178
  <CapLabel type="label1" className={className}>
180
179
  {formatMessage(messages.charactersCountLabel, {
@@ -196,18 +195,24 @@ export const SmsTraiEdit = (props) => {
196
195
  };
197
196
 
198
197
  const renderRcsFallbackMessage = (str = '') => {
199
- if (!useRcsFallbackVarSegment) {
198
+ if (!useRcsFallbackVarSegmentForCurrentText) {
200
199
  return (
201
200
  <CapRow className="rcs-create-template-message-input">
202
201
  <div className="rcs_text_area_wrapper">
203
- <TextArea
204
- id="rcs_fallback_message_textarea"
205
- autosize={{ minRows: 4, maxRows: 12 }}
206
- value={fallbackText}
207
- onChange={(e) => setFallbackText(e.target.value)}
208
- placeholder={formatMessage(rcsMessages.fallbackMsgPlaceholder)}
209
- data-testid="rcs_fallback_plain_text_area"
210
- />
202
+ <div className="var-segment-message-editor__var-slot">
203
+ <TextArea
204
+ id="rcs_fallback_message_textarea"
205
+ autosize={{ minRows: 1, maxRows: 3 }}
206
+ value={fallbackText}
207
+ onChange={(e) => setFallbackText(e.target.value)}
208
+ onBlur={() => {
209
+ const hasVarToken = (fallbackText.match(COMBINED_SMS_TEMPLATE_VAR_REGEX) || []).length > 0;
210
+ if (hasVarToken) setRcsFallbackVarSegmentModeActive(true);
211
+ }}
212
+ placeholder={formatMessage(rcsMessages.fallbackMsgPlaceholder)}
213
+ data-testid="rcs_fallback_plain_text_area"
214
+ />
215
+ </div>
211
216
  {renderDescriptionCharacterCount()}
212
217
  </div>
213
218
  </CapRow>
@@ -362,7 +367,9 @@ export const SmsTraiEdit = (props) => {
362
367
  const templateBase = get(activeTemplateSourceForInit, 'versions.base', {});
363
368
  const unicodeValidity = get(templateBase, 'unicode-validity', true);
364
369
  const templateMsg = get(activeTemplateSourceForInit, 'versions.base.sms-editor', '') || '';
365
- if (!useRcsFallbackVarSegment) {
370
+ const templateMsgHasVarToken = (templateMsg.match(COMBINED_SMS_TEMPLATE_VAR_REGEX) || []).length > 0;
371
+ setRcsFallbackVarSegmentModeActive(templateMsgHasVarToken);
372
+ if (!templateMsgHasVarToken) {
366
373
  setFallbackText(templateMsg);
367
374
  setFallbackVarMappedData({});
368
375
  setUpdatedSmsEditor(String(templateMsg).split(''));
@@ -429,7 +436,7 @@ export const SmsTraiEdit = (props) => {
429
436
 
430
437
  useEffect(() => {
431
438
  if (!isRcsSmsFallback) return;
432
- if (!useRcsFallbackVarSegment) {
439
+ if (!useRcsFallbackVarSegmentForCurrentText) {
433
440
  const plainFallbackSmsText = fallbackText || '';
434
441
  setUpdatedSmsEditor(plainFallbackSmsText.split(''));
435
442
  setTotalMessageLength(plainFallbackSmsText.length);
@@ -441,15 +448,17 @@ export const SmsTraiEdit = (props) => {
441
448
  );
442
449
  setUpdatedSmsEditor(resolvedFallbackDisplay.split(''));
443
450
  setTotalMessageLength(resolvedFallbackDisplay.length);
444
- }, [isRcsSmsFallback, useRcsFallbackVarSegment, fallbackText, fallbackVarMappedData]);
451
+ }, [isRcsSmsFallback, useRcsFallbackVarSegmentForCurrentText, fallbackText, fallbackVarMappedData]);
445
452
 
446
453
  useEffect(() => {
447
454
  if (!isRcsSmsFallback) return;
455
+ // Skip until hydration populates fallbackVarMappedData, or this wipes the parent's rcsSmsFallbackVarMapped before init restores it.
456
+ if (loading) return;
448
457
  if (typeof onRcsFallbackEditorStateChange !== 'function') return;
449
458
  onRcsFallbackEditorStateChange({
450
459
  rcsSmsFallbackVarMapped: fallbackVarMappedData || {},
451
460
  });
452
- }, [isRcsSmsFallback, fallbackVarMappedData, onRcsFallbackEditorStateChange]);
461
+ }, [isRcsSmsFallback, loading, fallbackVarMappedData, onRcsFallbackEditorStateChange]);
453
462
 
454
463
  useEffect(() => {
455
464
  if (!isRcsSmsFallback) return;
@@ -532,7 +541,7 @@ export const SmsTraiEdit = (props) => {
532
541
  // TRAI/DLT VarSegment: `validateIfTagClosed` only understands paired `{{…}}` and breaks on
533
542
  // legitimate `{#…#}` / mixed TRAI shapes (extra `{`/`}` counts). Do not tie Done to it;
534
543
  // slot completeness is enforced by `areAllRcsSmsFallbackVarSlotsFilled` on the RCS screen.
535
- if (useRcsFallbackVarSegment) {
544
+ if (useRcsFallbackVarSegmentForCurrentText) {
536
545
  tagValidationResponseRef.current = {};
537
546
  updateIsTagValidationError(false);
538
547
  return;
@@ -573,7 +582,7 @@ export const SmsTraiEdit = (props) => {
573
582
  tags,
574
583
  isRcsSmsFallback,
575
584
  isFullMode,
576
- useRcsFallbackVarSegment,
585
+ useRcsFallbackVarSegmentForCurrentText,
577
586
  fallbackText,
578
587
  fallbackVarMappedData,
579
588
  getDefaultTags,
@@ -712,7 +721,8 @@ export const SmsTraiEdit = (props) => {
712
721
  ...baseWithoutDerivedFields,
713
722
  'sms-editor': fallbackText || '',
714
723
  'unicode-validity': isUnicodeAllowed,
715
- ...(useRcsFallbackVarSegment && {
724
+ // Gate on useRcsFallbackVarSegmentForCurrentText (not the static DLT flag), or non-DLT var-token flows lose slot values on save.
725
+ ...(useRcsFallbackVarSegmentForCurrentText && {
716
726
  'rcs-sms-fallback-var-mapped': fallbackVarMappedData || {},
717
727
  }),
718
728
  };
@@ -778,8 +788,9 @@ export const SmsTraiEdit = (props) => {
778
788
 
779
789
  const onTagSelect = (data) => {
780
790
  if (isRcsSmsFallback) {
781
- if (!useRcsFallbackVarSegment) {
791
+ if (!useRcsFallbackVarSegmentForCurrentText) {
782
792
  setFallbackText((prev) => `${prev || ''}{{${data}}}`);
793
+ setRcsFallbackVarSegmentModeActive(true);
783
794
  return;
784
795
  }
785
796
  if (!fallbackFocusedId) return;
@@ -949,7 +960,7 @@ export const SmsTraiEdit = (props) => {
949
960
 
950
961
  const calculateTotalMessageLength = () => {
951
962
  if (isRcsSmsFallback) {
952
- if (useRcsFallbackVarSegment) {
963
+ if (useRcsFallbackVarSegmentForCurrentText) {
953
964
  const resolved = getFallbackResolvedContent(fallbackText || '', fallbackVarMappedData || {});
954
965
  setTotalMessageLength(resolved.length);
955
966
  } else {