@linktr.ee/messaging-react 1.7.0 → 1.7.2-rc-1763202567

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "1.7.0",
3
+ "version": "1.7.2-rc-1763202567",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,6 @@ export const Avatar: React.FC<AvatarProps> = ({
22
22
  }) => {
23
23
  const emoji = getAvatarEmoji(id)
24
24
 
25
- const DEFAULT_COLOR = '#FBFAF9'
26
25
  // Determine font size based on avatar size
27
26
  const getFontSizeClass = () => {
28
27
  if (size < 32) return 'text-xs'
@@ -50,13 +49,9 @@ export const Avatar: React.FC<AvatarProps> = ({
50
49
  <div
51
50
  aria-hidden="true"
52
51
  className={classNames(
53
- 'flex h-full w-full items-center justify-center font-semibold rounded-sm',
52
+ 'flex h-full w-full items-center justify-center font-semibold rounded-sm bg-[#FBFAF9]/60',
54
53
  fontSizeClass
55
54
  )}
56
- style={{
57
- color: DEFAULT_COLOR,
58
- backgroundColor: `color-mix(in srgb, ${DEFAULT_COLOR} 60%, solid)`,
59
- }}
60
55
  >
61
56
  {emoji}
62
57
  </div>
@@ -1,33 +1,21 @@
1
- import SelectPill from '@linktr.ee/component-library/InputSelectPill'
2
- import SelectPillGroup from '@linktr.ee/component-library/InputSelectPillGroup'
3
- import { NotePencilIcon } from '@phosphor-icons/react'
4
1
  import classNames from 'classnames'
5
- import React, { useState } from 'react'
2
+ import React from 'react'
6
3
  import {
7
4
  ChannelList as StreamChannelList,
8
- useChatContext,
9
5
  } from 'stream-chat-react'
10
6
 
11
7
  import { useMessagingContext } from '../../providers/MessagingProvider'
12
8
  import type { ChannelListProps } from '../../types'
13
- import { IconButton } from '../IconButton'
14
9
 
15
10
  import CustomChannelPreview from './CustomChannelPreview'
16
11
 
17
- enum ChannelFilter {
18
- All,
19
- Unread,
20
- }
21
-
22
12
  /**
23
13
  * Channel list component with customizable header and actions
24
14
  */
25
15
  export const ChannelList: React.FC<ChannelListProps> = ({
26
16
  onChannelSelect,
27
17
  selectedChannel,
28
- showStartConversation = false,
29
- onStartConversation,
30
- participantLabel = 'participants',
18
+ filters,
31
19
  className,
32
20
  }) => {
33
21
  // Track renders
@@ -41,55 +29,10 @@ export const ChannelList: React.FC<ChannelListProps> = ({
41
29
  console.log('📺 [ChannelList] 🔄 RENDER START', {
42
30
  renderCount: renderCountRef.current,
43
31
  selectedChannelId: selectedChannel?.id,
44
- showStartConversation,
45
- participantLabel,
32
+ filters,
46
33
  })
47
34
  }
48
35
 
49
- const { client } = useChatContext()
50
-
51
- if (debug) {
52
- console.log('📺 [ChannelList] 📡 CHAT CONTEXT', {
53
- renderCount: renderCountRef.current,
54
- hasClient: !!client,
55
- clientUserId: client?.userID,
56
- clientConnected: client?.wsConnection?.isHealthy,
57
- })
58
- }
59
-
60
- const [staticFilters, setStaticFilters] = useState<{
61
- type: string
62
- last_message_at: { $exists: boolean }
63
- has_unread: boolean | undefined
64
- }>({
65
- type: 'messaging',
66
- last_message_at: { $exists: true },
67
- has_unread: undefined,
68
- })
69
-
70
- // Filter for messaging channels
71
- const filters = React.useMemo(() => {
72
- const userId = client.userID
73
-
74
- const newFilters = {
75
- ...staticFilters,
76
- ...(userId && {
77
- members: { $in: [userId] },
78
- hidden: false,
79
- }),
80
- }
81
-
82
- if (debug) {
83
- console.log('📺 [ChannelList] 🔍 FILTERS MEMOIZED', {
84
- renderCount: renderCountRef.current,
85
- userId,
86
- filters: newFilters,
87
- })
88
- }
89
-
90
- return newFilters
91
- }, [client.userID, debug, staticFilters])
92
-
93
36
  return (
94
37
  <div
95
38
  className={classNames(
@@ -97,49 +40,6 @@ export const ChannelList: React.FC<ChannelListProps> = ({
97
40
  className
98
41
  )}
99
42
  >
100
- {/* Header */}
101
- <div className="px-4 py-4 border-b border-sand bg-chalk">
102
- <div className="flex items-center justify-between gap-3 min-h-10 min-w-0">
103
- <div>
104
- <h2 className="text-lg font-semibold text-charcoal">
105
- Conversations
106
- </h2>
107
- <SelectPillGroup>
108
- <SelectPill
109
- checked={!filters.has_unread}
110
- name="All"
111
- onChange={() =>
112
- setStaticFilters((state) => ({
113
- ...state,
114
- has_unread: undefined,
115
- }))
116
- }
117
- value={ChannelFilter.All}
118
- />
119
- <SelectPill
120
- checked={filters.has_unread}
121
- name="Unread"
122
- onChange={() =>
123
- setStaticFilters((state) => ({ ...state, has_unread: true }))
124
- }
125
- value={ChannelFilter.Unread}
126
- />
127
- </SelectPillGroup>
128
- </div>
129
- <div className="flex items-center gap-2">
130
- {showStartConversation && onStartConversation && (
131
- <IconButton
132
- label="Start a new conversation"
133
- onClick={onStartConversation}
134
- className="inline-flex size-10 items-center justify-center"
135
- >
136
- <NotePencilIcon className="h-5 w-5" />
137
- </IconButton>
138
- )}
139
- </div>
140
- </div>
141
- </div>
142
-
143
43
  {/* Channel List */}
144
44
  <div className="flex-1 overflow-hidden min-w-0">
145
45
  {(() => {
@@ -147,8 +47,6 @@ export const ChannelList: React.FC<ChannelListProps> = ({
147
47
  console.log('📺 [ChannelList] 🎬 RENDERING STREAM CHANNEL LIST', {
148
48
  renderCount: renderCountRef.current,
149
49
  filters,
150
- hasClient: !!client,
151
- clientUserId: client?.userID,
152
50
  })
153
51
  }
154
52
 
@@ -287,7 +287,10 @@ const ChannelInfoDialog: React.FC<{
287
287
  </div>
288
288
 
289
289
  <div className="flex-1 px-2 overflow-y-auto w-full">
290
- <div className="flex flex-col items-center gap-3 self-stretch px-4 py-2 mt-6 rounded-lg border border-black/[0.04]" style={{ backgroundColor: '#FBFAF9' }}>
290
+ <div
291
+ className="flex flex-col items-center gap-3 self-stretch px-4 py-2 mt-6 rounded-lg border border-black/[0.04]"
292
+ style={{ backgroundColor: '#FBFAF9' }}
293
+ >
291
294
  <div className="flex items-center gap-3 w-full">
292
295
  <Avatar
293
296
  id={participantId}
@@ -310,8 +313,14 @@ const ChannelInfoDialog: React.FC<{
310
313
  className="mt-1 rounded-full text-xs font-normal w-fit"
311
314
  style={{
312
315
  padding: '4px 8px',
313
- backgroundColor: followerStatusLabel === 'Subscribed to you' ? '#DCFCE7' : '#F5F5F4',
314
- color: followerStatusLabel === 'Subscribed to you' ? '#008236' : '#78716C',
316
+ backgroundColor:
317
+ followerStatusLabel === 'Subscribed to you'
318
+ ? '#DCFCE7'
319
+ : '#F5F5F4',
320
+ color:
321
+ followerStatusLabel === 'Subscribed to you'
322
+ ? '#008236'
323
+ : '#78716C',
315
324
  lineHeight: '133.333%',
316
325
  letterSpacing: '0.21px',
317
326
  }}
@@ -335,7 +344,7 @@ const ChannelInfoDialog: React.FC<{
335
344
  ) : (
336
345
  <SignOutIcon className="h-5 w-5" />
337
346
  )}
338
- <span>Leave Conversation</span>
347
+ <span>Delete Conversation</span>
339
348
  </ActionButton>
340
349
  </li>
341
350
  <li>
@@ -418,14 +427,16 @@ const ChannelViewInner: React.FC<{
418
427
  followerStatus?: string
419
428
  isFollower?: boolean
420
429
  }
421
-
430
+
422
431
  // If explicit followerStatus is provided, use it
423
432
  if (channelExtraData.followerStatus) {
424
433
  return String(channelExtraData.followerStatus)
425
434
  }
426
435
  // If isFollower is explicitly defined, use it to determine status
427
436
  if (channelExtraData.isFollower !== undefined) {
428
- return channelExtraData.isFollower ? 'Subscribed to you' : 'Not subscribed'
437
+ return channelExtraData.isFollower
438
+ ? 'Subscribed to you'
439
+ : 'Not subscribed'
429
440
  }
430
441
  // Otherwise, don't show any status
431
442
  return undefined
@@ -1,6 +1,5 @@
1
1
  import classNames from 'classnames'
2
2
  import React from 'react'
3
-
4
3
  export interface FaqListItemProps {
5
4
  question: string
6
5
  onClick: () => void
@@ -25,6 +25,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
25
25
  initialParticipantData,
26
26
  CustomChannelEmptyState,
27
27
  showChannelList = true,
28
+ filters,
28
29
  }) => {
29
30
  const {
30
31
  service,
@@ -56,6 +57,28 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
56
57
  participantLabel = 'participants',
57
58
  } = capabilities
58
59
 
60
+ // Create default filters and merge with provided filters
61
+ const channelFilters = React.useMemo(() => {
62
+ const userId = client?.userID
63
+
64
+ // Base filters that should always be present
65
+ const baseFilters = {
66
+ type: 'messaging',
67
+ last_message_at: { $exists: true },
68
+ ...(userId && {
69
+ members: { $in: [userId] },
70
+ hidden: false,
71
+ }),
72
+ }
73
+
74
+ // Merge provided filters with base filters
75
+ // Provided filters can override base filters if needed
76
+ return {
77
+ ...baseFilters,
78
+ ...filters,
79
+ }
80
+ }, [filters, client?.userID])
81
+
59
82
  // Track if we've already synced channels to prevent repeated API calls
60
83
  const syncedRef = useRef<string | null>(null)
61
84
 
@@ -405,11 +428,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
405
428
  <ChannelList
406
429
  onChannelSelect={handleChannelSelect}
407
430
  selectedChannel={selectedChannel || undefined}
408
- showStartConversation={
409
- showStartConversation && Boolean(participantSource)
410
- }
411
- onStartConversation={handleStartConversation}
412
- participantLabel={participantLabel}
431
+ filters={channelFilters}
413
432
  />
414
433
  </div>
415
434
 
package/src/types.ts CHANGED
@@ -2,7 +2,7 @@ import type {
2
2
  MessagingUser,
3
3
  StreamChatServiceConfig,
4
4
  } from '@linktr.ee/messaging-core'
5
- import type { Channel } from 'stream-chat'
5
+ import type { Channel, ChannelFilters } from 'stream-chat'
6
6
 
7
7
  /**
8
8
  * Generic participant interface for different host environments
@@ -49,7 +49,6 @@ export interface MessagingCapabilities {
49
49
  export interface MessagingCustomization {
50
50
  theme?: 'light' | 'dark' | 'auto'
51
51
  accentColor?: string
52
- showParticipantStatus?: boolean
53
52
  }
54
53
 
55
54
  /**
@@ -94,6 +93,11 @@ export interface MessagingShellProps {
94
93
  * to show only the channel view without the list.
95
94
  */
96
95
  showChannelList?: boolean
96
+
97
+ /**
98
+ * Filters for channel list. Passed through to StreamChat ChannelList.
99
+ */
100
+ filters?: ChannelFilters
97
101
  }
98
102
 
99
103
  /**
@@ -106,6 +110,7 @@ export interface ChannelListProps {
106
110
  onStartConversation?: () => void
107
111
  participantLabel?: string
108
112
  className?: string
113
+ filters: ChannelFilters
109
114
  }
110
115
 
111
116
  /**