ugcinc-render 1.8.103 → 1.8.104

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.
package/dist/index.js CHANGED
@@ -2878,7 +2878,7 @@ function ScreenshotAnimation({
2878
2878
  }
2879
2879
 
2880
2880
  // src/compositions/InstagramDmComposition/index.tsx
2881
- var import_react8 = require("react");
2881
+ var import_react9 = require("react");
2882
2882
  var import_remotion10 = require("remotion");
2883
2883
 
2884
2884
  // src/compositions/InstagramDmComposition/theme.ts
@@ -3524,6 +3524,7 @@ function IgMessageFooter({
3524
3524
  }
3525
3525
 
3526
3526
  // src/compositions/InstagramDmComposition/components/IgMessages.tsx
3527
+ var import_react8 = __toESM(require("react"));
3527
3528
  var import_remotion9 = require("remotion");
3528
3529
  var import_jsx_runtime11 = require("react/jsx-runtime");
3529
3530
  var DEFAULTS2 = {
@@ -3577,7 +3578,20 @@ function getInterpolatedSenderColor(bubbleCenter, messageAreaTop, messageAreaBot
3577
3578
  }
3578
3579
  }
3579
3580
  var FONT_FAMILY = '"SF Pro", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif';
3580
- function measureTextWidth(text, fontSize) {
3581
+ function calculateAutoWidthAndLines2({
3582
+ text,
3583
+ maxWidth,
3584
+ paddingLeft,
3585
+ paddingRight,
3586
+ fontSize
3587
+ }) {
3588
+ if (typeof document === "undefined") {
3589
+ return { width: maxWidth, lines: [text] };
3590
+ }
3591
+ const availableWidth = maxWidth - paddingLeft - paddingRight;
3592
+ if (availableWidth <= 0) {
3593
+ return { width: maxWidth, lines: [text] };
3594
+ }
3581
3595
  const measureSpan = document.createElement("span");
3582
3596
  measureSpan.style.cssText = `
3583
3597
  position: absolute;
@@ -3590,10 +3604,67 @@ function measureTextWidth(text, fontSize) {
3590
3604
  white-space: nowrap;
3591
3605
  `;
3592
3606
  document.body.appendChild(measureSpan);
3593
- measureSpan.textContent = text;
3594
- const width = measureSpan.getBoundingClientRect().width;
3607
+ const measureText = (textToMeasure) => {
3608
+ measureSpan.textContent = textToMeasure;
3609
+ return measureSpan.getBoundingClientRect().width;
3610
+ };
3611
+ const words = text.split(/(\s+)/);
3612
+ const lines = [];
3613
+ let currentLine = "";
3614
+ for (let i = 0; i < words.length; i++) {
3615
+ const word = words[i];
3616
+ if (word === "\n" || word === "\r\n") {
3617
+ if (currentLine) lines.push(currentLine);
3618
+ currentLine = "";
3619
+ continue;
3620
+ }
3621
+ if (!word) continue;
3622
+ if (/^\s+$/.test(word)) {
3623
+ if (currentLine) currentLine += word;
3624
+ continue;
3625
+ }
3626
+ const testLine = currentLine + word;
3627
+ const testWidth = measureText(testLine);
3628
+ const WRAP_TOLERANCE = 0.5;
3629
+ if (testWidth > availableWidth + WRAP_TOLERANCE && currentLine.trim()) {
3630
+ lines.push(currentLine.trimEnd());
3631
+ currentLine = word;
3632
+ const wordWidth = measureText(word);
3633
+ if (wordWidth > availableWidth) {
3634
+ let remainingWord = word;
3635
+ while (remainingWord) {
3636
+ let breakPoint = 1;
3637
+ for (let j = 1; j <= remainingWord.length; j++) {
3638
+ measureSpan.textContent = remainingWord.substring(0, j);
3639
+ if (measureSpan.getBoundingClientRect().width > availableWidth) {
3640
+ breakPoint = Math.max(1, j - 1);
3641
+ break;
3642
+ }
3643
+ breakPoint = j;
3644
+ }
3645
+ if (breakPoint >= remainingWord.length) {
3646
+ currentLine = remainingWord;
3647
+ break;
3648
+ } else {
3649
+ lines.push(remainingWord.substring(0, breakPoint));
3650
+ remainingWord = remainingWord.substring(breakPoint);
3651
+ }
3652
+ }
3653
+ }
3654
+ } else {
3655
+ currentLine = testLine;
3656
+ }
3657
+ }
3658
+ if (currentLine.trim()) lines.push(currentLine.trimEnd());
3659
+ if (lines.length === 0) lines.push("");
3660
+ let widestLineWidth = 0;
3661
+ for (const line of lines) {
3662
+ const lineWidth = measureText(line);
3663
+ widestLineWidth = Math.max(widestLineWidth, lineWidth);
3664
+ }
3595
3665
  document.body.removeChild(measureSpan);
3596
- return width;
3666
+ const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
3667
+ return { width: calculatedWidth, lines };
3597
3668
  }
3598
3669
  function IgMessages({
3599
3670
  messages = [],
@@ -3625,7 +3696,6 @@ function IgMessages({
3625
3696
  if (messages.length === 0) {
3626
3697
  return null;
3627
3698
  }
3628
- const maxTextWidth = bubbleMaxWidth - messagePaddingLeft - messagePaddingRight;
3629
3699
  const renderedMessages = [];
3630
3700
  let currentBottom = messageAreaBottom;
3631
3701
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -3648,22 +3718,16 @@ function IgMessages({
3648
3718
  gap = messageGapDifferentUser;
3649
3719
  }
3650
3720
  }
3651
- const actualTextWidth = measureTextWidth(message.text, messageFontSize);
3652
- const fitsOnSingleLine = actualTextWidth <= maxTextWidth;
3653
- let lineCount;
3654
- if (fitsOnSingleLine) {
3655
- lineCount = 1;
3656
- } else {
3657
- lineCount = Math.ceil(actualTextWidth / maxTextWidth);
3658
- }
3721
+ const { width: bubbleWidth, lines } = calculateAutoWidthAndLines2({
3722
+ text: message.text,
3723
+ maxWidth: bubbleMaxWidth,
3724
+ paddingLeft: messagePaddingLeft,
3725
+ paddingRight: messagePaddingRight,
3726
+ fontSize: messageFontSize
3727
+ });
3728
+ const lineCount = lines.length;
3659
3729
  const textHeight = lineCount * messageLineHeight;
3660
3730
  const bubbleHeight = textHeight + messagePaddingTop + messagePaddingBottom;
3661
- let bubbleWidth;
3662
- if (fitsOnSingleLine) {
3663
- bubbleWidth = actualTextWidth + messagePaddingLeft + messagePaddingRight;
3664
- } else {
3665
- bubbleWidth = bubbleMaxWidth;
3666
- }
3667
3731
  const bubbleBottom = currentBottom - gap;
3668
3732
  const bubbleTop = bubbleBottom - bubbleHeight;
3669
3733
  let bubbleLeft;
@@ -3679,6 +3743,7 @@ function IgMessages({
3679
3743
  left: bubbleLeft,
3680
3744
  width: bubbleWidth,
3681
3745
  height: bubbleHeight,
3746
+ lines,
3682
3747
  isFirstInGroup,
3683
3748
  isLastInGroup,
3684
3749
  isSingleMessage
@@ -3803,10 +3868,12 @@ function IgMessages({
3803
3868
  fontFamily: '"SF Pro", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif',
3804
3869
  fontWeight: 400,
3805
3870
  lineHeight: `${messageLineHeight}px`,
3806
- textAlign: "left",
3807
- wordBreak: "break-word"
3871
+ textAlign: "left"
3808
3872
  },
3809
- children: rm.message.text
3873
+ children: rm.lines.map((line, idx) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react8.default.Fragment, { children: [
3874
+ line,
3875
+ idx < rm.lines.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("br", {})
3876
+ ] }, idx))
3810
3877
  }
3811
3878
  )
3812
3879
  },
@@ -4003,20 +4070,20 @@ function InstagramDmComposition({
4003
4070
  profilePicGap
4004
4071
  }) {
4005
4072
  const clampedReferenceOpacity = Math.max(0, Math.min(100, referenceOpacity));
4006
- const [fontsLoaded, setFontsLoaded] = (0, import_react8.useState)(false);
4007
- const [zoom, setZoom] = (0, import_react8.useState)(100);
4008
- const [scrollX, setScrollX] = (0, import_react8.useState)(0);
4009
- const [scrollY, setScrollY] = (0, import_react8.useState)(0);
4010
- const [referenceVisible, setReferenceVisible] = (0, import_react8.useState)(true);
4011
- const handleZoomChange = (0, import_react8.useCallback)((newZoom, newScrollX, newScrollY) => {
4073
+ const [fontsLoaded, setFontsLoaded] = (0, import_react9.useState)(false);
4074
+ const [zoom, setZoom] = (0, import_react9.useState)(100);
4075
+ const [scrollX, setScrollX] = (0, import_react9.useState)(0);
4076
+ const [scrollY, setScrollY] = (0, import_react9.useState)(0);
4077
+ const [referenceVisible, setReferenceVisible] = (0, import_react9.useState)(true);
4078
+ const handleZoomChange = (0, import_react9.useCallback)((newZoom, newScrollX, newScrollY) => {
4012
4079
  setZoom(newZoom);
4013
4080
  setScrollX(newScrollX);
4014
4081
  setScrollY(newScrollY);
4015
4082
  }, []);
4016
- const handleToggleReference = (0, import_react8.useCallback)(() => {
4083
+ const handleToggleReference = (0, import_react9.useCallback)(() => {
4017
4084
  setReferenceVisible((prev) => !prev);
4018
4085
  }, []);
4019
- (0, import_react8.useEffect)(() => {
4086
+ (0, import_react9.useEffect)(() => {
4020
4087
  const interceptBeforeUnload = (e) => {
4021
4088
  e.stopImmediatePropagation();
4022
4089
  };
@@ -4035,7 +4102,7 @@ function InstagramDmComposition({
4035
4102
  window.removeEventListener("beforeunload", interceptBeforeUnload, { capture: true });
4036
4103
  };
4037
4104
  }, []);
4038
- (0, import_react8.useEffect)(() => {
4105
+ (0, import_react9.useEffect)(() => {
4039
4106
  const handle = (0, import_remotion10.delayRender)("Loading fonts...");
4040
4107
  preloadFonts().then(() => {
4041
4108
  setFontsLoaded(true);
@@ -4935,10 +5002,10 @@ function isValidCaptionPreset(name) {
4935
5002
  }
4936
5003
 
4937
5004
  // src/hooks/index.ts
4938
- var import_react9 = require("react");
5005
+ var import_react10 = require("react");
4939
5006
  function useFontsLoaded() {
4940
- const [loaded, setLoaded] = (0, import_react9.useState)(areFontsLoaded());
4941
- (0, import_react9.useEffect)(() => {
5007
+ const [loaded, setLoaded] = (0, import_react10.useState)(areFontsLoaded());
5008
+ (0, import_react10.useEffect)(() => {
4942
5009
  if (!loaded) {
4943
5010
  preloadFonts().then(() => setLoaded(true)).catch(console.error);
4944
5011
  }
@@ -4946,8 +5013,8 @@ function useFontsLoaded() {
4946
5013
  return loaded;
4947
5014
  }
4948
5015
  function useImageLoader(src) {
4949
- const [image, setImage] = (0, import_react9.useState)(null);
4950
- (0, import_react9.useEffect)(() => {
5016
+ const [image, setImage] = (0, import_react10.useState)(null);
5017
+ (0, import_react10.useEffect)(() => {
4951
5018
  if (!src) {
4952
5019
  setImage(null);
4953
5020
  return;
@@ -4967,9 +5034,9 @@ function useImageLoader(src) {
4967
5034
  return image;
4968
5035
  }
4969
5036
  function useImagePreloader(sources) {
4970
- const [images, setImages] = (0, import_react9.useState)({});
4971
- const [loaded, setLoaded] = (0, import_react9.useState)(false);
4972
- (0, import_react9.useEffect)(() => {
5037
+ const [images, setImages] = (0, import_react10.useState)({});
5038
+ const [loaded, setLoaded] = (0, import_react10.useState)(false);
5039
+ (0, import_react10.useEffect)(() => {
4973
5040
  const entries = Object.entries(sources);
4974
5041
  if (entries.length === 0) {
4975
5042
  setLoaded(true);
@@ -5007,7 +5074,7 @@ function useImagePreloader(sources) {
5007
5074
  return { loaded, images };
5008
5075
  }
5009
5076
  function useResolvedPositions(elements, textValues) {
5010
- return (0, import_react9.useMemo)(() => {
5077
+ return (0, import_react10.useMemo)(() => {
5011
5078
  if (elements.length === 0) {
5012
5079
  return { elements: [], errors: [] };
5013
5080
  }
package/dist/index.mjs CHANGED
@@ -2593,6 +2593,7 @@ function IgMessageFooter({
2593
2593
  }
2594
2594
 
2595
2595
  // src/compositions/InstagramDmComposition/components/IgMessages.tsx
2596
+ import React8 from "react";
2596
2597
  import { Img as Img5 } from "remotion";
2597
2598
  import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2598
2599
  var DEFAULTS2 = {
@@ -2646,7 +2647,20 @@ function getInterpolatedSenderColor(bubbleCenter, messageAreaTop, messageAreaBot
2646
2647
  }
2647
2648
  }
2648
2649
  var FONT_FAMILY = '"SF Pro", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif';
2649
- function measureTextWidth(text, fontSize) {
2650
+ function calculateAutoWidthAndLines2({
2651
+ text,
2652
+ maxWidth,
2653
+ paddingLeft,
2654
+ paddingRight,
2655
+ fontSize
2656
+ }) {
2657
+ if (typeof document === "undefined") {
2658
+ return { width: maxWidth, lines: [text] };
2659
+ }
2660
+ const availableWidth = maxWidth - paddingLeft - paddingRight;
2661
+ if (availableWidth <= 0) {
2662
+ return { width: maxWidth, lines: [text] };
2663
+ }
2650
2664
  const measureSpan = document.createElement("span");
2651
2665
  measureSpan.style.cssText = `
2652
2666
  position: absolute;
@@ -2659,10 +2673,67 @@ function measureTextWidth(text, fontSize) {
2659
2673
  white-space: nowrap;
2660
2674
  `;
2661
2675
  document.body.appendChild(measureSpan);
2662
- measureSpan.textContent = text;
2663
- const width = measureSpan.getBoundingClientRect().width;
2676
+ const measureText = (textToMeasure) => {
2677
+ measureSpan.textContent = textToMeasure;
2678
+ return measureSpan.getBoundingClientRect().width;
2679
+ };
2680
+ const words = text.split(/(\s+)/);
2681
+ const lines = [];
2682
+ let currentLine = "";
2683
+ for (let i = 0; i < words.length; i++) {
2684
+ const word = words[i];
2685
+ if (word === "\n" || word === "\r\n") {
2686
+ if (currentLine) lines.push(currentLine);
2687
+ currentLine = "";
2688
+ continue;
2689
+ }
2690
+ if (!word) continue;
2691
+ if (/^\s+$/.test(word)) {
2692
+ if (currentLine) currentLine += word;
2693
+ continue;
2694
+ }
2695
+ const testLine = currentLine + word;
2696
+ const testWidth = measureText(testLine);
2697
+ const WRAP_TOLERANCE = 0.5;
2698
+ if (testWidth > availableWidth + WRAP_TOLERANCE && currentLine.trim()) {
2699
+ lines.push(currentLine.trimEnd());
2700
+ currentLine = word;
2701
+ const wordWidth = measureText(word);
2702
+ if (wordWidth > availableWidth) {
2703
+ let remainingWord = word;
2704
+ while (remainingWord) {
2705
+ let breakPoint = 1;
2706
+ for (let j = 1; j <= remainingWord.length; j++) {
2707
+ measureSpan.textContent = remainingWord.substring(0, j);
2708
+ if (measureSpan.getBoundingClientRect().width > availableWidth) {
2709
+ breakPoint = Math.max(1, j - 1);
2710
+ break;
2711
+ }
2712
+ breakPoint = j;
2713
+ }
2714
+ if (breakPoint >= remainingWord.length) {
2715
+ currentLine = remainingWord;
2716
+ break;
2717
+ } else {
2718
+ lines.push(remainingWord.substring(0, breakPoint));
2719
+ remainingWord = remainingWord.substring(breakPoint);
2720
+ }
2721
+ }
2722
+ }
2723
+ } else {
2724
+ currentLine = testLine;
2725
+ }
2726
+ }
2727
+ if (currentLine.trim()) lines.push(currentLine.trimEnd());
2728
+ if (lines.length === 0) lines.push("");
2729
+ let widestLineWidth = 0;
2730
+ for (const line of lines) {
2731
+ const lineWidth = measureText(line);
2732
+ widestLineWidth = Math.max(widestLineWidth, lineWidth);
2733
+ }
2664
2734
  document.body.removeChild(measureSpan);
2665
- return width;
2735
+ const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
2736
+ return { width: calculatedWidth, lines };
2666
2737
  }
2667
2738
  function IgMessages({
2668
2739
  messages = [],
@@ -2694,7 +2765,6 @@ function IgMessages({
2694
2765
  if (messages.length === 0) {
2695
2766
  return null;
2696
2767
  }
2697
- const maxTextWidth = bubbleMaxWidth - messagePaddingLeft - messagePaddingRight;
2698
2768
  const renderedMessages = [];
2699
2769
  let currentBottom = messageAreaBottom;
2700
2770
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -2717,22 +2787,16 @@ function IgMessages({
2717
2787
  gap = messageGapDifferentUser;
2718
2788
  }
2719
2789
  }
2720
- const actualTextWidth = measureTextWidth(message.text, messageFontSize);
2721
- const fitsOnSingleLine = actualTextWidth <= maxTextWidth;
2722
- let lineCount;
2723
- if (fitsOnSingleLine) {
2724
- lineCount = 1;
2725
- } else {
2726
- lineCount = Math.ceil(actualTextWidth / maxTextWidth);
2727
- }
2790
+ const { width: bubbleWidth, lines } = calculateAutoWidthAndLines2({
2791
+ text: message.text,
2792
+ maxWidth: bubbleMaxWidth,
2793
+ paddingLeft: messagePaddingLeft,
2794
+ paddingRight: messagePaddingRight,
2795
+ fontSize: messageFontSize
2796
+ });
2797
+ const lineCount = lines.length;
2728
2798
  const textHeight = lineCount * messageLineHeight;
2729
2799
  const bubbleHeight = textHeight + messagePaddingTop + messagePaddingBottom;
2730
- let bubbleWidth;
2731
- if (fitsOnSingleLine) {
2732
- bubbleWidth = actualTextWidth + messagePaddingLeft + messagePaddingRight;
2733
- } else {
2734
- bubbleWidth = bubbleMaxWidth;
2735
- }
2736
2800
  const bubbleBottom = currentBottom - gap;
2737
2801
  const bubbleTop = bubbleBottom - bubbleHeight;
2738
2802
  let bubbleLeft;
@@ -2748,6 +2812,7 @@ function IgMessages({
2748
2812
  left: bubbleLeft,
2749
2813
  width: bubbleWidth,
2750
2814
  height: bubbleHeight,
2815
+ lines,
2751
2816
  isFirstInGroup,
2752
2817
  isLastInGroup,
2753
2818
  isSingleMessage
@@ -2872,10 +2937,12 @@ function IgMessages({
2872
2937
  fontFamily: '"SF Pro", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif',
2873
2938
  fontWeight: 400,
2874
2939
  lineHeight: `${messageLineHeight}px`,
2875
- textAlign: "left",
2876
- wordBreak: "break-word"
2940
+ textAlign: "left"
2877
2941
  },
2878
- children: rm.message.text
2942
+ children: rm.lines.map((line, idx) => /* @__PURE__ */ jsxs9(React8.Fragment, { children: [
2943
+ line,
2944
+ idx < rm.lines.length - 1 && /* @__PURE__ */ jsx11("br", {})
2945
+ ] }, idx))
2879
2946
  }
2880
2947
  )
2881
2948
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.8.103",
3
+ "version": "1.8.104",
4
4
  "description": "Unified rendering package for UGC Inc - shared types, components, and compositions for pixel-perfect client/server rendering",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",