@linktr.ee/messaging-react 2.2.3 → 2.3.0-rc-1779427772
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/{Card-BRub_HpW.js → Card-B7yHs01-.js} +16 -16
- package/dist/{Card-BRub_HpW.js.map → Card-B7yHs01-.js.map} +1 -1
- package/dist/{Card-CyszwESe.cjs → Card-BkWwtS0b.cjs} +2 -2
- package/dist/{Card-CyszwESe.cjs.map → Card-BkWwtS0b.cjs.map} +1 -1
- package/dist/{Card-DWH_vCQD.cjs → Card-BlzGsGam.cjs} +2 -2
- package/dist/{Card-DWH_vCQD.cjs.map → Card-BlzGsGam.cjs.map} +1 -1
- package/dist/{Card-imQIyJzJ.cjs → Card-DApWNv5V.cjs} +2 -2
- package/dist/{Card-imQIyJzJ.cjs.map → Card-DApWNv5V.cjs.map} +1 -1
- package/dist/{Card-DOws_Rs6.js → Card-DKp7ijLV.js} +6 -6
- package/dist/{Card-DOws_Rs6.js.map → Card-DKp7ijLV.js.map} +1 -1
- package/dist/{Card-Ccy5fPho.js → Card-Djm6JjNo.js} +19 -19
- package/dist/{Card-Ccy5fPho.js.map → Card-Djm6JjNo.js.map} +1 -1
- package/dist/{LockedThumbnail-D512VE6T.cjs → LockedThumbnail-BjF6khtg.cjs} +2 -2
- package/dist/{LockedThumbnail-D512VE6T.cjs.map → LockedThumbnail-BjF6khtg.cjs.map} +1 -1
- package/dist/{LockedThumbnail-C9eocsRT.js → LockedThumbnail-pm6jo2B4.js} +8 -8
- package/dist/{LockedThumbnail-C9eocsRT.js.map → LockedThumbnail-pm6jo2B4.js.map} +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/index-7sLuX6s4.cjs +18 -0
- package/dist/index-7sLuX6s4.cjs.map +1 -0
- package/dist/index-Co-LV7yc.js +8220 -0
- package/dist/index-Co-LV7yc.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/ChannelView.tsx +8 -2
- package/src/components/CustomMessage/CustomMessage.stories.tsx +140 -0
- package/src/components/CustomMessage/CustomMessageActions.tsx +35 -0
- package/src/components/CustomMessage/index.tsx +20 -15
- package/src/styles.css +84 -19
- package/dist/index-IlgylJT2.cjs +0 -2
- package/dist/index-IlgylJT2.cjs.map +0 -1
- package/dist/index-uxWUZe1M.js +0 -4790
- package/dist/index-uxWUZe1M.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-7sLuX6s4.cjs");exports.ActionButton=e.ActionButton;exports.Avatar=e.Avatar;exports.ChannelEmptyState=e.ChannelEmptyState;exports.ChannelList=e.ChannelList;exports.ChannelView=e.ChannelView;exports.CustomMessageProvider=e.CustomMessageProvider;exports.FaqList=e.FaqList;exports.FaqListItem=e.FaqListItem;exports.LinkAttachment=e.LinkAttachment;exports.LockedAttachment=e.LockedAttachment;exports.MediaMessage=e.MediaMessage;exports.MessageAttachment=e.MessageAttachment;exports.MessageVoteButtons=e.MessageVoteButtons;exports.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.buildCompactMetaLabel=e.buildCompactMetaLabel;exports.formatFileSize=e.formatFileSize;exports.formatRelativeTime=e.formatRelativeTime;exports.getFileExtensionLabel=e.getFileExtensionLabel;exports.getMessageDisplayText=e.getMessageDisplayText;exports.isLinkAttachment=e.isLinkAttachment;exports.isUuidLike=e.isUuidLike;exports.messageAttachmentGroupPositionFromStream=e.bubbleGroupPositionFromStream;exports.normalizeLanguageCode=e.normalizeLanguageCode;exports.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;exports.useCustomMessage=e.useCustomMessage;exports.useMessageVote=e.useMessageVote;exports.useMessaging=e.useMessaging;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, b as t, C as i, c as n, d as o, e as m, F as g, f as l, L as r, h as M, M as u, i as L, j as c, k as h, l as d, m as p, n as v, o as A, p as C, q as F, s as k, t as b, u as f, v as x, w as y, x as P, y as S, z as q, B as z, D as B } from "./index-
|
|
1
|
+
import { a as e, b as t, C as i, c as n, d as o, e as m, F as g, f as l, L as r, h as M, M as u, i as L, j as c, k as h, l as d, m as p, n as v, o as A, p as C, q as F, s as k, t as b, u as f, v as x, w as y, x as P, y as S, z as q, B as z, D as B } from "./index-Co-LV7yc.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ActionButton,
|
|
4
4
|
t as Avatar,
|
package/package.json
CHANGED
|
@@ -26,6 +26,7 @@ import { Avatar } from './Avatar'
|
|
|
26
26
|
import { ChannelInfoDialog } from './ChannelInfoDialog'
|
|
27
27
|
import { CustomDateSeparator } from './CustomDateSeparator'
|
|
28
28
|
import { CustomMessage } from './CustomMessage'
|
|
29
|
+
import { CustomMessageActions } from './CustomMessage/CustomMessageActions'
|
|
29
30
|
import { CustomMessageInput } from './CustomMessageInput'
|
|
30
31
|
import { CustomSystemMessage } from './CustomSystemMessage'
|
|
31
32
|
import CustomTypingIndicator from './CustomTypingIndicator'
|
|
@@ -35,6 +36,7 @@ import { LoadingState } from './MessagingShell/LoadingState'
|
|
|
35
36
|
|
|
36
37
|
const ICON_BTN_CLASS =
|
|
37
38
|
'size-10 rounded-full bg-[#F1F0EE] hover:bg-[#E5E4E1] flex items-center justify-center transition-colors duration-150 focus-ring'
|
|
39
|
+
|
|
38
40
|
const DM_AGENT_HEADER_HELPER_TEXT = 'Replies instantly with AI assistant'
|
|
39
41
|
|
|
40
42
|
/**
|
|
@@ -374,7 +376,12 @@ const ChannelViewInner: React.FC<{
|
|
|
374
376
|
|
|
375
377
|
return (
|
|
376
378
|
<>
|
|
377
|
-
<WithComponents
|
|
379
|
+
<WithComponents
|
|
380
|
+
overrides={{
|
|
381
|
+
Message: MessageOverride,
|
|
382
|
+
MessageActions: CustomMessageActions,
|
|
383
|
+
}}
|
|
384
|
+
>
|
|
378
385
|
<Window>
|
|
379
386
|
{/* Custom Channel Header */}
|
|
380
387
|
<div key="lt-channel-header" className="p-4">
|
|
@@ -404,7 +411,6 @@ const ChannelViewInner: React.FC<{
|
|
|
404
411
|
<MessageList
|
|
405
412
|
hideDeletedMessages
|
|
406
413
|
hideNewMessageSeparator={false}
|
|
407
|
-
messageActions={undefined}
|
|
408
414
|
/>
|
|
409
415
|
</div>
|
|
410
416
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../../stream-custom-data'
|
|
2
2
|
|
|
3
3
|
import type { Meta, StoryFn } from '@storybook/react'
|
|
4
|
+
import { expect, userEvent, within } from '@storybook/test'
|
|
4
5
|
import React, { useEffect } from 'react'
|
|
5
6
|
import {
|
|
6
7
|
Channel as ChannelType,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
MessageList,
|
|
14
15
|
MessageUIComponentProps,
|
|
15
16
|
Window,
|
|
17
|
+
WithComponents,
|
|
16
18
|
} from 'stream-chat-react'
|
|
17
19
|
|
|
18
20
|
import {
|
|
@@ -22,6 +24,8 @@ import {
|
|
|
22
24
|
} from '../../stories/decorators/storyUser'
|
|
23
25
|
import CustomTypingIndicator from '../CustomTypingIndicator'
|
|
24
26
|
|
|
27
|
+
import { CustomMessageActions } from './CustomMessageActions'
|
|
28
|
+
|
|
25
29
|
import { CustomMessage } from './index'
|
|
26
30
|
|
|
27
31
|
const meta: Meta = {
|
|
@@ -58,6 +62,8 @@ const createMockChannel = async (
|
|
|
58
62
|
|
|
59
63
|
const channelData = {
|
|
60
64
|
members: [storyUsers.creator.id, storyUsers.visitor.id],
|
|
65
|
+
// Required for useUserRole: canDelete needs delete-own-message, canFlag needs flag-message
|
|
66
|
+
own_capabilities: ['delete-own-message', 'flag-message'],
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
const channel = client.channel(
|
|
@@ -352,6 +358,8 @@ LockedAttachment.args = {
|
|
|
352
358
|
],
|
|
353
359
|
}
|
|
354
360
|
|
|
361
|
+
|
|
362
|
+
|
|
355
363
|
export const ChatbotVariants: StoryFn<TemplateProps> = Template.bind({})
|
|
356
364
|
ChatbotVariants.args = {
|
|
357
365
|
messages: [
|
|
@@ -445,3 +453,135 @@ WithTypingIndicatorComparison.parameters = {
|
|
|
445
453
|
},
|
|
446
454
|
},
|
|
447
455
|
}
|
|
456
|
+
|
|
457
|
+
// ─── Message Actions ──────────────────────────────────────────────────────────
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Same as TemplateInner but wraps with WithComponents so CustomMessageActions
|
|
461
|
+
* is wired in — matching what ChannelView does in production.
|
|
462
|
+
*/
|
|
463
|
+
const WithActionsTemplateInner: React.FC<{
|
|
464
|
+
currentUser: StoryUser
|
|
465
|
+
messages: TemplateProps['messages']
|
|
466
|
+
}> = ({ currentUser, messages }) => {
|
|
467
|
+
const [client] = React.useState(() => {
|
|
468
|
+
const c = new StreamChat('mock-api-key', { allowServerSideConnect: true })
|
|
469
|
+
c.userID = currentUser.id
|
|
470
|
+
c.user = currentUser
|
|
471
|
+
return c
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
const [channel, setChannel] = React.useState<ChannelType | null>(null)
|
|
475
|
+
|
|
476
|
+
useEffect(() => {
|
|
477
|
+
createMockChannel(client, messages).then(setChannel)
|
|
478
|
+
}, [client, messages])
|
|
479
|
+
|
|
480
|
+
const MessageComponent = React.useMemo(() => {
|
|
481
|
+
return function CustomMessageComponent(props: MessageUIComponentProps) {
|
|
482
|
+
return <CustomMessage {...props} />
|
|
483
|
+
}
|
|
484
|
+
}, [])
|
|
485
|
+
|
|
486
|
+
if (!channel) {
|
|
487
|
+
return <div className="p-4">Loading...</div>
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return (
|
|
491
|
+
<Chat client={client}>
|
|
492
|
+
<div className="h-screen w-full bg-white">
|
|
493
|
+
<Channel channel={channel} TypingIndicator={CustomTypingIndicator}>
|
|
494
|
+
<WithComponents
|
|
495
|
+
overrides={{
|
|
496
|
+
Message: MessageComponent,
|
|
497
|
+
MessageActions: CustomMessageActions,
|
|
498
|
+
}}
|
|
499
|
+
>
|
|
500
|
+
<Window>
|
|
501
|
+
<MessageList />
|
|
502
|
+
</Window>
|
|
503
|
+
</WithComponents>
|
|
504
|
+
</Channel>
|
|
505
|
+
</div>
|
|
506
|
+
</Chat>
|
|
507
|
+
)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const WithActionsTemplate: StoryFn<TemplateProps> = ({
|
|
511
|
+
currentUser = storyUsers.creator,
|
|
512
|
+
messages,
|
|
513
|
+
}) => (
|
|
514
|
+
<WithActionsTemplateInner
|
|
515
|
+
key={currentUser.id}
|
|
516
|
+
currentUser={currentUser}
|
|
517
|
+
messages={messages}
|
|
518
|
+
/>
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
export const DeleteOwnMessage: StoryFn<TemplateProps> =
|
|
522
|
+
WithActionsTemplate.bind({})
|
|
523
|
+
DeleteOwnMessage.args = {
|
|
524
|
+
currentUser: storyUsers.creator,
|
|
525
|
+
messages: [
|
|
526
|
+
{
|
|
527
|
+
id: 'msg-1',
|
|
528
|
+
text: 'Hey, how are you?',
|
|
529
|
+
user: storyUsers.visitor,
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: 'msg-2',
|
|
533
|
+
text: 'Doing great — hover me to delete!',
|
|
534
|
+
user: storyUsers.creator,
|
|
535
|
+
},
|
|
536
|
+
],
|
|
537
|
+
}
|
|
538
|
+
DeleteOwnMessage.play = async ({ canvasElement }) => {
|
|
539
|
+
const canvas = within(canvasElement)
|
|
540
|
+
const ownBubble = await canvas.findByText('Doing great — hover me to delete!')
|
|
541
|
+
await userEvent.hover(ownBubble)
|
|
542
|
+
const toggle = await canvas.findByTestId('message-actions-toggle-button')
|
|
543
|
+
await userEvent.click(toggle)
|
|
544
|
+
await expect(canvas.getByText('Delete')).toBeInTheDocument()
|
|
545
|
+
}
|
|
546
|
+
DeleteOwnMessage.parameters = {
|
|
547
|
+
docs: {
|
|
548
|
+
description: {
|
|
549
|
+
story:
|
|
550
|
+
'Current user hovers their own message. Only "Delete" is shown — "Report" is hidden.',
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export const ReportOthersMessage: StoryFn<TemplateProps> =
|
|
556
|
+
WithActionsTemplate.bind({})
|
|
557
|
+
ReportOthersMessage.args = {
|
|
558
|
+
currentUser: storyUsers.creator,
|
|
559
|
+
messages: [
|
|
560
|
+
{
|
|
561
|
+
id: 'msg-1',
|
|
562
|
+
text: 'Hover me to report!',
|
|
563
|
+
user: storyUsers.visitor,
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
id: 'msg-2',
|
|
567
|
+
text: "That's a fine message.",
|
|
568
|
+
user: storyUsers.creator,
|
|
569
|
+
},
|
|
570
|
+
],
|
|
571
|
+
}
|
|
572
|
+
ReportOthersMessage.play = async ({ canvasElement }) => {
|
|
573
|
+
const canvas = within(canvasElement)
|
|
574
|
+
const otherBubble = await canvas.findByText('Hover me to report!')
|
|
575
|
+
await userEvent.hover(otherBubble)
|
|
576
|
+
const toggle = await canvas.findByTestId('message-actions-toggle-button')
|
|
577
|
+
await userEvent.click(toggle)
|
|
578
|
+
await expect(canvas.getByText('Report')).toBeInTheDocument()
|
|
579
|
+
}
|
|
580
|
+
ReportOthersMessage.parameters = {
|
|
581
|
+
docs: {
|
|
582
|
+
description: {
|
|
583
|
+
story:
|
|
584
|
+
"Current user hovers the other participant's message. Only \"Report\" is shown — \"Delete\" is hidden.",
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useMessageContext, useTranslationContext } from 'stream-chat-react'
|
|
3
|
+
import {
|
|
4
|
+
DefaultDropdownActionButton,
|
|
5
|
+
MessageActions,
|
|
6
|
+
type MessageActionSetItem,
|
|
7
|
+
} from 'stream-chat-react/experimental'
|
|
8
|
+
|
|
9
|
+
const DeleteAction = () => {
|
|
10
|
+
const { handleDelete } = useMessageContext('CustomMessageActions')
|
|
11
|
+
const { t } = useTranslationContext('CustomMessageActions')
|
|
12
|
+
return (
|
|
13
|
+
<DefaultDropdownActionButton onClick={handleDelete}>
|
|
14
|
+
{t('Delete')}
|
|
15
|
+
</DefaultDropdownActionButton>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ReportAction = () => {
|
|
20
|
+
const { handleFlag } = useMessageContext('CustomMessageActions')
|
|
21
|
+
return (
|
|
22
|
+
<DefaultDropdownActionButton onClick={handleFlag}>
|
|
23
|
+
Report
|
|
24
|
+
</DefaultDropdownActionButton>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const MESSAGE_ACTION_SET: MessageActionSetItem[] = [
|
|
29
|
+
{ Component: DeleteAction, placement: 'dropdown', type: 'delete' },
|
|
30
|
+
{ Component: ReportAction, placement: 'dropdown', type: 'flag' },
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
export const CustomMessageActions = () => (
|
|
34
|
+
<MessageActions messageActionSet={MESSAGE_ACTION_SET} />
|
|
35
|
+
)
|
|
@@ -85,6 +85,7 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
85
85
|
const {
|
|
86
86
|
Attachment = DefaultAttachment,
|
|
87
87
|
EditMessageModal = DefaultEditMessageModal,
|
|
88
|
+
MessageActions,
|
|
88
89
|
MessageBlocked = DefaultMessageBlocked,
|
|
89
90
|
MessageBouncePrompt = DefaultMessageBouncePrompt,
|
|
90
91
|
MessageDeleted = DefaultMessageDeleted,
|
|
@@ -297,24 +298,28 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
297
298
|
)}
|
|
298
299
|
<MessageErrorIcon />
|
|
299
300
|
</div>
|
|
300
|
-
{/* Tip/paid tags stay outside; chatbot attachment indicator stays outside too */}
|
|
301
|
-
{(!isChatbot || useAttachmentFooterChatbotTag) && (
|
|
302
|
-
<MessageTag
|
|
303
|
-
message={message}
|
|
304
|
-
hasAttachment={hasRenderableAttachments}
|
|
305
|
-
isMyMessage={isMine}
|
|
306
|
-
/>
|
|
307
|
-
)}
|
|
308
|
-
{chatbotVotingEnabled && isChatbot && (
|
|
309
|
-
<MessageVoteButtons
|
|
310
|
-
selected={voteState}
|
|
311
|
-
onVoteUp={voteUp}
|
|
312
|
-
onVoteDown={voteDown}
|
|
313
|
-
/>
|
|
314
|
-
)}
|
|
315
301
|
</div>
|
|
316
302
|
)}
|
|
303
|
+
{MessageActions && <MessageActions />}
|
|
317
304
|
</div>
|
|
305
|
+
{!isAttachment && !isTipOnly && (
|
|
306
|
+
<div className="str-chat__message-footer">
|
|
307
|
+
{(!isChatbot || useAttachmentFooterChatbotTag) && (
|
|
308
|
+
<MessageTag
|
|
309
|
+
message={message}
|
|
310
|
+
hasAttachment={hasRenderableAttachments}
|
|
311
|
+
isMyMessage={isMine}
|
|
312
|
+
/>
|
|
313
|
+
)}
|
|
314
|
+
{chatbotVotingEnabled && isChatbot && (
|
|
315
|
+
<MessageVoteButtons
|
|
316
|
+
selected={voteState}
|
|
317
|
+
onVoteUp={voteUp}
|
|
318
|
+
onVoteDown={voteDown}
|
|
319
|
+
/>
|
|
320
|
+
)}
|
|
321
|
+
</div>
|
|
322
|
+
)}
|
|
318
323
|
{showReplyCountButton && (
|
|
319
324
|
<MessageRepliesCountButton
|
|
320
325
|
onClick={handleOpenThread}
|
package/src/styles.css
CHANGED
|
@@ -160,32 +160,82 @@
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
.str-chat__li .str-chat__message-inner {
|
|
163
|
-
grid-column-gap:
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.str-chat__li .str-chat__message--me .str-chat__message-bubble-wrapper {
|
|
167
|
-
display: flex;
|
|
168
|
-
flex-direction: column;
|
|
169
|
-
align-items: flex-end;
|
|
170
|
-
gap: 2px;
|
|
163
|
+
grid-column-gap: 4px;
|
|
171
164
|
}
|
|
172
165
|
|
|
166
|
+
/* Outer grid for other (incoming) messages — add footer row after message */
|
|
173
167
|
.str-chat__li .str-chat__message--other {
|
|
174
|
-
|
|
168
|
+
grid-template-areas:
|
|
169
|
+
'. message-reminder'
|
|
170
|
+
'avatar message'
|
|
171
|
+
'. footer'
|
|
172
|
+
'. replies'
|
|
173
|
+
'. translation-notice'
|
|
174
|
+
'. custom-metadata'
|
|
175
|
+
'. metadata';
|
|
175
176
|
grid-template-columns: 28px 1fr;
|
|
177
|
+
justify-items: flex-start;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
|
-
|
|
180
|
+
/* Outer grid for me (outgoing) messages — add footer row after message */
|
|
181
|
+
.str-chat__li .str-chat__message--me {
|
|
182
|
+
grid-template-areas:
|
|
183
|
+
'message-reminder'
|
|
184
|
+
'message'
|
|
185
|
+
'footer'
|
|
186
|
+
'replies'
|
|
187
|
+
'translation-notice'
|
|
188
|
+
'custom-metadata'
|
|
189
|
+
'metadata';
|
|
190
|
+
justify-items: end;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Avatar: proper grid item aligned to bottom of its row */
|
|
194
|
+
.str-chat__li .str-chat__message--other .str-chat__message-sender-avatar {
|
|
195
|
+
grid-area: avatar;
|
|
196
|
+
align-self: end;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* message-inner sits in the message grid area */
|
|
200
|
+
.str-chat__li .str-chat__message-inner {
|
|
201
|
+
grid-area: message;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Inner grid: bubble beside options only (no footer row) */
|
|
205
|
+
.str-chat__li .str-chat__message--other .str-chat__message-inner {
|
|
206
|
+
grid-template-areas: 'message-bubble options';
|
|
207
|
+
grid-template-columns: auto auto;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.str-chat__li .str-chat__message--me .str-chat__message-inner {
|
|
211
|
+
grid-template-areas: 'options message-bubble';
|
|
212
|
+
grid-template-columns: auto auto;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Bubble wrapper occupies the message-bubble grid area */
|
|
216
|
+
.str-chat__li .str-chat__message-inner > .str-chat__message-bubble-wrapper {
|
|
217
|
+
grid-area: message-bubble;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Actions button centers vertically with the bubble */
|
|
221
|
+
.str-chat__li .str-chat__message-inner .str-chat__message-options {
|
|
222
|
+
align-self: center;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Footer: tag then vote buttons stacked, in outer grid footer area */
|
|
226
|
+
.str-chat__li .str-chat__message-footer {
|
|
227
|
+
grid-area: footer;
|
|
179
228
|
display: flex;
|
|
180
229
|
flex-direction: column;
|
|
181
|
-
align-items: flex-start;
|
|
182
230
|
gap: 2px;
|
|
183
231
|
}
|
|
184
232
|
|
|
185
|
-
.str-chat__li .str-chat__message--other .str-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
233
|
+
.str-chat__li .str-chat__message--other .str-chat__message-footer {
|
|
234
|
+
align-items: flex-start;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.str-chat__li .str-chat__message--me .str-chat__message-footer {
|
|
238
|
+
align-items: flex-end;
|
|
189
239
|
}
|
|
190
240
|
|
|
191
241
|
/* Channel list load-more button overrides */
|
|
@@ -258,9 +308,7 @@
|
|
|
258
308
|
}
|
|
259
309
|
|
|
260
310
|
.message-chatbot-indicator--attachment {
|
|
261
|
-
width: 100%;
|
|
262
311
|
gap: 8px;
|
|
263
|
-
margin-top: 4px;
|
|
264
312
|
color: rgba(0, 0, 0, 0.3);
|
|
265
313
|
}
|
|
266
314
|
|
|
@@ -279,7 +327,6 @@
|
|
|
279
327
|
display: inline-flex;
|
|
280
328
|
align-items: center;
|
|
281
329
|
gap: 2px;
|
|
282
|
-
margin-top: 4px;
|
|
283
330
|
}
|
|
284
331
|
|
|
285
332
|
.message-vote-button {
|
|
@@ -389,6 +436,24 @@
|
|
|
389
436
|
margin-bottom: 0;
|
|
390
437
|
}
|
|
391
438
|
|
|
439
|
+
/* Locked attachment wrapper: stack card + text bubble in the correct direction */
|
|
440
|
+
.str-chat__li .str-chat__message--me .str-chat__message-bubble-wrapper {
|
|
441
|
+
display: flex;
|
|
442
|
+
flex-direction: column;
|
|
443
|
+
align-items: flex-end;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.str-chat__li .str-chat__message--other .str-chat__message-bubble-wrapper {
|
|
447
|
+
display: flex;
|
|
448
|
+
flex-direction: column;
|
|
449
|
+
align-items: flex-start;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/* Gap between locked attachment card and accompanying text bubble */
|
|
453
|
+
.str-chat__message-bubble-wrapper > .str-chat__message-bubble:not(:first-child) {
|
|
454
|
+
margin-top: 4px;
|
|
455
|
+
}
|
|
456
|
+
|
|
392
457
|
/* Standalone tip message (tip without text) */
|
|
393
458
|
.message-tip-standalone {
|
|
394
459
|
display: inline-flex;
|
|
@@ -400,4 +465,4 @@
|
|
|
400
465
|
font-weight: 500;
|
|
401
466
|
color: #016e1a;
|
|
402
467
|
background-color: #dbf0e0;
|
|
403
|
-
}
|
|
468
|
+
}
|