@pushwoosh/dumb-components 1.1.224 → 1.1.226
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/Switch/Switch.d.ts +1 -1
- package/Switch/Switch.js +9 -2
- package/Switch/__tests__/Switch.test.d.ts +1 -0
- package/Switch/__tests__/Switch.test.js +44 -0
- package/Switch/styles.js +4 -2
- package/Switch/types.d.ts +2 -1
- package/WhatsAppPreview/WhatsAppPreview.d.ts +1 -1
- package/WhatsAppPreview/WhatsAppPreview.js +31 -92
- package/WhatsAppPreview/__tests__/attachment.test.js +17 -11
- package/WhatsAppPreview/components/WhatsAppAttachment/WhatsAppAttachment.js +41 -38
- package/WhatsAppPreview/components/WhatsAppAttachment/styles.d.ts +11 -30
- package/WhatsAppPreview/components/WhatsAppAttachment/styles.js +23 -30
- package/WhatsAppPreview/components/WhatsAppAttachment/types.d.ts +0 -5
- package/WhatsAppPreview/components/WhatsAppMessageBubble/WhatsAppMessageBubble.d.ts +1 -1
- package/WhatsAppPreview/components/WhatsAppMessageBubble/WhatsAppMessageBubble.js +14 -33
- package/WhatsAppPreview/components/WhatsAppMessageBubble/styles.d.ts +2 -16
- package/WhatsAppPreview/components/WhatsAppMessageBubble/styles.js +5 -33
- package/WhatsAppPreview/constants.d.ts +10 -40
- package/WhatsAppPreview/constants.js +11 -41
- package/WhatsAppPreview/helpers.d.ts +3 -1
- package/WhatsAppPreview/helpers.js +12 -4
- package/WhatsAppPreview/icons/index.d.ts +0 -10
- package/WhatsAppPreview/icons/index.js +1 -11
- package/WhatsAppPreview/index.d.ts +1 -1
- package/WhatsAppPreview/polyglot/messages_ar.js +2 -3
- package/WhatsAppPreview/polyglot/messages_bn.js +2 -3
- package/WhatsAppPreview/polyglot/messages_de.js +2 -3
- package/WhatsAppPreview/polyglot/messages_en.js +2 -3
- package/WhatsAppPreview/polyglot/messages_es.js +2 -3
- package/WhatsAppPreview/polyglot/messages_fr.js +2 -3
- package/WhatsAppPreview/polyglot/messages_he.js +2 -3
- package/WhatsAppPreview/polyglot/messages_hi.js +2 -3
- package/WhatsAppPreview/polyglot/messages_ja.js +2 -3
- package/WhatsAppPreview/polyglot/messages_ko.js +2 -3
- package/WhatsAppPreview/polyglot/messages_pt.js +2 -3
- package/WhatsAppPreview/polyglot/messages_ru.js +2 -3
- package/WhatsAppPreview/polyglot/messages_th.js +2 -3
- package/WhatsAppPreview/polyglot/messages_zh.js +2 -3
- package/WhatsAppPreview/polyglot/types.d.ts +3 -2
- package/WhatsAppPreview/styles.d.ts +21 -14
- package/WhatsAppPreview/styles.js +22 -19
- package/WhatsAppPreview/types.d.ts +11 -35
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/WhatsAppPreview/components/WhatsAppChatHeader/WhatsAppChatHeader.d.ts +0 -4
- package/WhatsAppPreview/components/WhatsAppChatHeader/WhatsAppChatHeader.js +0 -39
- package/WhatsAppPreview/components/WhatsAppChatHeader/index.d.ts +0 -1
- package/WhatsAppPreview/components/WhatsAppChatHeader/index.js +0 -1
- package/WhatsAppPreview/components/WhatsAppChatHeader/styles.d.ts +0 -47
- package/WhatsAppPreview/components/WhatsAppChatHeader/styles.js +0 -37
- package/WhatsAppPreview/components/WhatsAppChatHeader/types.d.ts +0 -10
- package/WhatsAppPreview/components/WhatsAppChatHeader/types.js +0 -1
- package/WhatsAppPreview/components/WhatsAppDateChip/WhatsAppDateChip.d.ts +0 -4
- package/WhatsAppPreview/components/WhatsAppDateChip/WhatsAppDateChip.js +0 -28
- package/WhatsAppPreview/components/WhatsAppDateChip/index.d.ts +0 -1
- package/WhatsAppPreview/components/WhatsAppDateChip/index.js +0 -1
- package/WhatsAppPreview/components/WhatsAppDateChip/styles.d.ts +0 -6
- package/WhatsAppPreview/components/WhatsAppDateChip/styles.js +0 -6
- package/WhatsAppPreview/components/WhatsAppDateChip/types.d.ts +0 -6
- package/WhatsAppPreview/components/WhatsAppDateChip/types.js +0 -1
- package/WhatsAppPreview/components/WhatsAppStatusBar/WhatsAppStatusBar.d.ts +0 -4
- package/WhatsAppPreview/components/WhatsAppStatusBar/WhatsAppStatusBar.js +0 -18
- package/WhatsAppPreview/components/WhatsAppStatusBar/index.d.ts +0 -1
- package/WhatsAppPreview/components/WhatsAppStatusBar/index.js +0 -1
- package/WhatsAppPreview/components/WhatsAppStatusBar/styles.d.ts +0 -69
- package/WhatsAppPreview/components/WhatsAppStatusBar/styles.js +0 -47
- package/WhatsAppPreview/components/WhatsAppStatusBar/types.d.ts +0 -5
- package/WhatsAppPreview/components/WhatsAppStatusBar/types.js +0 -1
- package/WhatsAppPreview/icons/WhatsAppAvatarIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppBackIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppBatteryIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppCallIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppMenuIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppSignalIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppTickIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppTicksIcon.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppWallpaperPattern.svg +0 -1
- package/WhatsAppPreview/icons/WhatsAppWifiIcon.svg +0 -1
package/Switch/Switch.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { SwitchProps } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Toggle switch for a boolean value, with an optional label on either side.
|
|
4
|
+
* Toggle switch for a boolean value, with an optional label on either side; a click anywhere flips it.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* <Switch enabled={on} onChange={() => setOn((v) => !v)}>Notifications</Switch>
|
package/Switch/Switch.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from 'react';
|
|
2
3
|
import { Container, Box, Circle, Label } from './styles';
|
|
3
4
|
/**
|
|
4
|
-
* Toggle switch for a boolean value, with an optional label on either side.
|
|
5
|
+
* Toggle switch for a boolean value, with an optional label on either side; a click anywhere flips it.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* <Switch enabled={on} onChange={() => setOn((v) => !v)}>Notifications</Switch>
|
|
@@ -13,12 +14,18 @@ export function Switch({
|
|
|
13
14
|
children,
|
|
14
15
|
onChange
|
|
15
16
|
}) {
|
|
17
|
+
const handleClick = useCallback(() => {
|
|
18
|
+
if (!isDisabled) {
|
|
19
|
+
onChange();
|
|
20
|
+
}
|
|
21
|
+
}, [isDisabled, onChange]);
|
|
16
22
|
return _jsxs(Container, {
|
|
17
23
|
labelPosition: labelPosition,
|
|
24
|
+
isDisabled: isDisabled,
|
|
25
|
+
onClick: handleClick,
|
|
18
26
|
children: [_jsx(Box, {
|
|
19
27
|
enabled: enabled,
|
|
20
28
|
isDisabled: isDisabled,
|
|
21
|
-
onClick: onChange,
|
|
22
29
|
children: _jsx(Circle, {
|
|
23
30
|
enabled: enabled,
|
|
24
31
|
isDisabled: isDisabled
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
3
|
+
import { Switch } from '../Switch';
|
|
4
|
+
describe('Switch', () => {
|
|
5
|
+
it('flips on a click on the label, not only on the toggle', () => {
|
|
6
|
+
const onChange = jest.fn();
|
|
7
|
+
render(_jsx(Switch, {
|
|
8
|
+
enabled: false,
|
|
9
|
+
onChange: onChange,
|
|
10
|
+
children: "Save inbox"
|
|
11
|
+
}));
|
|
12
|
+
fireEvent.click(screen.getByText('Save inbox'));
|
|
13
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
14
|
+
});
|
|
15
|
+
it('flips on a click on the toggle', () => {
|
|
16
|
+
const onChange = jest.fn();
|
|
17
|
+
const {
|
|
18
|
+
container
|
|
19
|
+
} = render(_jsx(Switch, {
|
|
20
|
+
enabled: true,
|
|
21
|
+
onChange: onChange,
|
|
22
|
+
children: "Save inbox"
|
|
23
|
+
}));
|
|
24
|
+
const box = container.querySelector('[tabindex="0"]');
|
|
25
|
+
if (!box) {
|
|
26
|
+
throw new Error('toggle not rendered');
|
|
27
|
+
}
|
|
28
|
+
fireEvent.click(box);
|
|
29
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
30
|
+
});
|
|
31
|
+
it('stays silent while disabled, label and toggle alike', () => {
|
|
32
|
+
const onChange = jest.fn();
|
|
33
|
+
const {
|
|
34
|
+
container
|
|
35
|
+
} = render(_jsx(Switch, {
|
|
36
|
+
isDisabled: true,
|
|
37
|
+
onChange: onChange,
|
|
38
|
+
children: "Save inbox"
|
|
39
|
+
}));
|
|
40
|
+
fireEvent.click(screen.getByText('Save inbox'));
|
|
41
|
+
fireEvent.click(container.querySelector('[tabindex="0"]'));
|
|
42
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
});
|
package/Switch/styles.js
CHANGED
|
@@ -37,9 +37,11 @@ const cssActive = css(["&:active{background:", ";border:2px solid ", ";}"], Colo
|
|
|
37
37
|
export const Container = styled.div.withConfig({
|
|
38
38
|
displayName: "Container",
|
|
39
39
|
componentId: "sc-csdrg2-0"
|
|
40
|
-
})(["display:flex;align-items:center;flex-direction:", ";"], ({
|
|
40
|
+
})(["display:flex;align-items:center;flex-direction:", ";cursor:", ";"], ({
|
|
41
41
|
labelPosition
|
|
42
|
-
}) => labelPosition === 'left' ? 'row-reverse' : 'row'
|
|
42
|
+
}) => labelPosition === 'left' ? 'row-reverse' : 'row', ({
|
|
43
|
+
isDisabled
|
|
44
|
+
}) => isDisabled ? 'not-allowed' : 'pointer');
|
|
43
45
|
export const Box = styled.div.attrs({
|
|
44
46
|
tabIndex: '0'
|
|
45
47
|
}).withConfig({
|
package/Switch/types.d.ts
CHANGED
|
@@ -12,9 +12,10 @@ export interface SwitchProps {
|
|
|
12
12
|
/** Fires when the toggle is clicked; flip `enabled` in the handler. */
|
|
13
13
|
onChange: () => void;
|
|
14
14
|
}
|
|
15
|
-
/** Internal style
|
|
15
|
+
/** Internal style props carrying the label side and the disabled state. */
|
|
16
16
|
export interface AlignProps {
|
|
17
17
|
labelPosition?: string;
|
|
18
|
+
isDisabled?: boolean;
|
|
18
19
|
}
|
|
19
20
|
/** Internal style prop carrying the toggle state. */
|
|
20
21
|
export interface ComponentProps {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { WhatsAppPreviewProps } from './types';
|
|
3
|
-
/** Renders a WhatsApp
|
|
3
|
+
/** Renders a WhatsApp message the way the recipient sees it, WhatsApp markup and attachments included. */
|
|
4
4
|
export declare function WhatsAppPreview(props: WhatsAppPreviewProps): ReactElement;
|
|
@@ -1,105 +1,44 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Color } from '@pushwoosh/kit-constants';
|
|
3
|
-
import { Horizontal
|
|
4
|
-
import { Text } from '@pushwoosh/kit-typography';
|
|
5
|
-
import { WhatsAppChatHeader } from './components/WhatsAppChatHeader';
|
|
6
|
-
import { WhatsAppDateChip } from './components/WhatsAppDateChip';
|
|
2
|
+
import { Color, ShapeRadius } from '@pushwoosh/kit-constants';
|
|
3
|
+
import { Horizontal } from '@pushwoosh/kit-helpers';
|
|
7
4
|
import { WhatsAppMessageBubble } from './components/WhatsAppMessageBubble';
|
|
8
|
-
import {
|
|
9
|
-
import { WHATSAPP_COLOR, WHATSAPP_PREVIEW_HEIGHT, WHATSAPP_PREVIEW_WIDTH, WHATSAPP_STATUS_BAR_TIME } from './constants';
|
|
5
|
+
import { WHATSAPP_BACKDROP_PADDING, WHATSAPP_BACKDROP_WIDTH, WHATSAPP_BUBBLE_PADDING } from './constants';
|
|
10
6
|
import { isMessageDrawable } from './helpers';
|
|
11
|
-
import { WhatsAppWallpaperPattern } from './icons';
|
|
12
7
|
import { Lang } from './polyglot';
|
|
13
|
-
import {
|
|
8
|
+
import { Backdrop, Bubble, PreviewText } from './styles';
|
|
14
9
|
import { Spinner } from '../Spinner';
|
|
15
|
-
/** Renders a WhatsApp
|
|
10
|
+
/** Renders a WhatsApp message the way the recipient sees it, WhatsApp markup and attachments included. */
|
|
16
11
|
export function WhatsAppPreview(props) {
|
|
17
12
|
const {
|
|
18
|
-
|
|
19
|
-
contactName = '',
|
|
20
|
-
contactSubtitle,
|
|
21
|
-
avatarUrl,
|
|
22
|
-
dateLabel,
|
|
23
|
-
statusBarTime = WHATSAPP_STATUS_BAR_TIME,
|
|
24
|
-
wallpaperUrl,
|
|
13
|
+
message,
|
|
25
14
|
emptyText,
|
|
26
|
-
width = WHATSAPP_PREVIEW_WIDTH,
|
|
27
|
-
height = WHATSAPP_PREVIEW_HEIGHT,
|
|
28
15
|
isLoading = false
|
|
29
16
|
} = props;
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"$
|
|
36
|
-
"$width":
|
|
37
|
-
children:
|
|
38
|
-
"$
|
|
39
|
-
"$
|
|
40
|
-
"$
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
17
|
+
const isDrawable = message !== undefined && isMessageDrawable(message);
|
|
18
|
+
return _jsxs(Backdrop, {
|
|
19
|
+
"$alignContent": "start",
|
|
20
|
+
"$bgColor": Color.SOFT_LIGHT,
|
|
21
|
+
"$borderRadius": ShapeRadius.SECTION,
|
|
22
|
+
"$padding": WHATSAPP_BACKDROP_PADDING,
|
|
23
|
+
"$width": WHATSAPP_BACKDROP_WIDTH,
|
|
24
|
+
children: [isLoading && _jsx(Horizontal, {
|
|
25
|
+
"$alignItems": "center",
|
|
26
|
+
"$justifyContent": "center",
|
|
27
|
+
"$padding": WHATSAPP_BUBBLE_PADDING,
|
|
28
|
+
children: _jsx(Spinner, {
|
|
29
|
+
color: Color.LOCKED,
|
|
30
|
+
size: "medium"
|
|
31
|
+
})
|
|
32
|
+
}), !isLoading && !isDrawable && _jsx(Bubble, {
|
|
33
|
+
children: _jsx(PreviewText, {
|
|
34
|
+
"$color": Color.LOCKED,
|
|
35
|
+
"$ellipsis": true,
|
|
36
|
+
children: emptyText ?? _jsx(Lang, {
|
|
37
|
+
message: "DUMB.WHATSAPP_PREVIEW.EMPTY"
|
|
49
38
|
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
children: [_jsx(WallpaperLayer, {
|
|
55
|
-
children: wallpaperUrl ? _jsx(WallpaperImage, {
|
|
56
|
-
alt: "",
|
|
57
|
-
src: wallpaperUrl
|
|
58
|
-
}) : _jsx(WhatsAppWallpaperPattern, {})
|
|
59
|
-
}), isLoading && _jsx(Horizontal, {
|
|
60
|
-
"$alignItems": "center",
|
|
61
|
-
"$inset": 0,
|
|
62
|
-
"$justifyContent": "center",
|
|
63
|
-
"$position": "absolute",
|
|
64
|
-
children: _jsx(Spinner, {
|
|
65
|
-
color: Color.LOCKED,
|
|
66
|
-
size: "medium"
|
|
67
|
-
})
|
|
68
|
-
}), !isLoading && drawnMessages.length === 0 && _jsx(Horizontal, {
|
|
69
|
-
"$alignItems": "center",
|
|
70
|
-
"$inset": 0,
|
|
71
|
-
"$justifyContent": "center",
|
|
72
|
-
"$padding": 24,
|
|
73
|
-
"$position": "absolute",
|
|
74
|
-
children: _jsx(Text, {
|
|
75
|
-
"$color": WHATSAPP_COLOR.SUBTITLE,
|
|
76
|
-
"$variant": "footnote",
|
|
77
|
-
children: emptyText ?? _jsx(Lang, {
|
|
78
|
-
message: "DUMB.WHATSAPP_PREVIEW.EMPTY"
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
}), !isLoading && drawnMessages.length > 0 && _jsx(Vertical, {
|
|
82
|
-
"$inset": 0,
|
|
83
|
-
"$overflowY": "auto",
|
|
84
|
-
"$position": "absolute",
|
|
85
|
-
children: _jsxs(Vertical, {
|
|
86
|
-
"$alignContent": "start",
|
|
87
|
-
"$gap": 8,
|
|
88
|
-
"$minHeight": "100%",
|
|
89
|
-
"$padding": {
|
|
90
|
-
top: 12,
|
|
91
|
-
right: 9,
|
|
92
|
-
bottom: 16,
|
|
93
|
-
left: 9
|
|
94
|
-
},
|
|
95
|
-
children: [separator && _jsx(WhatsAppDateChip, {
|
|
96
|
-
children: separator
|
|
97
|
-
}), drawnMessages.map((message, index) => _jsx(WhatsAppMessageBubble, {
|
|
98
|
-
message: message
|
|
99
|
-
}, message.id ?? index))]
|
|
100
|
-
})
|
|
101
|
-
})]
|
|
102
|
-
})]
|
|
103
|
-
})
|
|
39
|
+
})
|
|
40
|
+
}), !isLoading && isDrawable && _jsx(WhatsAppMessageBubble, {
|
|
41
|
+
message: message
|
|
42
|
+
})]
|
|
104
43
|
});
|
|
105
44
|
}
|
|
@@ -53,6 +53,18 @@ describe('attachment meta', () => {
|
|
|
53
53
|
source: SOURCE
|
|
54
54
|
})).toBe('');
|
|
55
55
|
});
|
|
56
|
+
it('falls back to the MIME subtype when the name has no extension', () => {
|
|
57
|
+
expect(getAttachmentExtension({
|
|
58
|
+
name: 'Title',
|
|
59
|
+
source: SOURCE,
|
|
60
|
+
mimeType: 'application/PDF'
|
|
61
|
+
})).toBe('pdf');
|
|
62
|
+
expect(getAttachmentExtension({
|
|
63
|
+
name: 'Title.docx',
|
|
64
|
+
source: SOURCE,
|
|
65
|
+
mimeType: 'application/pdf'
|
|
66
|
+
})).toBe('docx');
|
|
67
|
+
});
|
|
56
68
|
it('writes sizes the way WhatsApp does', () => {
|
|
57
69
|
expect(formatAttachmentSize(912)).toBe('912 B');
|
|
58
70
|
expect(formatAttachmentSize(69_632)).toBe('68 kB');
|
|
@@ -70,28 +82,22 @@ describe('attachment meta', () => {
|
|
|
70
82
|
describe('isMessageDrawable', () => {
|
|
71
83
|
it('keeps a message that has a body or a file', () => {
|
|
72
84
|
expect(isMessageDrawable({
|
|
73
|
-
direction: 'incoming',
|
|
74
85
|
text: 'hi'
|
|
75
86
|
})).toBe(true);
|
|
76
87
|
expect(isMessageDrawable({
|
|
77
|
-
|
|
78
|
-
attachment: {
|
|
88
|
+
attachments: [{
|
|
79
89
|
name: 'a.jpg',
|
|
80
90
|
source: SOURCE
|
|
81
|
-
}
|
|
91
|
+
}]
|
|
82
92
|
})).toBe(true);
|
|
83
93
|
});
|
|
84
94
|
it('drops a message with nothing to show', () => {
|
|
95
|
+
expect(isMessageDrawable({})).toBe(false);
|
|
85
96
|
expect(isMessageDrawable({
|
|
86
|
-
|
|
87
|
-
time: '11:06'
|
|
88
|
-
})).toBe(false);
|
|
89
|
-
expect(isMessageDrawable({
|
|
90
|
-
direction: 'incoming',
|
|
91
|
-
attachment: {
|
|
97
|
+
attachments: [{
|
|
92
98
|
name: 'a.jpg',
|
|
93
99
|
source: ''
|
|
94
|
-
}
|
|
100
|
+
}]
|
|
95
101
|
})).toBe(false);
|
|
96
102
|
});
|
|
97
103
|
});
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { DocumentBox, DocumentGlyph, MediaBox, MediaDuration,
|
|
6
|
-
import { WHATSAPP_COLOR } from '../../constants';
|
|
3
|
+
import { Color } from '@pushwoosh/kit-constants';
|
|
4
|
+
import { Columns, Vertical } from '@pushwoosh/kit-helpers';
|
|
5
|
+
import { DocumentBox, DocumentGlyph, DocumentThumbnail, MediaBox, MediaDuration, MediaOverlay, PlayButton, PlayGlyph } from './styles';
|
|
7
6
|
import { formatAttachmentDuration, formatAttachmentSize, getAttachmentExtension, resolveAttachmentKind, toVideoPosterSource } from '../../helpers';
|
|
8
7
|
import { WhatsAppDocumentIcon, WhatsAppPlayIcon, WhatsAppVideoIcon } from '../../icons';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
doc: WHATSAPP_COLOR.DOCUMENT_TEXT,
|
|
12
|
-
docx: WHATSAPP_COLOR.DOCUMENT_TEXT
|
|
13
|
-
};
|
|
8
|
+
import { useLang } from '../../polyglot';
|
|
9
|
+
import { PreviewText } from '../../styles';
|
|
14
10
|
/** Draws an attached file inside a chat bubble: image, video with its play badge, or a document card. */
|
|
15
11
|
export function WhatsAppAttachment(props) {
|
|
16
12
|
const {
|
|
17
|
-
attachment
|
|
18
|
-
meta,
|
|
19
|
-
hasCaption = false
|
|
13
|
+
attachment
|
|
20
14
|
} = props;
|
|
21
15
|
const {
|
|
22
16
|
name,
|
|
23
17
|
source,
|
|
24
18
|
size,
|
|
25
|
-
duration
|
|
19
|
+
duration,
|
|
20
|
+
thumbnailSource,
|
|
21
|
+
pageCount
|
|
26
22
|
} = attachment;
|
|
23
|
+
const lang = useLang();
|
|
27
24
|
const [readDuration, setReadDuration] = useState(null);
|
|
28
25
|
const kind = resolveAttachmentKind(attachment);
|
|
29
26
|
const extension = getAttachmentExtension(attachment);
|
|
@@ -34,24 +31,32 @@ export function WhatsAppAttachment(props) {
|
|
|
34
31
|
setReadDuration(Number.isFinite(length) ? length : null);
|
|
35
32
|
}, []);
|
|
36
33
|
if (kind === 'document') {
|
|
37
|
-
const meaning = [
|
|
34
|
+
const meaning = [pageCount === undefined ? '' : lang({
|
|
35
|
+
message: 'DUMB.WHATSAPP_PREVIEW.DOCUMENT_PAGES',
|
|
36
|
+
count: pageCount
|
|
37
|
+
}), size === undefined ? '' : formatAttachmentSize(size), extension].filter(Boolean);
|
|
38
38
|
return _jsxs(DocumentBox, {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"$gap":
|
|
45
|
-
"$
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"$
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
children: [thumbnailSource && _jsx(DocumentThumbnail, {
|
|
40
|
+
alt: name,
|
|
41
|
+
src: thumbnailSource
|
|
42
|
+
}), _jsxs(Columns, {
|
|
43
|
+
"$alignItems": "center",
|
|
44
|
+
"$gap": 10,
|
|
45
|
+
"$padding": "8px 10px",
|
|
46
|
+
"$sizes": "auto minmax(0, 1fr)",
|
|
47
|
+
"$width": "100%",
|
|
48
|
+
children: [_jsx(DocumentGlyph, {
|
|
49
|
+
children: _jsx(WhatsAppDocumentIcon, {})
|
|
50
|
+
}), _jsxs(Vertical, {
|
|
51
|
+
"$gap": 1,
|
|
52
|
+
"$minWidth": 0,
|
|
53
|
+
children: [_jsx(PreviewText, {
|
|
54
|
+
"$ellipsis": true,
|
|
55
|
+
children: name
|
|
56
|
+
}), meaning.length > 0 && _jsx(PreviewText, {
|
|
57
|
+
"$color": Color.LOCKED,
|
|
58
|
+
children: meaning.join(' • ')
|
|
59
|
+
})]
|
|
55
60
|
})]
|
|
56
61
|
})]
|
|
57
62
|
});
|
|
@@ -59,8 +64,8 @@ export function WhatsAppAttachment(props) {
|
|
|
59
64
|
const length = duration ?? readDuration;
|
|
60
65
|
const isVideo = kind === 'video';
|
|
61
66
|
return _jsxs(MediaBox, {
|
|
62
|
-
"$
|
|
63
|
-
children: [isVideo ? _jsx("video", {
|
|
67
|
+
"$hasOverlay": isVideo,
|
|
68
|
+
children: [isVideo && !thumbnailSource ? _jsx("video", {
|
|
64
69
|
muted: true,
|
|
65
70
|
playsInline: true,
|
|
66
71
|
onLoadedMetadata: handleLoadedMetadata,
|
|
@@ -68,17 +73,15 @@ export function WhatsAppAttachment(props) {
|
|
|
68
73
|
src: toVideoPosterSource(source)
|
|
69
74
|
}) : _jsx("img", {
|
|
70
75
|
alt: name,
|
|
71
|
-
src: source
|
|
76
|
+
src: thumbnailSource ?? source
|
|
72
77
|
}), isVideo && _jsx(PlayButton, {
|
|
73
78
|
children: _jsx(PlayGlyph, {
|
|
74
79
|
children: _jsx(WhatsAppPlayIcon, {})
|
|
75
80
|
})
|
|
76
|
-
}),
|
|
77
|
-
children:
|
|
81
|
+
}), isVideo && _jsx(MediaOverlay, {
|
|
82
|
+
children: _jsxs(MediaDuration, {
|
|
78
83
|
children: [_jsx(WhatsAppVideoIcon, {}), length === null ? null : formatAttachmentDuration(length)]
|
|
79
|
-
})
|
|
80
|
-
children: meta
|
|
81
|
-
})]
|
|
84
|
+
})
|
|
82
85
|
})]
|
|
83
86
|
});
|
|
84
87
|
}
|
|
@@ -12,9 +12,11 @@ export declare const MediaBox: import("styled-components").StyledComponent<"div"
|
|
|
12
12
|
} & {
|
|
13
13
|
$position: string;
|
|
14
14
|
$bgColor: "#0B141A";
|
|
15
|
+
$borderRadius: number;
|
|
16
|
+
$justifyItems: string;
|
|
15
17
|
} & {
|
|
16
|
-
$
|
|
17
|
-
}, "$gridAutoFlow" | "$bgColor" | "$position">;
|
|
18
|
+
$hasOverlay: boolean;
|
|
19
|
+
}, "$gridAutoFlow" | "$bgColor" | "$borderRadius" | "$position" | "$justifyItems">;
|
|
18
20
|
export declare const PlayButton: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
19
21
|
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
20
22
|
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
@@ -61,18 +63,16 @@ export declare const MediaOverlay: import("styled-components").StyledComponent<"
|
|
|
61
63
|
$justifyItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
62
64
|
$placeItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
63
65
|
} & {
|
|
64
|
-
$
|
|
66
|
+
$gridAutoFlow: string;
|
|
65
67
|
} & {
|
|
66
68
|
$alignItems: string;
|
|
67
|
-
$gap: number;
|
|
68
|
-
$sizes: string;
|
|
69
69
|
$padding: {
|
|
70
70
|
top: number;
|
|
71
71
|
right: number;
|
|
72
72
|
bottom: number;
|
|
73
73
|
left: number;
|
|
74
74
|
};
|
|
75
|
-
}, "$
|
|
75
|
+
}, "$gridAutoFlow" | "$padding" | "$alignItems">;
|
|
76
76
|
export declare const MediaDuration: import("styled-components").StyledComponent<"span", any, {
|
|
77
77
|
$color?: string | undefined;
|
|
78
78
|
$uppercase?: boolean | undefined;
|
|
@@ -82,20 +82,6 @@ export declare const MediaDuration: import("styled-components").StyledComponent<
|
|
|
82
82
|
$variant: "footnote";
|
|
83
83
|
$color: "#FFFFFF";
|
|
84
84
|
}, "$color" | "$variant">;
|
|
85
|
-
export declare const MediaMeta: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
86
|
-
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
87
|
-
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
88
|
-
$gap?: import("@pushwoosh/kit-helpers/styled-helpers").StrNum | undefined;
|
|
89
|
-
$justifyContent?: import("@pushwoosh/kit-helpers/styled-helpers").JustifyContentValue | undefined;
|
|
90
|
-
} & {
|
|
91
|
-
$gridAutoFlow?: "row" | "column" | "dense" | "row dense" | "column dense" | undefined;
|
|
92
|
-
$justifyItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
93
|
-
$placeItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
94
|
-
} & {
|
|
95
|
-
$gridAutoFlow: string;
|
|
96
|
-
} & {
|
|
97
|
-
$justifyContent: string;
|
|
98
|
-
}, "$gridAutoFlow" | "$justifyContent">;
|
|
99
85
|
export declare const DocumentBox: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
100
86
|
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
101
87
|
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
@@ -106,16 +92,13 @@ export declare const DocumentBox: import("styled-components").StyledComponent<"d
|
|
|
106
92
|
$justifyItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
107
93
|
$placeItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
108
94
|
} & {
|
|
109
|
-
$
|
|
95
|
+
$gridAutoFlow: string;
|
|
110
96
|
} & {
|
|
111
|
-
$alignItems: string;
|
|
112
|
-
$gap: number;
|
|
113
|
-
$sizes: string;
|
|
114
|
-
$padding: string;
|
|
115
97
|
$bgColor: "#F5F6F6";
|
|
116
|
-
|
|
117
|
-
$
|
|
118
|
-
}, "$
|
|
98
|
+
$borderRadius: number;
|
|
99
|
+
$width: string;
|
|
100
|
+
}, "$gridAutoFlow" | "$bgColor" | "$borderRadius" | "$width">;
|
|
101
|
+
export declare const DocumentThumbnail: import("styled-components").StyledComponent<"img", any, {}, never>;
|
|
119
102
|
export declare const DocumentGlyph: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
120
103
|
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
121
104
|
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
@@ -127,6 +110,4 @@ export declare const DocumentGlyph: import("styled-components").StyledComponent<
|
|
|
127
110
|
$placeItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
128
111
|
} & {
|
|
129
112
|
$gridAutoFlow: string;
|
|
130
|
-
} & {
|
|
131
|
-
$color: string;
|
|
132
113
|
}, "$gridAutoFlow">;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import styled
|
|
2
|
-
import {
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Horizontal, Vertical } from '@pushwoosh/kit-helpers';
|
|
3
3
|
import { Text } from '@pushwoosh/kit-typography';
|
|
4
|
-
import { WHATSAPP_COLOR, WHATSAPP_MEDIA_MAX_HEIGHT } from '../../constants';
|
|
5
|
-
const bubbleInset = css(["margin:-3px -5px ", ";border-radius:6px;overflow:hidden;"], ({
|
|
6
|
-
$hasCaption
|
|
7
|
-
}) => $hasCaption ? '5px' : '-4px');
|
|
4
|
+
import { WHATSAPP_COLOR, WHATSAPP_MEDIA_MAX_HEIGHT, WHATSAPP_MEDIA_MIN_HEIGHT, WHATSAPP_MEDIA_RADIUS } from '../../constants';
|
|
8
5
|
export const MediaBox = styled(Vertical).attrs({
|
|
9
6
|
$position: 'relative',
|
|
10
|
-
$bgColor: WHATSAPP_COLOR.MEDIA_BACKDROP
|
|
7
|
+
$bgColor: WHATSAPP_COLOR.MEDIA_BACKDROP,
|
|
8
|
+
$borderRadius: WHATSAPP_MEDIA_RADIUS,
|
|
9
|
+
$justifyItems: 'start'
|
|
11
10
|
}).withConfig({
|
|
12
11
|
displayName: "MediaBox",
|
|
13
12
|
componentId: "sc-1uezfps-0"
|
|
14
|
-
})(["
|
|
13
|
+
})(["overflow:hidden;width:fit-content;max-width:100%;img,video{display:block;width:auto;max-width:100%;max-height:", "px;", "}"], WHATSAPP_MEDIA_MAX_HEIGHT, ({
|
|
14
|
+
$hasOverlay
|
|
15
|
+
}) => $hasOverlay ? `min-height: ${WHATSAPP_MEDIA_MIN_HEIGHT}px;` : '');
|
|
15
16
|
export const PlayButton = styled(Horizontal).attrs({
|
|
16
17
|
$alignItems: 'center',
|
|
17
18
|
$justifyContent: 'center',
|
|
@@ -32,20 +33,18 @@ export const PlayGlyph = styled(Horizontal).attrs({
|
|
|
32
33
|
displayName: "PlayGlyph",
|
|
33
34
|
componentId: "sc-1uezfps-2"
|
|
34
35
|
})(["color:", ";svg{display:block;margin-left:3px;}"], WHATSAPP_COLOR.PLAY_GLYPH);
|
|
35
|
-
export const MediaOverlay = styled(
|
|
36
|
+
export const MediaOverlay = styled(Horizontal).attrs({
|
|
36
37
|
$alignItems: 'end',
|
|
37
|
-
$gap: 8,
|
|
38
|
-
$sizes: 'auto minmax(0, 1fr)',
|
|
39
38
|
$padding: {
|
|
40
|
-
top:
|
|
39
|
+
top: 12,
|
|
41
40
|
right: 8,
|
|
42
|
-
bottom:
|
|
41
|
+
bottom: 4,
|
|
43
42
|
left: 8
|
|
44
43
|
}
|
|
45
44
|
}).withConfig({
|
|
46
45
|
displayName: "MediaOverlay",
|
|
47
46
|
componentId: "sc-1uezfps-3"
|
|
48
|
-
})(["position:absolute;right:0;bottom:0;left:0;background:linear-gradient(to top,", ",transparent);pointer-events:none;"], WHATSAPP_COLOR.MEDIA_SCRIM);
|
|
47
|
+
})(["position:absolute;right:0;bottom:0;left:0;max-height:100%;overflow:hidden;background:linear-gradient(to top,", ",transparent);pointer-events:none;"], WHATSAPP_COLOR.MEDIA_SCRIM);
|
|
49
48
|
export const MediaDuration = styled(Text).attrs({
|
|
50
49
|
$variant: 'footnote',
|
|
51
50
|
$color: WHATSAPP_COLOR.MEDIA_META
|
|
@@ -53,25 +52,19 @@ export const MediaDuration = styled(Text).attrs({
|
|
|
53
52
|
displayName: "MediaDuration",
|
|
54
53
|
componentId: "sc-1uezfps-4"
|
|
55
54
|
})(["display:inline-flex;align-items:center;gap:4px;svg{display:block;}"]);
|
|
56
|
-
export const
|
|
57
|
-
$
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
componentId: "sc-1uezfps-5"
|
|
61
|
-
})(["color:", ";svg{color:", ";}"], WHATSAPP_COLOR.MEDIA_META, WHATSAPP_COLOR.MEDIA_META);
|
|
62
|
-
export const DocumentBox = styled(Columns).attrs({
|
|
63
|
-
$alignItems: 'center',
|
|
64
|
-
$gap: 10,
|
|
65
|
-
$sizes: 'auto minmax(0, 1fr)',
|
|
66
|
-
$padding: '8px 10px',
|
|
67
|
-
$bgColor: WHATSAPP_COLOR.DOCUMENT_CARD
|
|
55
|
+
export const DocumentBox = styled(Vertical).attrs({
|
|
56
|
+
$bgColor: WHATSAPP_COLOR.DOCUMENT_CARD,
|
|
57
|
+
$borderRadius: WHATSAPP_MEDIA_RADIUS,
|
|
58
|
+
$width: '100%'
|
|
68
59
|
}).withConfig({
|
|
69
60
|
displayName: "DocumentBox",
|
|
61
|
+
componentId: "sc-1uezfps-5"
|
|
62
|
+
})(["overflow:hidden;"]);
|
|
63
|
+
export const DocumentThumbnail = styled.img.withConfig({
|
|
64
|
+
displayName: "DocumentThumbnail",
|
|
70
65
|
componentId: "sc-1uezfps-6"
|
|
71
|
-
})(["", ""],
|
|
66
|
+
})(["display:block;width:100%;max-height:", "px;object-fit:cover;"], WHATSAPP_MEDIA_MAX_HEIGHT);
|
|
72
67
|
export const DocumentGlyph = styled(Horizontal).withConfig({
|
|
73
68
|
displayName: "DocumentGlyph",
|
|
74
69
|
componentId: "sc-1uezfps-7"
|
|
75
|
-
})(["color:", ";svg{display:block;}"],
|
|
76
|
-
$color
|
|
77
|
-
}) => $color);
|
|
70
|
+
})(["color:", ";svg{display:block;}"], WHATSAPP_COLOR.DOCUMENT_GLYPH);
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
1
|
import type { WhatsAppAttachment } from '../../types';
|
|
3
2
|
/** Props of {@link WhatsAppAttachment}. */
|
|
4
3
|
export interface WhatsAppAttachmentProps {
|
|
5
4
|
/** File to draw. */
|
|
6
5
|
attachment: WhatsAppAttachment;
|
|
7
|
-
/** Time and ticks overlaid on the media; pass it only when the bubble has no caption below. */
|
|
8
|
-
meta?: ReactNode;
|
|
9
|
-
/** Keep the bottom inset of the bubble instead of hugging its padding. */
|
|
10
|
-
hasCaption?: boolean;
|
|
11
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { WhatsAppMessageBubbleProps } from './types';
|
|
3
|
-
/** Single chat bubble:
|
|
3
|
+
/** Single chat bubble: attachments on top, message body underneath. */
|
|
4
4
|
export declare function WhatsAppMessageBubble(props: WhatsAppMessageBubbleProps): ReactElement;
|