@linktr.ee/messaging-react 1.38.0-rc-1777583423 → 1.38.0

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
@@ -1,4 +1,4 @@
1
- import { b as e, c as t, C as i, d as n, e as o, f as r, F as g, g as M, L as m, M as l, h as u, i as c, j as h, P as d, k as v, r as C, l as L, u as P, m as k, n as p, o as A } from "./index-jnKl3mQ0.js";
1
+ import { b as e, c as t, C as i, d as n, e as o, f as r, F as g, g as M, L as m, M as l, h as u, i as c, j as h, P as d, k as v, r as C, l as L, u as P, m as k, n as p, o as A } from "./index-B_4pciGp.js";
2
2
  export {
3
3
  e as ActionButton,
4
4
  t as Avatar,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "1.38.0-rc-1777583423",
3
+ "version": "1.38.0",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -70,15 +70,17 @@ const AttachmentCard: React.FC<AttachmentCardProps> = ({
70
70
  {thumbnail}
71
71
 
72
72
  <div className="px-4 pb-3 pt-3">
73
- <p
74
- className={classNames('mb-0.5 truncate text-base font-medium', {
75
- 'text-black': !isDark,
76
- 'text-white/30': isDark && titleDimmed,
77
- 'text-white': isDark && !titleDimmed,
78
- })}
79
- >
80
- {displayTitle}
81
- </p>
73
+ {displayTitle.trim() !== '' && (
74
+ <p
75
+ className={classNames('mb-0.5 truncate text-base font-medium', {
76
+ 'text-black': !isDark,
77
+ 'text-white/30': isDark && titleDimmed,
78
+ 'text-white': isDark && !titleDimmed,
79
+ })}
80
+ >
81
+ {displayTitle}
82
+ </p>
83
+ )}
82
84
 
83
85
  <div className="flex flex-wrap items-center gap-1">
84
86
  {renderTypeIcon(mimeType, {
@@ -4,7 +4,7 @@ import { describe, expect, it, vi } from 'vitest'
4
4
 
5
5
  import { renderWithProviders, screen, fireEvent } from '../../test/utils'
6
6
 
7
- import { MediaMessage } from '.'
7
+ import { MediaMessage, resolveLinkAttachment } from '.'
8
8
 
9
9
  vi.mock('../Avatar', () => ({
10
10
  Avatar: ({ id }: { id: string }) => (
@@ -310,6 +310,25 @@ describe('MediaMessage', () => {
310
310
  expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
311
311
  })
312
312
 
313
+ it('does not show literal placeholder title for sent image without title', () => {
314
+ renderWithProviders(
315
+ <MediaMessage
316
+ isMyMessage={true}
317
+ message={msg({
318
+ attachments: [
319
+ {
320
+ type: 'image',
321
+ image_url: 'https://cdn.example.com/photo.jpg',
322
+ mime_type: 'image/jpeg',
323
+ },
324
+ ],
325
+ })}
326
+ />
327
+ )
328
+
329
+ expect(screen.queryByText('Attachment title')).not.toBeInTheDocument()
330
+ })
331
+
313
332
  it('does not show Download button for sent (Creator) image attachment', () => {
314
333
  renderWithProviders(
315
334
  <MediaMessage
@@ -452,6 +471,20 @@ describe('MediaMessage', () => {
452
471
  expect(screen.queryByRole('button', { name: 'Download' })).not.toBeInTheDocument()
453
472
  })
454
473
 
474
+ it('resolveLinkAttachment ignores empty-string og_scrape_url without asset_url', () => {
475
+ const message = msg({
476
+ attachments: [
477
+ {
478
+ type: 'image',
479
+ image_url: 'https://cdn.example.com/photo.jpg',
480
+ mime_type: 'image/jpeg',
481
+ og_scrape_url: '',
482
+ },
483
+ ],
484
+ })
485
+ expect(resolveLinkAttachment(message)).toBeUndefined()
486
+ })
487
+
455
488
  it('Download button triggers fetch and uses fallback on failure', async () => {
456
489
  const fetchSpy = vi.spyOn(global, 'fetch').mockRejectedValue(new Error('fail'))
457
490
  const openSpy = vi.spyOn(window, 'open').mockReturnValue({
@@ -45,10 +45,12 @@ const LinkCard: React.FC<{
45
45
  isMyMessage: boolean
46
46
  }> = ({ attachment, isMyMessage }) => {
47
47
  const { title, text, image_url, og_scrape_url, title_link } = attachment
48
- const url = og_scrape_url ?? title_link
48
+ const rawUrl = og_scrape_url ?? title_link
49
+ const url =
50
+ typeof rawUrl === 'string' && rawUrl.trim() !== '' ? rawUrl : undefined
49
51
 
50
- return (
51
- <a href={url} target="_blank" rel="noopener noreferrer" className="block no-underline">
52
+ const body = (
53
+ <React.Fragment>
52
54
  <div className="p-2">
53
55
  {image_url ? (
54
56
  <img
@@ -79,15 +81,25 @@ const LinkCard: React.FC<{
79
81
  </p>
80
82
  )}
81
83
  </div>
82
- </a>
84
+ </React.Fragment>
83
85
  )
86
+
87
+ if (url) {
88
+ return (
89
+ <a href={url} target="_blank" rel="noopener noreferrer" className="block no-underline">
90
+ {body}
91
+ </a>
92
+ )
93
+ }
94
+
95
+ return <div className="block">{body}</div>
84
96
  }
85
97
 
86
98
  export function resolveLinkAttachment(
87
99
  message: LocalMessage
88
100
  ): Attachment | undefined {
89
101
  return message.attachments?.find(
90
- (a) => a.type === 'link' || (a.og_scrape_url != null && !a.asset_url)
102
+ (a) => a.type === 'link' || (!!a.og_scrape_url && !a.asset_url)
91
103
  )
92
104
  }
93
105
 
@@ -216,6 +228,7 @@ const Creator: React.FC<MediaMessageResolved> = ({
216
228
  <AttachmentCard
217
229
  variant="dark"
218
230
  title={title}
231
+ placeholderTitle=""
219
232
  mimeType={resolvedType}
220
233
  detail={detail}
221
234
  thumbnail={