@linktr.ee/messaging-react 3.37.1 → 3.38.0-rc-1786343622

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.
Files changed (39) hide show
  1. package/dist/{Card-DVMzYquF.js → Card-D2RldKU0.js} +2 -2
  2. package/dist/{Card-DVMzYquF.js.map → Card-D2RldKU0.js.map} +1 -1
  3. package/dist/{Card-Dxk_Ggxw.cjs → Card-OtystGRA.cjs} +2 -2
  4. package/dist/{Card-Dxk_Ggxw.cjs.map → Card-OtystGRA.cjs.map} +1 -1
  5. package/dist/assets/index.css +1 -1
  6. package/dist/{index-BOBIiAuD.js → index-BoxX5w8R.js} +3123 -3163
  7. package/dist/index-BoxX5w8R.js.map +1 -0
  8. package/dist/index-BrZetD5p.cjs +3 -0
  9. package/dist/index-BrZetD5p.cjs.map +1 -0
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.d.ts +1 -34
  12. package/dist/index.js +27 -29
  13. package/package.json +4 -3
  14. package/src/components/ChannelView.tsx +1 -6
  15. package/src/components/CustomMessage/CustomMessage.test.tsx +0 -12
  16. package/src/components/CustomMessage/MessageTag.test.tsx +9 -18
  17. package/src/components/CustomMessage/MessageTag.tsx +16 -17
  18. package/src/components/CustomMessage/MessageTail.tsx +45 -0
  19. package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +9 -2
  20. package/src/components/CustomMessage/StreamAttachmentMessage.tsx +18 -4
  21. package/src/components/CustomMessage/index.tsx +32 -24
  22. package/src/components/LinkAttachment/components/_shared/BubbleTail.tsx +5 -6
  23. package/src/components/MessageAttachment/_shared/CarouselNav.tsx +5 -6
  24. package/src/components/MessageAttachment/_shared/DownloadAction.tsx +5 -8
  25. package/src/components/MessageAttachment/_shared/ImageViewer.tsx +8 -12
  26. package/src/components/MessageAttachment/_shared/PdfViewer.tsx +1 -1
  27. package/src/components/MessageAttachment/_shared/VideoViewer.tsx +1 -1
  28. package/src/components/MessageAttachment/_shared/ViewerShell.tsx +16 -11
  29. package/src/components/MessageAttachment/_shared/viewerChromeClasses.ts +16 -0
  30. package/src/components/MessagingShell/index.tsx +0 -2
  31. package/src/index.ts +0 -3
  32. package/src/styles.css +56 -377
  33. package/src/types.ts +0 -8
  34. package/dist/index-BOBIiAuD.js.map +0 -1
  35. package/dist/index-D7A8U8GQ.cjs +0 -3
  36. package/dist/index-D7A8U8GQ.cjs.map +0 -1
  37. package/src/components/CustomMessage/MessageVoteButtons.stories.tsx +0 -95
  38. package/src/components/CustomMessage/MessageVoteButtons.tsx +0 -47
  39. package/src/hooks/useMessageVote.ts +0 -77
