ugcinc-render 1.8.160 → 1.8.161

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.d.mts CHANGED
@@ -1085,9 +1085,11 @@ interface IMessageDmCompositionProps {
1085
1085
  bubbleTextColor?: string;
1086
1086
  bubbleTextFontSize?: number;
1087
1087
  bubbleTextLetterSpacing?: number;
1088
+ bubbleTextLineHeight?: number;
1088
1089
  bubbleBorderRadius?: number;
1089
1090
  bubblePaddingX?: number;
1090
1091
  bubblePaddingY?: number;
1092
+ bubbleMaxWidth?: number;
1091
1093
  messageGapSameUser?: number;
1092
1094
  messageGapDifferentUser?: number;
1093
1095
  sentMessagePaddingLeft?: number;
package/dist/index.d.ts CHANGED
@@ -1085,9 +1085,11 @@ interface IMessageDmCompositionProps {
1085
1085
  bubbleTextColor?: string;
1086
1086
  bubbleTextFontSize?: number;
1087
1087
  bubbleTextLetterSpacing?: number;
1088
+ bubbleTextLineHeight?: number;
1088
1089
  bubbleBorderRadius?: number;
1089
1090
  bubblePaddingX?: number;
1090
1091
  bubblePaddingY?: number;
1092
+ bubbleMaxWidth?: number;
1091
1093
  messageGapSameUser?: number;
1092
1094
  messageGapDifferentUser?: number;
1093
1095
  sentMessagePaddingLeft?: number;
package/dist/index.js CHANGED
@@ -5260,25 +5260,118 @@ var MESSAGE_DEFAULTS2 = {
5260
5260
  bubbleTextColor: "#ffffff",
5261
5261
  bubbleTextFontSize: 48,
5262
5262
  bubbleTextLetterSpacing: 0.5,
5263
+ bubbleTextLineHeight: 1.3,
5263
5264
  bubbleBorderRadius: 40,
5264
- bubblePaddingX: 30,
5265
+ bubblePaddingX: 39,
5265
5266
  bubblePaddingY: 20,
5266
5267
  messageGapSameUser: 8,
5267
5268
  messageGapDifferentUser: 36,
5268
5269
  sentMessagePaddingLeft: 200,
5269
5270
  sentMessagePaddingRight: 28,
5270
- receivedMessagePaddingLeft: 28,
5271
- receivedMessagePaddingRight: 200,
5272
- multiLineSentMessagePaddingLeft: 31,
5273
- multiLineReceivedMessagePaddingRight: 31,
5274
- messagesAnchorY: 2340,
5271
+ receivedMessagePaddingLeft: 48,
5272
+ receivedMessagePaddingRight: 270,
5273
+ messagesAnchorY: 2310,
5274
+ bubbleMaxWidth: 900,
5275
5275
  // Image message defaults
5276
5276
  imageMaxWidth: 600,
5277
5277
  imageAspectRatio: 1,
5278
- // width / height
5279
5278
  imageBorderRadius: 30,
5280
5279
  imageGapToText: 8
5281
5280
  };
5281
+ var FONT_FAMILY2 = getFontFamily("apple");
5282
+ function calculateAutoWidthAndLines3({
5283
+ text,
5284
+ maxWidth,
5285
+ paddingLeft,
5286
+ paddingRight,
5287
+ fontSize,
5288
+ letterSpacing
5289
+ }) {
5290
+ if (typeof document === "undefined") {
5291
+ return { width: maxWidth, lines: [text] };
5292
+ }
5293
+ const availableWidth = maxWidth - paddingLeft - paddingRight;
5294
+ if (availableWidth <= 0) {
5295
+ return { width: maxWidth, lines: [text] };
5296
+ }
5297
+ const measureSpan = document.createElement("span");
5298
+ measureSpan.style.cssText = `
5299
+ position: absolute;
5300
+ visibility: hidden;
5301
+ pointer-events: none;
5302
+ font-family: ${FONT_FAMILY2};
5303
+ font-size: ${fontSize}px;
5304
+ font-weight: normal;
5305
+ letter-spacing: ${letterSpacing}px;
5306
+ white-space: nowrap;
5307
+ `;
5308
+ document.body.appendChild(measureSpan);
5309
+ const measureText = (textToMeasure) => {
5310
+ measureSpan.textContent = textToMeasure;
5311
+ return measureSpan.getBoundingClientRect().width;
5312
+ };
5313
+ const words = text.split(/(\s+)/);
5314
+ const lines = [];
5315
+ let currentLine = "";
5316
+ for (let i = 0; i < words.length; i++) {
5317
+ const word = words[i];
5318
+ if (word === "\n" || word === "\r\n") {
5319
+ if (currentLine) lines.push(currentLine);
5320
+ currentLine = "";
5321
+ continue;
5322
+ }
5323
+ if (!word) continue;
5324
+ if (/^\s+$/.test(word)) {
5325
+ if (currentLine) currentLine += word;
5326
+ continue;
5327
+ }
5328
+ const testLine = currentLine + word;
5329
+ const testWidth = measureText(testLine);
5330
+ const WRAP_TOLERANCE = 0.5;
5331
+ if (testWidth > availableWidth + WRAP_TOLERANCE) {
5332
+ if (currentLine.trim()) {
5333
+ lines.push(currentLine.trimEnd());
5334
+ currentLine = "";
5335
+ }
5336
+ const wordWidth = measureText(word);
5337
+ if (wordWidth > availableWidth) {
5338
+ let remainingWord = word;
5339
+ while (remainingWord) {
5340
+ let breakPoint = 1;
5341
+ for (let j = 1; j <= remainingWord.length; j++) {
5342
+ measureSpan.textContent = remainingWord.substring(0, j);
5343
+ if (measureSpan.getBoundingClientRect().width > availableWidth) {
5344
+ breakPoint = Math.max(1, j - 1);
5345
+ break;
5346
+ }
5347
+ breakPoint = j;
5348
+ }
5349
+ if (breakPoint >= remainingWord.length) {
5350
+ currentLine = remainingWord;
5351
+ break;
5352
+ } else {
5353
+ lines.push(remainingWord.substring(0, breakPoint));
5354
+ remainingWord = remainingWord.substring(breakPoint);
5355
+ }
5356
+ }
5357
+ } else {
5358
+ currentLine = word;
5359
+ }
5360
+ } else {
5361
+ currentLine = testLine;
5362
+ }
5363
+ }
5364
+ if (currentLine.trim()) lines.push(currentLine.trimEnd());
5365
+ if (lines.length === 0) lines.push("");
5366
+ let widestLineWidth = 0;
5367
+ for (const line of lines) {
5368
+ const lineWidth = measureText(line);
5369
+ widestLineWidth = Math.max(widestLineWidth, lineWidth);
5370
+ }
5371
+ document.body.removeChild(measureSpan);
5372
+ const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
5373
+ return { width: calculatedWidth, lines };
5374
+ }
5282
5375
  function calculateMessagePositions2(props) {
5283
5376
  const messages = props.messages ?? [];
5284
5377
  if (messages.length === 0) return [];
@@ -5286,13 +5379,12 @@ function calculateMessagePositions2(props) {
5286
5379
  const messagesAnchorY = props.messagesAnchorY ?? MESSAGE_DEFAULTS2.messagesAnchorY;
5287
5380
  const messageGapSameUser = props.messageGapSameUser ?? MESSAGE_DEFAULTS2.messageGapSameUser;
5288
5381
  const messageGapDifferentUser = props.messageGapDifferentUser ?? MESSAGE_DEFAULTS2.messageGapDifferentUser;
5289
- const sentMessagePaddingLeft = props.sentMessagePaddingLeft ?? MESSAGE_DEFAULTS2.sentMessagePaddingLeft;
5290
- const sentMessagePaddingRight = props.sentMessagePaddingRight ?? MESSAGE_DEFAULTS2.sentMessagePaddingRight;
5291
- const receivedMessagePaddingLeft = props.receivedMessagePaddingLeft ?? MESSAGE_DEFAULTS2.receivedMessagePaddingLeft;
5292
- const receivedMessagePaddingRight = props.receivedMessagePaddingRight ?? MESSAGE_DEFAULTS2.receivedMessagePaddingRight;
5293
5382
  const bubblePaddingX = props.bubblePaddingX ?? MESSAGE_DEFAULTS2.bubblePaddingX;
5294
5383
  const bubblePaddingY = props.bubblePaddingY ?? MESSAGE_DEFAULTS2.bubblePaddingY;
5295
5384
  const bubbleTextFontSize = props.bubbleTextFontSize ?? MESSAGE_DEFAULTS2.bubbleTextFontSize;
5385
+ const bubbleTextLetterSpacing = props.bubbleTextLetterSpacing ?? MESSAGE_DEFAULTS2.bubbleTextLetterSpacing;
5386
+ const bubbleTextLineHeight = props.bubbleTextLineHeight ?? MESSAGE_DEFAULTS2.bubbleTextLineHeight;
5387
+ const bubbleMaxWidth = props.bubbleMaxWidth ?? MESSAGE_DEFAULTS2.bubbleMaxWidth;
5296
5388
  const imageMaxWidth = MESSAGE_DEFAULTS2.imageMaxWidth;
5297
5389
  const imageAspectRatio = MESSAGE_DEFAULTS2.imageAspectRatio;
5298
5390
  const imageGapToText = MESSAGE_DEFAULTS2.imageGapToText;
@@ -5301,47 +5393,41 @@ function calculateMessagePositions2(props) {
5301
5393
  for (let i = messages.length - 1; i >= 0; i--) {
5302
5394
  const msg = messages[i];
5303
5395
  if (!msg) continue;
5304
- const isSender = msg.sender === "user";
5305
- const paddingLeft = isSender ? sentMessagePaddingLeft : receivedMessagePaddingLeft;
5306
- const paddingRight = isSender ? sentMessagePaddingRight : receivedMessagePaddingRight;
5307
- const maxBubbleWidth = canvasWidth - paddingLeft - paddingRight;
5308
- const maxTextWidth = maxBubbleWidth - bubblePaddingX * 2;
5309
- const charWidth = bubbleTextFontSize * 0.5;
5310
- const lineHeight = bubbleTextFontSize * 1.3;
5311
- const textWidth = Math.min(msg.text.length * charWidth, maxTextWidth);
5312
- const numLines = Math.ceil(msg.text.length * charWidth / maxTextWidth);
5313
- const textHeight = numLines * lineHeight;
5314
- const bubbleWidth = textWidth + bubblePaddingX * 2;
5396
+ const { lines } = calculateAutoWidthAndLines3({
5397
+ text: msg.text,
5398
+ maxWidth: bubbleMaxWidth,
5399
+ paddingLeft: bubblePaddingX,
5400
+ paddingRight: bubblePaddingX,
5401
+ fontSize: bubbleTextFontSize,
5402
+ letterSpacing: bubbleTextLetterSpacing
5403
+ });
5404
+ const lineCount = lines.length;
5405
+ const lineHeightPx = bubbleTextFontSize * bubbleTextLineHeight;
5406
+ const textHeight = lineCount * lineHeightPx;
5315
5407
  const bubbleHeight = textHeight + bubblePaddingY * 2;
5316
5408
  let imageWidth;
5317
5409
  let imageHeight;
5318
5410
  let imageY;
5319
- let totalHeight = bubbleHeight;
5320
5411
  if (msg.imageUrl) {
5321
- imageWidth = Math.min(imageMaxWidth, maxBubbleWidth);
5412
+ imageWidth = Math.min(imageMaxWidth, bubbleMaxWidth);
5322
5413
  imageHeight = imageWidth / imageAspectRatio;
5323
- totalHeight = imageHeight + imageGapToText + bubbleHeight;
5324
5414
  }
5325
- const x = isSender ? canvasWidth - paddingRight - bubbleWidth : paddingLeft;
5326
- const y = currentY - bubbleHeight;
5415
+ const bubbleTop = currentY - bubbleHeight;
5327
5416
  if (msg.imageUrl && imageHeight) {
5328
- imageY = y - imageGapToText - imageHeight;
5417
+ imageY = bubbleTop - imageGapToText - imageHeight;
5329
5418
  }
5330
5419
  calculatedMessages.unshift({
5331
5420
  message: msg,
5332
- x,
5333
- y,
5334
- width: bubbleWidth,
5421
+ top: bubbleTop,
5335
5422
  height: bubbleHeight,
5336
- textWidth,
5337
- textHeight,
5423
+ lines,
5338
5424
  imageWidth,
5339
5425
  imageHeight,
5340
5426
  imageY
5341
5427
  });
5342
5428
  const prevMsg = i > 0 ? messages[i - 1] : null;
5343
5429
  const gap = prevMsg && prevMsg.sender === msg.sender && !msg.groupWithPrevious ? messageGapSameUser : messageGapDifferentUser;
5344
- const topOfMessage = msg.imageUrl && imageY !== void 0 ? imageY : y;
5430
+ const topOfMessage = msg.imageUrl && imageY !== void 0 ? imageY : bubbleTop;
5345
5431
  currentY = topOfMessage - gap;
5346
5432
  }
5347
5433
  return calculatedMessages;
@@ -5354,14 +5440,18 @@ function generateMessageElements2(props, calculatedMessages) {
5354
5440
  const bubbleTextColor = props.bubbleTextColor ?? MESSAGE_DEFAULTS2.bubbleTextColor;
5355
5441
  const bubbleTextFontSize = props.bubbleTextFontSize ?? MESSAGE_DEFAULTS2.bubbleTextFontSize;
5356
5442
  const bubbleTextLetterSpacing = props.bubbleTextLetterSpacing ?? MESSAGE_DEFAULTS2.bubbleTextLetterSpacing;
5443
+ const bubbleTextLineHeight = props.bubbleTextLineHeight ?? MESSAGE_DEFAULTS2.bubbleTextLineHeight;
5357
5444
  const bubbleBorderRadius = props.bubbleBorderRadius ?? MESSAGE_DEFAULTS2.bubbleBorderRadius;
5358
5445
  const bubblePaddingX = props.bubblePaddingX ?? MESSAGE_DEFAULTS2.bubblePaddingX;
5359
5446
  const bubblePaddingY = props.bubblePaddingY ?? MESSAGE_DEFAULTS2.bubblePaddingY;
5447
+ const bubbleMaxWidth = props.bubbleMaxWidth ?? MESSAGE_DEFAULTS2.bubbleMaxWidth;
5360
5448
  const imageBorderRadius = MESSAGE_DEFAULTS2.imageBorderRadius;
5361
5449
  const sentMessagePaddingRight = props.sentMessagePaddingRight ?? MESSAGE_DEFAULTS2.sentMessagePaddingRight;
5362
5450
  const receivedMessagePaddingLeft = props.receivedMessagePaddingLeft ?? MESSAGE_DEFAULTS2.receivedMessagePaddingLeft;
5363
- for (const calc of calculatedMessages) {
5364
- const { message, x, y, width, height, imageWidth, imageHeight, imageY } = calc;
5451
+ const senderBubbleRight = canvasWidth - sentMessagePaddingRight;
5452
+ for (let i = 0; i < calculatedMessages.length; i++) {
5453
+ const calc = calculatedMessages[i];
5454
+ const { message, top, height, lines, imageWidth, imageHeight, imageY } = calc;
5365
5455
  const isSender = message.sender === "user";
5366
5456
  const bubbleColor = isSender ? senderBubbleColor : recipientBubbleColor;
5367
5457
  if (message.imageUrl && imageWidth && imageHeight && imageY !== void 0) {
@@ -5379,35 +5469,39 @@ function generateMessageElements2(props, calculatedMessages) {
5379
5469
  objectFit: "cover"
5380
5470
  });
5381
5471
  }
5472
+ const elementX = isSender ? senderBubbleRight - bubbleMaxWidth : receivedMessagePaddingLeft;
5473
+ const textContent = lines.join("\n");
5382
5474
  elements.push({
5383
- id: `bubble-${message.id}`,
5475
+ id: `message-${message.id}`,
5384
5476
  type: "text",
5385
- x,
5386
- y,
5387
- width,
5477
+ x: elementX,
5478
+ y: top,
5479
+ width: bubbleMaxWidth,
5388
5480
  height,
5389
- zIndex: 10,
5390
- text: "",
5391
- backgroundColor: bubbleColor,
5392
- backgroundOpacity: 100,
5393
- borderRadius: bubbleBorderRadius
5394
- });
5395
- elements.push({
5396
- id: `text-${message.id}`,
5397
- type: "text",
5398
- x: x + bubblePaddingX,
5399
- y: y + bubblePaddingY,
5400
- width: width - bubblePaddingX * 2,
5401
- height: height - bubblePaddingY * 2,
5402
- zIndex: 11,
5403
- text: message.text,
5481
+ zIndex: 10 + i,
5482
+ text: textContent,
5404
5483
  font: "apple",
5405
5484
  fontWeight: 400,
5406
5485
  fontSize: bubbleTextFontSize,
5407
5486
  letterSpacing: bubbleTextLetterSpacing,
5487
+ lineHeight: bubbleTextLineHeight,
5408
5488
  color: bubbleTextColor,
5409
5489
  textAlign: "left",
5410
- verticalAlign: "top"
5490
+ verticalAlign: "middle",
5491
+ backgroundColor: bubbleColor,
5492
+ backgroundOpacity: 100,
5493
+ backgroundBorderRadius: {
5494
+ topLeft: bubbleBorderRadius,
5495
+ topRight: bubbleBorderRadius,
5496
+ bottomLeft: bubbleBorderRadius,
5497
+ bottomRight: bubbleBorderRadius
5498
+ },
5499
+ paddingTop: bubblePaddingY,
5500
+ paddingRight: bubblePaddingX,
5501
+ paddingBottom: bubblePaddingY,
5502
+ paddingLeft: bubblePaddingX,
5503
+ autoWidth: true,
5504
+ boxAlign: isSender ? "right" : "left"
5411
5505
  });
5412
5506
  }
5413
5507
  return elements;
@@ -6713,9 +6807,11 @@ var iMessageDmPropsSchema = import_zod.z.object({
6713
6807
  bubbleTextColor: import_zod.z.string().optional(),
6714
6808
  bubbleTextFontSize: import_zod.z.number().optional(),
6715
6809
  bubbleTextLetterSpacing: import_zod.z.number().optional(),
6810
+ bubbleTextLineHeight: import_zod.z.number().optional(),
6716
6811
  bubbleBorderRadius: import_zod.z.number().optional(),
6717
6812
  bubblePaddingX: import_zod.z.number().optional(),
6718
6813
  bubblePaddingY: import_zod.z.number().optional(),
6814
+ bubbleMaxWidth: import_zod.z.number().optional(),
6719
6815
  messageGapSameUser: import_zod.z.number().optional(),
6720
6816
  messageGapDifferentUser: import_zod.z.number().optional(),
6721
6817
  sentMessagePaddingLeft: import_zod.z.number().optional(),
package/dist/index.mjs CHANGED
@@ -4306,25 +4306,118 @@ var MESSAGE_DEFAULTS2 = {
4306
4306
  bubbleTextColor: "#ffffff",
4307
4307
  bubbleTextFontSize: 48,
4308
4308
  bubbleTextLetterSpacing: 0.5,
4309
+ bubbleTextLineHeight: 1.3,
4309
4310
  bubbleBorderRadius: 40,
4310
- bubblePaddingX: 30,
4311
+ bubblePaddingX: 39,
4311
4312
  bubblePaddingY: 20,
4312
4313
  messageGapSameUser: 8,
4313
4314
  messageGapDifferentUser: 36,
4314
4315
  sentMessagePaddingLeft: 200,
4315
4316
  sentMessagePaddingRight: 28,
4316
- receivedMessagePaddingLeft: 28,
4317
- receivedMessagePaddingRight: 200,
4318
- multiLineSentMessagePaddingLeft: 31,
4319
- multiLineReceivedMessagePaddingRight: 31,
4320
- messagesAnchorY: 2340,
4317
+ receivedMessagePaddingLeft: 48,
4318
+ receivedMessagePaddingRight: 270,
4319
+ messagesAnchorY: 2310,
4320
+ bubbleMaxWidth: 900,
4321
4321
  // Image message defaults
4322
4322
  imageMaxWidth: 600,
4323
4323
  imageAspectRatio: 1,
4324
- // width / height
4325
4324
  imageBorderRadius: 30,
4326
4325
  imageGapToText: 8
4327
4326
  };
4327
+ var FONT_FAMILY2 = getFontFamily("apple");
4328
+ function calculateAutoWidthAndLines3({
4329
+ text,
4330
+ maxWidth,
4331
+ paddingLeft,
4332
+ paddingRight,
4333
+ fontSize,
4334
+ letterSpacing
4335
+ }) {
4336
+ if (typeof document === "undefined") {
4337
+ return { width: maxWidth, lines: [text] };
4338
+ }
4339
+ const availableWidth = maxWidth - paddingLeft - paddingRight;
4340
+ if (availableWidth <= 0) {
4341
+ return { width: maxWidth, lines: [text] };
4342
+ }
4343
+ const measureSpan = document.createElement("span");
4344
+ measureSpan.style.cssText = `
4345
+ position: absolute;
4346
+ visibility: hidden;
4347
+ pointer-events: none;
4348
+ font-family: ${FONT_FAMILY2};
4349
+ font-size: ${fontSize}px;
4350
+ font-weight: normal;
4351
+ letter-spacing: ${letterSpacing}px;
4352
+ white-space: nowrap;
4353
+ `;
4354
+ document.body.appendChild(measureSpan);
4355
+ const measureText = (textToMeasure) => {
4356
+ measureSpan.textContent = textToMeasure;
4357
+ return measureSpan.getBoundingClientRect().width;
4358
+ };
4359
+ const words = text.split(/(\s+)/);
4360
+ const lines = [];
4361
+ let currentLine = "";
4362
+ for (let i = 0; i < words.length; i++) {
4363
+ const word = words[i];
4364
+ if (word === "\n" || word === "\r\n") {
4365
+ if (currentLine) lines.push(currentLine);
4366
+ currentLine = "";
4367
+ continue;
4368
+ }
4369
+ if (!word) continue;
4370
+ if (/^\s+$/.test(word)) {
4371
+ if (currentLine) currentLine += word;
4372
+ continue;
4373
+ }
4374
+ const testLine = currentLine + word;
4375
+ const testWidth = measureText(testLine);
4376
+ const WRAP_TOLERANCE = 0.5;
4377
+ if (testWidth > availableWidth + WRAP_TOLERANCE) {
4378
+ if (currentLine.trim()) {
4379
+ lines.push(currentLine.trimEnd());
4380
+ currentLine = "";
4381
+ }
4382
+ const wordWidth = measureText(word);
4383
+ if (wordWidth > availableWidth) {
4384
+ let remainingWord = word;
4385
+ while (remainingWord) {
4386
+ let breakPoint = 1;
4387
+ for (let j = 1; j <= remainingWord.length; j++) {
4388
+ measureSpan.textContent = remainingWord.substring(0, j);
4389
+ if (measureSpan.getBoundingClientRect().width > availableWidth) {
4390
+ breakPoint = Math.max(1, j - 1);
4391
+ break;
4392
+ }
4393
+ breakPoint = j;
4394
+ }
4395
+ if (breakPoint >= remainingWord.length) {
4396
+ currentLine = remainingWord;
4397
+ break;
4398
+ } else {
4399
+ lines.push(remainingWord.substring(0, breakPoint));
4400
+ remainingWord = remainingWord.substring(breakPoint);
4401
+ }
4402
+ }
4403
+ } else {
4404
+ currentLine = word;
4405
+ }
4406
+ } else {
4407
+ currentLine = testLine;
4408
+ }
4409
+ }
4410
+ if (currentLine.trim()) lines.push(currentLine.trimEnd());
4411
+ if (lines.length === 0) lines.push("");
4412
+ let widestLineWidth = 0;
4413
+ for (const line of lines) {
4414
+ const lineWidth = measureText(line);
4415
+ widestLineWidth = Math.max(widestLineWidth, lineWidth);
4416
+ }
4417
+ document.body.removeChild(measureSpan);
4418
+ const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
4419
+ return { width: calculatedWidth, lines };
4420
+ }
4328
4421
  function calculateMessagePositions2(props) {
4329
4422
  const messages = props.messages ?? [];
4330
4423
  if (messages.length === 0) return [];
@@ -4332,13 +4425,12 @@ function calculateMessagePositions2(props) {
4332
4425
  const messagesAnchorY = props.messagesAnchorY ?? MESSAGE_DEFAULTS2.messagesAnchorY;
4333
4426
  const messageGapSameUser = props.messageGapSameUser ?? MESSAGE_DEFAULTS2.messageGapSameUser;
4334
4427
  const messageGapDifferentUser = props.messageGapDifferentUser ?? MESSAGE_DEFAULTS2.messageGapDifferentUser;
4335
- const sentMessagePaddingLeft = props.sentMessagePaddingLeft ?? MESSAGE_DEFAULTS2.sentMessagePaddingLeft;
4336
- const sentMessagePaddingRight = props.sentMessagePaddingRight ?? MESSAGE_DEFAULTS2.sentMessagePaddingRight;
4337
- const receivedMessagePaddingLeft = props.receivedMessagePaddingLeft ?? MESSAGE_DEFAULTS2.receivedMessagePaddingLeft;
4338
- const receivedMessagePaddingRight = props.receivedMessagePaddingRight ?? MESSAGE_DEFAULTS2.receivedMessagePaddingRight;
4339
4428
  const bubblePaddingX = props.bubblePaddingX ?? MESSAGE_DEFAULTS2.bubblePaddingX;
4340
4429
  const bubblePaddingY = props.bubblePaddingY ?? MESSAGE_DEFAULTS2.bubblePaddingY;
4341
4430
  const bubbleTextFontSize = props.bubbleTextFontSize ?? MESSAGE_DEFAULTS2.bubbleTextFontSize;
4431
+ const bubbleTextLetterSpacing = props.bubbleTextLetterSpacing ?? MESSAGE_DEFAULTS2.bubbleTextLetterSpacing;
4432
+ const bubbleTextLineHeight = props.bubbleTextLineHeight ?? MESSAGE_DEFAULTS2.bubbleTextLineHeight;
4433
+ const bubbleMaxWidth = props.bubbleMaxWidth ?? MESSAGE_DEFAULTS2.bubbleMaxWidth;
4342
4434
  const imageMaxWidth = MESSAGE_DEFAULTS2.imageMaxWidth;
4343
4435
  const imageAspectRatio = MESSAGE_DEFAULTS2.imageAspectRatio;
4344
4436
  const imageGapToText = MESSAGE_DEFAULTS2.imageGapToText;
@@ -4347,47 +4439,41 @@ function calculateMessagePositions2(props) {
4347
4439
  for (let i = messages.length - 1; i >= 0; i--) {
4348
4440
  const msg = messages[i];
4349
4441
  if (!msg) continue;
4350
- const isSender = msg.sender === "user";
4351
- const paddingLeft = isSender ? sentMessagePaddingLeft : receivedMessagePaddingLeft;
4352
- const paddingRight = isSender ? sentMessagePaddingRight : receivedMessagePaddingRight;
4353
- const maxBubbleWidth = canvasWidth - paddingLeft - paddingRight;
4354
- const maxTextWidth = maxBubbleWidth - bubblePaddingX * 2;
4355
- const charWidth = bubbleTextFontSize * 0.5;
4356
- const lineHeight = bubbleTextFontSize * 1.3;
4357
- const textWidth = Math.min(msg.text.length * charWidth, maxTextWidth);
4358
- const numLines = Math.ceil(msg.text.length * charWidth / maxTextWidth);
4359
- const textHeight = numLines * lineHeight;
4360
- const bubbleWidth = textWidth + bubblePaddingX * 2;
4442
+ const { lines } = calculateAutoWidthAndLines3({
4443
+ text: msg.text,
4444
+ maxWidth: bubbleMaxWidth,
4445
+ paddingLeft: bubblePaddingX,
4446
+ paddingRight: bubblePaddingX,
4447
+ fontSize: bubbleTextFontSize,
4448
+ letterSpacing: bubbleTextLetterSpacing
4449
+ });
4450
+ const lineCount = lines.length;
4451
+ const lineHeightPx = bubbleTextFontSize * bubbleTextLineHeight;
4452
+ const textHeight = lineCount * lineHeightPx;
4361
4453
  const bubbleHeight = textHeight + bubblePaddingY * 2;
4362
4454
  let imageWidth;
4363
4455
  let imageHeight;
4364
4456
  let imageY;
4365
- let totalHeight = bubbleHeight;
4366
4457
  if (msg.imageUrl) {
4367
- imageWidth = Math.min(imageMaxWidth, maxBubbleWidth);
4458
+ imageWidth = Math.min(imageMaxWidth, bubbleMaxWidth);
4368
4459
  imageHeight = imageWidth / imageAspectRatio;
4369
- totalHeight = imageHeight + imageGapToText + bubbleHeight;
4370
4460
  }
4371
- const x = isSender ? canvasWidth - paddingRight - bubbleWidth : paddingLeft;
4372
- const y = currentY - bubbleHeight;
4461
+ const bubbleTop = currentY - bubbleHeight;
4373
4462
  if (msg.imageUrl && imageHeight) {
4374
- imageY = y - imageGapToText - imageHeight;
4463
+ imageY = bubbleTop - imageGapToText - imageHeight;
4375
4464
  }
4376
4465
  calculatedMessages.unshift({
4377
4466
  message: msg,
4378
- x,
4379
- y,
4380
- width: bubbleWidth,
4467
+ top: bubbleTop,
4381
4468
  height: bubbleHeight,
4382
- textWidth,
4383
- textHeight,
4469
+ lines,
4384
4470
  imageWidth,
4385
4471
  imageHeight,
4386
4472
  imageY
4387
4473
  });
4388
4474
  const prevMsg = i > 0 ? messages[i - 1] : null;
4389
4475
  const gap = prevMsg && prevMsg.sender === msg.sender && !msg.groupWithPrevious ? messageGapSameUser : messageGapDifferentUser;
4390
- const topOfMessage = msg.imageUrl && imageY !== void 0 ? imageY : y;
4476
+ const topOfMessage = msg.imageUrl && imageY !== void 0 ? imageY : bubbleTop;
4391
4477
  currentY = topOfMessage - gap;
4392
4478
  }
4393
4479
  return calculatedMessages;
@@ -4400,14 +4486,18 @@ function generateMessageElements2(props, calculatedMessages) {
4400
4486
  const bubbleTextColor = props.bubbleTextColor ?? MESSAGE_DEFAULTS2.bubbleTextColor;
4401
4487
  const bubbleTextFontSize = props.bubbleTextFontSize ?? MESSAGE_DEFAULTS2.bubbleTextFontSize;
4402
4488
  const bubbleTextLetterSpacing = props.bubbleTextLetterSpacing ?? MESSAGE_DEFAULTS2.bubbleTextLetterSpacing;
4489
+ const bubbleTextLineHeight = props.bubbleTextLineHeight ?? MESSAGE_DEFAULTS2.bubbleTextLineHeight;
4403
4490
  const bubbleBorderRadius = props.bubbleBorderRadius ?? MESSAGE_DEFAULTS2.bubbleBorderRadius;
4404
4491
  const bubblePaddingX = props.bubblePaddingX ?? MESSAGE_DEFAULTS2.bubblePaddingX;
4405
4492
  const bubblePaddingY = props.bubblePaddingY ?? MESSAGE_DEFAULTS2.bubblePaddingY;
4493
+ const bubbleMaxWidth = props.bubbleMaxWidth ?? MESSAGE_DEFAULTS2.bubbleMaxWidth;
4406
4494
  const imageBorderRadius = MESSAGE_DEFAULTS2.imageBorderRadius;
4407
4495
  const sentMessagePaddingRight = props.sentMessagePaddingRight ?? MESSAGE_DEFAULTS2.sentMessagePaddingRight;
4408
4496
  const receivedMessagePaddingLeft = props.receivedMessagePaddingLeft ?? MESSAGE_DEFAULTS2.receivedMessagePaddingLeft;
4409
- for (const calc of calculatedMessages) {
4410
- const { message, x, y, width, height, imageWidth, imageHeight, imageY } = calc;
4497
+ const senderBubbleRight = canvasWidth - sentMessagePaddingRight;
4498
+ for (let i = 0; i < calculatedMessages.length; i++) {
4499
+ const calc = calculatedMessages[i];
4500
+ const { message, top, height, lines, imageWidth, imageHeight, imageY } = calc;
4411
4501
  const isSender = message.sender === "user";
4412
4502
  const bubbleColor = isSender ? senderBubbleColor : recipientBubbleColor;
4413
4503
  if (message.imageUrl && imageWidth && imageHeight && imageY !== void 0) {
@@ -4425,35 +4515,39 @@ function generateMessageElements2(props, calculatedMessages) {
4425
4515
  objectFit: "cover"
4426
4516
  });
4427
4517
  }
4518
+ const elementX = isSender ? senderBubbleRight - bubbleMaxWidth : receivedMessagePaddingLeft;
4519
+ const textContent = lines.join("\n");
4428
4520
  elements.push({
4429
- id: `bubble-${message.id}`,
4521
+ id: `message-${message.id}`,
4430
4522
  type: "text",
4431
- x,
4432
- y,
4433
- width,
4523
+ x: elementX,
4524
+ y: top,
4525
+ width: bubbleMaxWidth,
4434
4526
  height,
4435
- zIndex: 10,
4436
- text: "",
4437
- backgroundColor: bubbleColor,
4438
- backgroundOpacity: 100,
4439
- borderRadius: bubbleBorderRadius
4440
- });
4441
- elements.push({
4442
- id: `text-${message.id}`,
4443
- type: "text",
4444
- x: x + bubblePaddingX,
4445
- y: y + bubblePaddingY,
4446
- width: width - bubblePaddingX * 2,
4447
- height: height - bubblePaddingY * 2,
4448
- zIndex: 11,
4449
- text: message.text,
4527
+ zIndex: 10 + i,
4528
+ text: textContent,
4450
4529
  font: "apple",
4451
4530
  fontWeight: 400,
4452
4531
  fontSize: bubbleTextFontSize,
4453
4532
  letterSpacing: bubbleTextLetterSpacing,
4533
+ lineHeight: bubbleTextLineHeight,
4454
4534
  color: bubbleTextColor,
4455
4535
  textAlign: "left",
4456
- verticalAlign: "top"
4536
+ verticalAlign: "middle",
4537
+ backgroundColor: bubbleColor,
4538
+ backgroundOpacity: 100,
4539
+ backgroundBorderRadius: {
4540
+ topLeft: bubbleBorderRadius,
4541
+ topRight: bubbleBorderRadius,
4542
+ bottomLeft: bubbleBorderRadius,
4543
+ bottomRight: bubbleBorderRadius
4544
+ },
4545
+ paddingTop: bubblePaddingY,
4546
+ paddingRight: bubblePaddingX,
4547
+ paddingBottom: bubblePaddingY,
4548
+ paddingLeft: bubblePaddingX,
4549
+ autoWidth: true,
4550
+ boxAlign: isSender ? "right" : "left"
4457
4551
  });
4458
4552
  }
4459
4553
  return elements;
@@ -5476,9 +5570,11 @@ var iMessageDmPropsSchema = z.object({
5476
5570
  bubbleTextColor: z.string().optional(),
5477
5571
  bubbleTextFontSize: z.number().optional(),
5478
5572
  bubbleTextLetterSpacing: z.number().optional(),
5573
+ bubbleTextLineHeight: z.number().optional(),
5479
5574
  bubbleBorderRadius: z.number().optional(),
5480
5575
  bubblePaddingX: z.number().optional(),
5481
5576
  bubblePaddingY: z.number().optional(),
5577
+ bubbleMaxWidth: z.number().optional(),
5482
5578
  messageGapSameUser: z.number().optional(),
5483
5579
  messageGapDifferentUser: z.number().optional(),
5484
5580
  sentMessagePaddingLeft: z.number().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.8.160",
3
+ "version": "1.8.161",
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",