@@ -1,95 +0,0 @@
1
- import type { Meta, StoryFn } from '@storybook/react'
2
- import React, { useState } from 'react'
3
-
4
- import type { VoteSelection } from '../../hooks/useMessageVote'
5
-
6
- import { MessageVoteButtons } from './MessageVoteButtons'
7
-
8
- type ComponentProps = React.ComponentProps<typeof MessageVoteButtons>
9
-
10
- const meta: Meta<ComponentProps> = {
11
- title: 'MessageVoteButtons',
12
- component: MessageVoteButtons,
13
- parameters: {
14
- layout: 'centered',
15
- },
16
- }
17
- export default meta
18
-
19
- const Template: StoryFn<ComponentProps> = (args) => (
20
- <div className="p-12">
21
- <MessageVoteButtons {...args} />
22
- </div>
23
- )
24
-
25
- // Per-state stories (Unselected, GoodResponse, BadResponse) are individually
26
- // covered by rows of AllVariants — skip in Chromatic. Interactive has no
27
- // useful steady-state snapshot.
28
- const skipInChromatic = { chromatic: { disableSnapshot: true } }
29
-
30
- export const Unselected: StoryFn<ComponentProps> = Template.bind({})
31
- Unselected.args = {
32
- selected: null,
33
- onVoteUp: () => {},
34
- onVoteDown: () => {},
35
- }
36
- Unselected.parameters = skipInChromatic
37
-
38
- export const GoodResponse: StoryFn<ComponentProps> = Template.bind({})
39
- GoodResponse.args = {
40
- selected: 'up',
41
- onVoteUp: () => {},
42
- onVoteDown: () => {},
43
- }
44
- GoodResponse.parameters = skipInChromatic
45
-
46
- export const BadResponse: StoryFn<ComponentProps> = Template.bind({})
47
- BadResponse.args = {
48
- selected: 'down',
49
- onVoteUp: () => {},
50
- onVoteDown: () => {},
51
- }
52
- BadResponse.parameters = skipInChromatic
53
-
54
- export const Interactive: StoryFn = () => {
55
- const [selected, setSelected] = useState<VoteSelection>(null)
56
- return (
57
- <div className="p-12">
58
- <MessageVoteButtons
59
- selected={selected}
60
- onVoteUp={() => setSelected(selected === 'up' ? null : 'up')}
61
- onVoteDown={() => setSelected(selected === 'down' ? null : 'down')}
62
- />
63
- </div>
64
- )
65
- }
66
- Interactive.parameters = skipInChromatic
67
-
68
- export const AllVariants: StoryFn = () => (
69
- <div className="p-12 flex flex-col gap-6">
70
- <div className="flex items-center gap-4">
71
- <span className="text-sm w-32">Unselected:</span>
72
- <MessageVoteButtons
73
- selected={null}
74
- onVoteUp={() => {}}
75
- onVoteDown={() => {}}
76
- />
77
- </div>
78
- <div className="flex items-center gap-4">
79
- <span className="text-sm w-32">Good response:</span>
80
- <MessageVoteButtons
81
- selected="up"
82
- onVoteUp={() => {}}
83
- onVoteDown={() => {}}
84
- />
85
- </div>
86
- <div className="flex items-center gap-4">
87
- <span className="text-sm w-32">Bad response:</span>
88
- <MessageVoteButtons
89
- selected="down"
90
- onVoteUp={() => {}}
91
- onVoteDown={() => {}}
92
- />
93
- </div>
94
- </div>
95
- )
@@ -1,47 +0,0 @@
1
- import { ThumbsUpIcon, ThumbsDownIcon } from '@phosphor-icons/react'
2
- import classNames from 'classnames'
3
- import React from 'react'
4
-
5
- import type { VoteSelection } from '../../hooks/useMessageVote'
6
-
7
- interface MessageVoteButtonsProps {
8
- selected: VoteSelection
9
- onVoteUp: () => void
10
- onVoteDown: () => void
11
- }
12
-
13
- export const MessageVoteButtons: React.FC<MessageVoteButtonsProps> = ({
14
- selected,
15
- onVoteUp,
16
- onVoteDown,
17
- }) => (
18
- <div className="message-vote-buttons">
19
- <button
20
- type="button"
21
- className={classNames('message-vote-button focus-ring', {
22
- 'message-vote-button--selected': selected === 'up',
23
- })}
24
- onClick={onVoteUp}
25
- aria-label="Good response"
26
- aria-pressed={selected === 'up'}
27
- data-tooltip="Good response"
28
- >
29
- <ThumbsUpIcon size={16} weight={selected === 'up' ? 'fill' : 'regular'} />
30
- </button>
31
- <button
32
- type="button"
33
- className={classNames('message-vote-button focus-ring', {
34
- 'message-vote-button--selected': selected === 'down',
35
- })}
36
- onClick={onVoteDown}
37
- aria-label="Bad response"
38
- aria-pressed={selected === 'down'}
39
- data-tooltip="Bad response"
40
- >
41
- <ThumbsDownIcon
42
- size={16}
43
- weight={selected === 'down' ? 'fill' : 'regular'}
44
- />
45
- </button>
46
- </div>
47
- )
@@ -1,77 +0,0 @@
1
- import { useCallback, useMemo } from 'react'
2
- import type { LocalMessage } from 'stream-chat'
3
- import { useChannelStateContext, useChatContext } from 'stream-chat-react'
4
-
5
- export type VoteSelection = 'up' | 'down' | null
6
-
7
- const VOTE_UP = 'vote_up'
8
- const VOTE_DOWN = 'vote_down'
9
-
10
- function getVoteFromReactions(
11
- ownReactions: LocalMessage['own_reactions']
12
- ): VoteSelection {
13
- if (!ownReactions?.length) return null
14
- if (ownReactions.some((r) => r.type === VOTE_DOWN)) return 'down'
15
- if (ownReactions.some((r) => r.type === VOTE_UP)) return 'up'
16
- return null
17
- }
18
-
19
- interface UseMessageVoteResult {
20
- selected: VoteSelection
21
- voteUp: () => void
22
- voteDown: () => void
23
- }
24
-
25
- /**
26
- * Hook that wraps Stream Chat reactions to provide toggle-style
27
- * upvote/downvote behavior on a message.
28
- *
29
- * Uses enforce_unique so sending a new reaction type automatically
30
- * removes the previous one. Uses skip_push to avoid notifying the
31
- * Linker on every vote.
32
- */
33
- export function useMessageVote(message: LocalMessage): UseMessageVoteResult {
34
- const { channel } = useChannelStateContext()
35
- const { client } = useChatContext('useMessageVote')
36
-
37
- const selected = useMemo(
38
- () => getVoteFromReactions(message.own_reactions),
39
- [message.own_reactions]
40
- )
41
-
42
- const voteUp = useCallback(async () => {
43
- if (!client?.userID) return
44
- try {
45
- if (selected === 'up') {
46
- await channel.deleteReaction(message.id, VOTE_UP)
47
- } else {
48
- await channel.sendReaction(
49
- message.id,
50
- { type: VOTE_UP },
51
- { enforce_unique: true, skip_push: true }
52
- )
53
- }
54
- } catch {
55
- // Silently fail — voting is non-critical
56
- }
57
- }, [channel, client?.userID, message.id, selected])
58
-
59
- const voteDown = useCallback(async () => {
60
- if (!client?.userID) return
61
- try {
62
- if (selected === 'down') {
63
- await channel.deleteReaction(message.id, VOTE_DOWN)
64
- } else {
65
- await channel.sendReaction(
66
- message.id,
67
- { type: VOTE_DOWN },
68
- { enforce_unique: true, skip_push: true }
69
- )
70
- }
71
- } catch {
72
- // Silently fail — voting is non-critical
73
- }
74
- }, [channel, client?.userID, message.id, selected])
75
-
76
- return { selected, voteUp, voteDown }
77
- }