@memori.ai/memori-react 9.0.0-alpha.23 → 9.0.0-alpha.25
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/CHANGELOG.md +300 -1100
- package/dist/components/AgeVerificationModal/AgeVerificationModal.js +1 -3
- package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
- package/dist/components/Auth/Auth.js +1 -3
- package/dist/components/Auth/Auth.js.map +1 -1
- package/dist/components/Chat/Chat.css +10 -1
- package/dist/components/Chat/Chat.js +1 -3
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatBubble/ChatBubble.css +103 -5
- package/dist/components/ChatBubble/ChatBubble.js +48 -8
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatHistory.js +1 -3
- package/dist/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js +2 -4
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js.map +1 -1
- package/dist/components/ChatInputs/ChatInputs.css +17 -52
- package/dist/components/ChatInputs/ChatInputs.js +1 -3
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
- package/dist/components/ContentPreviewModal/ContentPreviewModal.js +1 -3
- package/dist/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -1
- package/dist/components/DateSelector/DateSelector.css +66 -3
- package/dist/components/DateSelector/DateSelector.js +5 -1
- package/dist/components/DateSelector/DateSelector.js.map +1 -1
- package/dist/components/ExpertsDrawer/ExpertsDrawer.js +1 -3
- package/dist/components/ExpertsDrawer/ExpertsDrawer.js.map +1 -1
- package/dist/components/FilePreview/FilePreview.css +94 -220
- package/dist/components/FilePreview/FilePreview.js +25 -71
- package/dist/components/FilePreview/FilePreview.js.map +1 -1
- package/dist/components/IconButton/IconButton.css +2 -11
- package/dist/components/KnownFacts/KnownFacts.css +3 -4
- package/dist/components/KnownFacts/KnownFacts.js +3 -5
- package/dist/components/KnownFacts/KnownFacts.js.map +1 -1
- package/dist/components/LoginDrawer/LoginDrawer.css +3 -7
- package/dist/components/LoginDrawer/LoginDrawer.js +51 -9
- package/dist/components/LoginDrawer/LoginDrawer.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.css +77 -57
- package/dist/components/MediaWidget/MediaItemWidget.js +4 -4
- package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -5
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.css +0 -55
- package/dist/components/MemoriWidget/MemoriWidget.js +115 -117
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
- package/dist/components/MobileSessionPanel/MobileSessionPanel.js +77 -117
- package/dist/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
- package/dist/components/PositionPopover/PositionPopover.css +1 -1
- package/dist/components/SettingsDrawer/SettingsDrawer.js +1 -3
- package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.css +12 -1
- package/dist/components/StartPanel/StartPanel.js +30 -7
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/dist/components/UploadButton/UploadButton.css +7 -7
- package/dist/components/UploadButton/UploadButton.js +3 -0
- package/dist/components/UploadButton/UploadButton.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +15 -5
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/components/UploadButton/UploadImages/UploadImages.js +1 -3
- package/dist/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
- package/dist/components/WhyThisAnswer/WhyThisAnswer.js +1 -3
- package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
- package/dist/components/layouts/HiddenChat.js +9 -1
- package/dist/components/layouts/HiddenChat.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js +84 -5
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
- package/dist/components/layouts/fullpage.css +1 -0
- package/dist/components/layouts/hidden-chat.css +29 -5
- package/dist/helpers/constants.d.ts +3 -2
- package/dist/helpers/constants.js +19 -20
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/error.js +2 -1
- package/dist/helpers/error.js.map +1 -1
- package/dist/helpers/positionPopover.d.ts +1 -0
- package/dist/helpers/positionPopover.js +7 -0
- package/dist/helpers/positionPopover.js.map +1 -1
- package/dist/helpers/usePressTooltip.d.ts +6 -1
- package/dist/helpers/usePressTooltip.js +16 -1
- package/dist/helpers/usePressTooltip.js.map +1 -1
- package/dist/helpers/utils.d.ts +2 -1
- package/dist/helpers/utils.js +7 -1
- package/dist/helpers/utils.js.map +1 -1
- package/dist/locales/de.json +8 -2
- package/dist/locales/en.json +6 -3
- package/dist/locales/es.json +6 -3
- package/dist/locales/fr.json +6 -3
- package/dist/locales/it.json +6 -3
- package/dist/styles.css +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/AgeVerificationModal/AgeVerificationModal.js +1 -3
- package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
- package/esm/components/Auth/Auth.js +1 -3
- package/esm/components/Auth/Auth.js.map +1 -1
- package/esm/components/Chat/Chat.css +10 -1
- package/esm/components/Chat/Chat.js +1 -3
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/ChatBubble/ChatBubble.css +103 -5
- package/esm/components/ChatBubble/ChatBubble.js +48 -8
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/ChatHistoryDrawer/ChatHistory.js +1 -3
- package/esm/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
- package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.js +2 -4
- package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.js.map +1 -1
- package/esm/components/ChatInputs/ChatInputs.css +17 -52
- package/esm/components/ChatInputs/ChatInputs.js +1 -3
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
- package/esm/components/ContentPreviewModal/ContentPreviewModal.js +1 -3
- package/esm/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -1
- package/esm/components/DateSelector/DateSelector.css +66 -3
- package/esm/components/DateSelector/DateSelector.js +5 -1
- package/esm/components/DateSelector/DateSelector.js.map +1 -1
- package/esm/components/ExpertsDrawer/ExpertsDrawer.js +1 -3
- package/esm/components/ExpertsDrawer/ExpertsDrawer.js.map +1 -1
- package/esm/components/FilePreview/FilePreview.css +94 -220
- package/esm/components/FilePreview/FilePreview.js +25 -71
- package/esm/components/FilePreview/FilePreview.js.map +1 -1
- package/esm/components/IconButton/IconButton.css +2 -11
- package/esm/components/KnownFacts/KnownFacts.css +3 -4
- package/esm/components/KnownFacts/KnownFacts.js +3 -5
- package/esm/components/KnownFacts/KnownFacts.js.map +1 -1
- package/esm/components/LoginDrawer/LoginDrawer.css +3 -7
- package/esm/components/LoginDrawer/LoginDrawer.js +51 -9
- package/esm/components/LoginDrawer/LoginDrawer.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.css +77 -57
- package/esm/components/MediaWidget/MediaItemWidget.js +5 -5
- package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -5
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.css +0 -55
- package/esm/components/MemoriWidget/MemoriWidget.js +115 -117
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
- package/esm/components/MobileSessionPanel/MobileSessionPanel.js +78 -118
- package/esm/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
- package/esm/components/PositionPopover/PositionPopover.css +1 -1
- package/esm/components/SettingsDrawer/SettingsDrawer.js +1 -3
- package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.css +12 -1
- package/esm/components/StartPanel/StartPanel.js +30 -7
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/UploadButton/UploadButton.css +7 -7
- package/esm/components/UploadButton/UploadButton.js +4 -1
- package/esm/components/UploadButton/UploadButton.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +17 -7
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/components/UploadButton/UploadImages/UploadImages.js +1 -3
- package/esm/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
- package/esm/components/WhyThisAnswer/WhyThisAnswer.js +1 -3
- package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
- package/esm/components/layouts/HiddenChat.js +9 -1
- package/esm/components/layouts/HiddenChat.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js +85 -6
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
- package/esm/components/layouts/fullpage.css +1 -0
- package/esm/components/layouts/hidden-chat.css +29 -5
- package/esm/helpers/constants.d.ts +3 -2
- package/esm/helpers/constants.js +18 -19
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/error.js +2 -1
- package/esm/helpers/error.js.map +1 -1
- package/esm/helpers/positionPopover.d.ts +1 -0
- package/esm/helpers/positionPopover.js +6 -0
- package/esm/helpers/positionPopover.js.map +1 -1
- package/esm/helpers/usePressTooltip.d.ts +6 -1
- package/esm/helpers/usePressTooltip.js +17 -2
- package/esm/helpers/usePressTooltip.js.map +1 -1
- package/esm/helpers/utils.d.ts +2 -1
- package/esm/helpers/utils.js +6 -1
- package/esm/helpers/utils.js.map +1 -1
- package/esm/locales/de.json +8 -2
- package/esm/locales/en.json +6 -3
- package/esm/locales/es.json +6 -3
- package/esm/locales/fr.json +6 -3
- package/esm/locales/it.json +6 -3
- package/esm/styles.css +1 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +4 -46
- package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +0 -3
- package/src/components/Auth/Auth.tsx +0 -3
- package/src/components/Auth/__snapshots__/Auth.test.tsx.snap +1 -0
- package/src/components/BlockedMemoriBadge/__snapshots__/BlockedMemoriBadge.test.tsx.snap +5 -0
- package/src/components/Chat/Chat.css +10 -1
- package/src/components/Chat/Chat.tsx +0 -3
- package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +1735 -1765
- package/src/components/ChatBubble/ChatBubble.css +103 -5
- package/src/components/ChatBubble/ChatBubble.test.tsx +33 -0
- package/src/components/ChatBubble/ChatBubble.tsx +524 -273
- package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +655 -684
- package/src/components/ChatHistoryDrawer/ChatHistory.tsx +0 -3
- package/src/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
- package/src/components/ChatHistoryDrawer/ChatResumeDrawer.tsx +3 -6
- package/src/components/ChatInputs/ChatInputs.css +17 -52
- package/src/components/ChatInputs/ChatInputs.tsx +2 -4
- package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +3 -0
- package/src/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
- package/src/components/ContentPreviewModal/ContentPreviewModal.tsx +0 -3
- package/src/components/DateSelector/DateSelector.css +66 -3
- package/src/components/DateSelector/DateSelector.test.tsx +33 -4
- package/src/components/DateSelector/DateSelector.tsx +37 -11
- package/src/components/ExpertsDrawer/ExpertsDrawer.tsx +0 -3
- package/src/components/FeedbackButtons/__snapshots__/FeedbackButtons.test.tsx.snap +2 -1
- package/src/components/FilePreview/FilePreview.css +94 -220
- package/src/components/FilePreview/FilePreview.tsx +77 -124
- package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +33 -81
- package/src/components/Header/ChatConsumptionDropdown.test.tsx +53 -86
- package/src/components/Header/__snapshots__/Header.test.tsx.snap +60 -44
- package/src/components/IconButton/IconButton.css +2 -11
- package/src/components/KnownFacts/KnownFacts.css +3 -4
- package/src/components/KnownFacts/KnownFacts.tsx +0 -5
- package/src/components/KnownFacts/__snapshots__/KnownFacts.test.tsx.snap +2 -6
- package/src/components/LoginDrawer/LoginDrawer.css +3 -7
- package/src/components/LoginDrawer/LoginDrawer.tsx +101 -54
- package/src/components/LoginDrawer/__snapshots__/LoginDrawer.test.tsx.snap +11 -33
- package/src/components/MediaWidget/MediaItemWidget.css +77 -57
- package/src/components/MediaWidget/MediaItemWidget.test.tsx +33 -0
- package/src/components/MediaWidget/MediaItemWidget.tsx +6 -12
- package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +2 -0
- package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +1 -1
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +0 -5
- package/src/components/MemoriWidget/MemoriUIProvider.contract.test.tsx +25 -7
- package/src/components/MemoriWidget/MemoriWidget.css +0 -55
- package/src/components/MemoriWidget/MemoriWidget.tsx +18 -12
- package/src/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
- package/src/components/MobileSessionPanel/MobileSessionPanel.tsx +29 -68
- package/src/components/PositionPopover/PositionPopover.css +1 -1
- package/src/components/SettingsDrawer/SettingsDrawer.tsx +0 -3
- package/src/components/ShareButton/__snapshots__/ShareButton.test.tsx.snap +9 -9
- package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +8 -0
- package/src/components/StartPanel/StartPanel.css +12 -1
- package/src/components/StartPanel/StartPanel.test.tsx +57 -0
- package/src/components/StartPanel/StartPanel.tsx +41 -4
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +41 -6
- package/src/components/UploadButton/UploadButton.css +7 -7
- package/src/components/UploadButton/UploadButton.tsx +4 -0
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +21 -8
- package/src/components/UploadButton/UploadImages/UploadImages.tsx +0 -3
- package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +10 -12
- package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +0 -3
- package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +3 -9
- package/src/components/layouts/HiddenChat.tsx +9 -1
- package/src/components/layouts/WebsiteAssistant/WebsiteAssistant.tsx +103 -6
- package/src/components/layouts/WebsiteAssistant/__snapshots__/WebsiteAssistant.test.tsx.snap +63 -57
- package/src/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
- package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +7 -4
- package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +12 -8
- package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +7 -4
- package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +10 -5
- package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +6 -4
- package/src/components/layouts/fullpage.css +1 -0
- package/src/components/layouts/hidden-chat.css +29 -5
- package/src/components/layouts/layouts.stories.tsx +2 -2
- package/src/helpers/constants.ts +21 -20
- package/src/helpers/error.ts +2 -1
- package/src/helpers/positionPopover.test.ts +15 -0
- package/src/helpers/positionPopover.ts +16 -0
- package/src/helpers/usePressTooltip.test.ts +30 -0
- package/src/helpers/usePressTooltip.ts +31 -1
- package/src/helpers/utils.test.ts +14 -4
- package/src/helpers/utils.ts +6 -1
- package/src/index.tsx +1 -1
- package/src/locales/de.json +8 -2
- package/src/locales/en.json +6 -3
- package/src/locales/es.json +6 -3
- package/src/locales/fr.json +6 -3
- package/src/locales/it.json +6 -3
- package/src/styles.brandTokens.test.js +52 -0
- package/src/styles.css +27 -2
- package/src/version.ts +1 -1
- package/dist/context/widgetSurfaceContext.d.ts +0 -3
- package/dist/context/widgetSurfaceContext.js +0 -11
- package/dist/context/widgetSurfaceContext.js.map +0 -1
- package/esm/context/widgetSurfaceContext.d.ts +0 -3
- package/esm/context/widgetSurfaceContext.js +0 -7
- package/esm/context/widgetSurfaceContext.js.map +0 -1
- package/src/context/widgetSurfaceContext.tsx +0 -14
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
Field,
|
|
13
13
|
} from '@memori.ai/ui';
|
|
14
14
|
import { useTranslation } from 'react-i18next';
|
|
15
|
-
import { useWidgetSurfaceEl } from '../../context/widgetSurfaceContext';
|
|
16
15
|
import cx from 'classnames';
|
|
17
16
|
import memoriApiClient from '@memori.ai/memori-api-client';
|
|
18
17
|
import { getErrori18nKey } from '../../helpers/error';
|
|
@@ -52,7 +51,6 @@ const LoginDrawer = ({
|
|
|
52
51
|
__TEST__signup = false,
|
|
53
52
|
__TEST__needMissingData = false,
|
|
54
53
|
}: Props) => {
|
|
55
|
-
const surfaceEl = useWidgetSurfaceEl();
|
|
56
54
|
const { t, i18n } = useTranslation();
|
|
57
55
|
const { add } = useAlertManager();
|
|
58
56
|
const lang = i18n.language === 'it' ? 'it' : 'en';
|
|
@@ -77,6 +75,9 @@ const LoginDrawer = ({
|
|
|
77
75
|
const [showOtpForm, setShowOtpForm] = useState(true);
|
|
78
76
|
const [showOtpCodeForm, setShowOtpCodeForm] = useState(false);
|
|
79
77
|
const [otpTimer, setOtpTimer] = useState<number | null>(null);
|
|
78
|
+
const [otpResendCooldown, setOtpResendCooldown] = useState<number | null>(
|
|
79
|
+
null
|
|
80
|
+
);
|
|
80
81
|
const [otpSent, setOtpSent] = useState(false);
|
|
81
82
|
const [avatar, setAvatar] = useState<Blob | null>(null);
|
|
82
83
|
const [isResending, setIsResending] = useState(false);
|
|
@@ -105,7 +106,7 @@ const LoginDrawer = ({
|
|
|
105
106
|
: ({} as any)
|
|
106
107
|
);
|
|
107
108
|
|
|
108
|
-
// OTP timer
|
|
109
|
+
// OTP validity timer (5 minutes, matches backend)
|
|
109
110
|
useEffect(() => {
|
|
110
111
|
let interval: NodeJS.Timeout;
|
|
111
112
|
if (otpTimer != null && otpTimer > 0) {
|
|
@@ -126,6 +127,27 @@ const LoginDrawer = ({
|
|
|
126
127
|
}
|
|
127
128
|
}, [otpTimer, otpSuccess, t]);
|
|
128
129
|
|
|
130
|
+
// Resend cooldown (60s), independent from OTP validity
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
let interval: NodeJS.Timeout;
|
|
133
|
+
if (otpResendCooldown != null && otpResendCooldown > 0) {
|
|
134
|
+
interval = setInterval(() => {
|
|
135
|
+
setOtpResendCooldown(prev =>
|
|
136
|
+
prev != null && prev > 0 ? prev - 1 : 0
|
|
137
|
+
);
|
|
138
|
+
}, 1000);
|
|
139
|
+
}
|
|
140
|
+
return () => {
|
|
141
|
+
if (interval) clearInterval(interval);
|
|
142
|
+
};
|
|
143
|
+
}, [otpResendCooldown]);
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (otpResendCooldown === 0) {
|
|
147
|
+
setOtpResendCooldown(null);
|
|
148
|
+
}
|
|
149
|
+
}, [otpResendCooldown]);
|
|
150
|
+
|
|
129
151
|
useEffect(() => {
|
|
130
152
|
const mediaQuery = window.matchMedia('(max-width: 768px)');
|
|
131
153
|
const onChange = () => setIsMobileViewport(mediaQuery.matches);
|
|
@@ -257,8 +279,24 @@ const LoginDrawer = ({
|
|
|
257
279
|
setOtpError(t('login.otpNotFound'));
|
|
258
280
|
} else if (response.resultCode === -108) {
|
|
259
281
|
setOtpError(t('login.otpExpired'));
|
|
282
|
+
setOtpTimer(null);
|
|
283
|
+
setOtpResendCooldown(null);
|
|
260
284
|
} else if (response.resultCode === -109) {
|
|
261
|
-
|
|
285
|
+
// Wrong code on 1st/2nd attempt — allow retry
|
|
286
|
+
setOtpError(t('login.otpInvalid'));
|
|
287
|
+
setOtpCode('');
|
|
288
|
+
setOtpFocusedIndex(0);
|
|
289
|
+
window.setTimeout(() => {
|
|
290
|
+
otpInputRefs.current[0]?.focus();
|
|
291
|
+
}, 50);
|
|
292
|
+
} else if (response.resultCode === -110) {
|
|
293
|
+
// 3rd wrong attempt — OTP invalidated, need a new LoginWithOTP
|
|
294
|
+
setOtpError(t('login.otpAttemptsExceeded'));
|
|
295
|
+
setOtpCode('');
|
|
296
|
+
setOtpTimer(null);
|
|
297
|
+
setOtpResendCooldown(null);
|
|
298
|
+
setShowOtpCodeForm(false);
|
|
299
|
+
setOtpSent(false);
|
|
262
300
|
} else {
|
|
263
301
|
setOtpError(response.resultMessage || t('login.otpInvalid'));
|
|
264
302
|
}
|
|
@@ -392,9 +430,16 @@ const LoginDrawer = ({
|
|
|
392
430
|
}
|
|
393
431
|
};
|
|
394
432
|
|
|
395
|
-
|
|
433
|
+
const formatOtpTimer = (seconds: number) => {
|
|
434
|
+
const m = Math.floor(seconds / 60);
|
|
435
|
+
const s = seconds % 60;
|
|
436
|
+
return `${m}:${s.toString().padStart(2, '0')}`;
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
// Start OTP validity (5 min) + resend cooldown (60s)
|
|
396
440
|
const startOtpTimer = () => {
|
|
397
|
-
setOtpTimer(
|
|
441
|
+
setOtpTimer(300);
|
|
442
|
+
setOtpResendCooldown(60);
|
|
398
443
|
};
|
|
399
444
|
|
|
400
445
|
const updateMissingData = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
@@ -447,7 +492,6 @@ const LoginDrawer = ({
|
|
|
447
492
|
|
|
448
493
|
return (
|
|
449
494
|
<Drawer
|
|
450
|
-
container={surfaceEl ?? undefined}
|
|
451
495
|
open={open}
|
|
452
496
|
onClose={onClose}
|
|
453
497
|
className={cx('memori--login-drawer', {
|
|
@@ -500,49 +544,47 @@ const LoginDrawer = ({
|
|
|
500
544
|
|
|
501
545
|
{needsMissingData?.tnCAndPPAccepted && (
|
|
502
546
|
<>
|
|
503
|
-
<
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
{t('login.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
</span>
|
|
545
|
-
</label>
|
|
547
|
+
<Checkbox
|
|
548
|
+
name="tnCAndPPAccepted"
|
|
549
|
+
className="memori-login-drawer--consent"
|
|
550
|
+
checked={tnCAndPPAccepted}
|
|
551
|
+
onChange={checked => setTnCAndPPAccepted(checked)}
|
|
552
|
+
label={
|
|
553
|
+
<>
|
|
554
|
+
{t('login.privacyLabel')}{' '}
|
|
555
|
+
<a
|
|
556
|
+
href={`https://memori.ai/${lang}/privacy_and_cookie`}
|
|
557
|
+
target="_blank"
|
|
558
|
+
rel="noopener noreferrer"
|
|
559
|
+
>
|
|
560
|
+
{t('login.privacyAndCookiePolicy')}
|
|
561
|
+
</a>{' '}
|
|
562
|
+
{t('login.and')}{' '}
|
|
563
|
+
<a
|
|
564
|
+
href={`https://memori.ai/${lang}/tos`}
|
|
565
|
+
target="_blank"
|
|
566
|
+
rel="noopener noreferrer"
|
|
567
|
+
>
|
|
568
|
+
{t('login.termsOfService')}
|
|
569
|
+
</a>
|
|
570
|
+
</>
|
|
571
|
+
}
|
|
572
|
+
/>
|
|
573
|
+
|
|
574
|
+
<Checkbox
|
|
575
|
+
name="pAndCUAccepted"
|
|
576
|
+
className="memori-login-drawer--consent"
|
|
577
|
+
checked={pAndCUAccepted}
|
|
578
|
+
onChange={checked => setPAndCUAccepted(checked)}
|
|
579
|
+
label={
|
|
580
|
+
<>
|
|
581
|
+
{t('login.pAndCUAccepted')}{' '}
|
|
582
|
+
<small>
|
|
583
|
+
<em>({t('login.optional')})</em>
|
|
584
|
+
</small>
|
|
585
|
+
</>
|
|
586
|
+
}
|
|
587
|
+
/>
|
|
546
588
|
<p>
|
|
547
589
|
<small>{t('login.goToAccountToChangeYourPreferences')}</small>
|
|
548
590
|
</p>
|
|
@@ -649,8 +691,9 @@ const LoginDrawer = ({
|
|
|
649
691
|
|
|
650
692
|
{otpTimer != null && otpTimer > 0 && !otpSuccess && (
|
|
651
693
|
<div className="memori--login-drawer--otp-timer">
|
|
652
|
-
|
|
653
|
-
|
|
694
|
+
<span>
|
|
695
|
+
{t('login.otpTimer', { time: formatOtpTimer(otpTimer) })}
|
|
696
|
+
</span>
|
|
654
697
|
</div>
|
|
655
698
|
)}
|
|
656
699
|
|
|
@@ -675,13 +718,17 @@ const LoginDrawer = ({
|
|
|
675
718
|
disabled={
|
|
676
719
|
loading ||
|
|
677
720
|
isResending ||
|
|
678
|
-
(
|
|
721
|
+
(otpResendCooldown != null && otpResendCooldown > 0) ||
|
|
679
722
|
!otpEmail
|
|
680
723
|
}
|
|
681
724
|
loading={isResending}
|
|
682
725
|
icon={<RefreshCcwIcon className="icon" />}
|
|
683
726
|
>
|
|
684
|
-
{isResending
|
|
727
|
+
{isResending
|
|
728
|
+
? t('login.resending')
|
|
729
|
+
: otpResendCooldown != null && otpResendCooldown > 0
|
|
730
|
+
? t('login.resendOtpIn', { seconds: otpResendCooldown })
|
|
731
|
+
: t('login.resendOtp')}
|
|
685
732
|
</Button>
|
|
686
733
|
</div>
|
|
687
734
|
)}
|
|
@@ -15,9 +15,7 @@ exports[`renders LoginDrawer closed unchanged 1`] = `
|
|
|
15
15
|
`;
|
|
16
16
|
|
|
17
17
|
exports[`renders LoginDrawer logged in unchanged 1`] = `
|
|
18
|
-
<div
|
|
19
|
-
data-base-ui-inert=""
|
|
20
|
-
>
|
|
18
|
+
<div>
|
|
21
19
|
<div
|
|
22
20
|
aria-atomic="false"
|
|
23
21
|
aria-label="Notifications"
|
|
@@ -31,9 +29,7 @@ exports[`renders LoginDrawer logged in unchanged 1`] = `
|
|
|
31
29
|
`;
|
|
32
30
|
|
|
33
31
|
exports[`renders LoginDrawer logged with missing data unchanged 1`] = `
|
|
34
|
-
<div
|
|
35
|
-
data-base-ui-inert=""
|
|
36
|
-
>
|
|
32
|
+
<div>
|
|
37
33
|
<div
|
|
38
34
|
aria-atomic="false"
|
|
39
35
|
aria-label="Notifications"
|
|
@@ -47,9 +43,7 @@ exports[`renders LoginDrawer logged with missing data unchanged 1`] = `
|
|
|
47
43
|
`;
|
|
48
44
|
|
|
49
45
|
exports[`renders LoginDrawer on change password unchanged 1`] = `
|
|
50
|
-
<div
|
|
51
|
-
data-base-ui-inert=""
|
|
52
|
-
>
|
|
46
|
+
<div>
|
|
53
47
|
<div
|
|
54
48
|
aria-atomic="false"
|
|
55
49
|
aria-label="Notifications"
|
|
@@ -63,9 +57,7 @@ exports[`renders LoginDrawer on change password unchanged 1`] = `
|
|
|
63
57
|
`;
|
|
64
58
|
|
|
65
59
|
exports[`renders LoginDrawer on signup unchanged 1`] = `
|
|
66
|
-
<div
|
|
67
|
-
data-base-ui-inert=""
|
|
68
|
-
>
|
|
60
|
+
<div>
|
|
69
61
|
<div
|
|
70
62
|
aria-atomic="false"
|
|
71
63
|
aria-label="Notifications"
|
|
@@ -79,9 +71,7 @@ exports[`renders LoginDrawer on signup unchanged 1`] = `
|
|
|
79
71
|
`;
|
|
80
72
|
|
|
81
73
|
exports[`renders LoginDrawer on signup waiting for otp unchanged 1`] = `
|
|
82
|
-
<div
|
|
83
|
-
data-base-ui-inert=""
|
|
84
|
-
>
|
|
74
|
+
<div>
|
|
85
75
|
<div
|
|
86
76
|
aria-atomic="false"
|
|
87
77
|
aria-label="Notifications"
|
|
@@ -95,9 +85,7 @@ exports[`renders LoginDrawer on signup waiting for otp unchanged 1`] = `
|
|
|
95
85
|
`;
|
|
96
86
|
|
|
97
87
|
exports[`renders LoginDrawer open unchanged 1`] = `
|
|
98
|
-
<div
|
|
99
|
-
data-base-ui-inert=""
|
|
100
|
-
>
|
|
88
|
+
<div>
|
|
101
89
|
<div
|
|
102
90
|
aria-atomic="false"
|
|
103
91
|
aria-label="Notifications"
|
|
@@ -111,9 +99,7 @@ exports[`renders LoginDrawer open unchanged 1`] = `
|
|
|
111
99
|
`;
|
|
112
100
|
|
|
113
101
|
exports[`renders LoginDrawer unlogged unchanged 1`] = `
|
|
114
|
-
<div
|
|
115
|
-
data-base-ui-inert=""
|
|
116
|
-
>
|
|
102
|
+
<div>
|
|
117
103
|
<div
|
|
118
104
|
aria-atomic="false"
|
|
119
105
|
aria-label="Notifications"
|
|
@@ -127,9 +113,7 @@ exports[`renders LoginDrawer unlogged unchanged 1`] = `
|
|
|
127
113
|
`;
|
|
128
114
|
|
|
129
115
|
exports[`renders LoginDrawer with OTP form and error unchanged 1`] = `
|
|
130
|
-
<div
|
|
131
|
-
data-base-ui-inert=""
|
|
132
|
-
>
|
|
116
|
+
<div>
|
|
133
117
|
<div
|
|
134
118
|
aria-atomic="false"
|
|
135
119
|
aria-label="Notifications"
|
|
@@ -143,9 +127,7 @@ exports[`renders LoginDrawer with OTP form and error unchanged 1`] = `
|
|
|
143
127
|
`;
|
|
144
128
|
|
|
145
129
|
exports[`renders LoginDrawer with OTP form and timer unchanged 1`] = `
|
|
146
|
-
<div
|
|
147
|
-
data-base-ui-inert=""
|
|
148
|
-
>
|
|
130
|
+
<div>
|
|
149
131
|
<div
|
|
150
132
|
aria-atomic="false"
|
|
151
133
|
aria-label="Notifications"
|
|
@@ -159,9 +141,7 @@ exports[`renders LoginDrawer with OTP form and timer unchanged 1`] = `
|
|
|
159
141
|
`;
|
|
160
142
|
|
|
161
143
|
exports[`renders LoginDrawer with OTP form loading unchanged 1`] = `
|
|
162
|
-
<div
|
|
163
|
-
data-base-ui-inert=""
|
|
164
|
-
>
|
|
144
|
+
<div>
|
|
165
145
|
<div
|
|
166
146
|
aria-atomic="false"
|
|
167
147
|
aria-label="Notifications"
|
|
@@ -175,9 +155,7 @@ exports[`renders LoginDrawer with OTP form loading unchanged 1`] = `
|
|
|
175
155
|
`;
|
|
176
156
|
|
|
177
157
|
exports[`renders LoginDrawer with OTP form unchanged 1`] = `
|
|
178
|
-
<div
|
|
179
|
-
data-base-ui-inert=""
|
|
180
|
-
>
|
|
158
|
+
<div>
|
|
181
159
|
<div
|
|
182
160
|
aria-atomic="false"
|
|
183
161
|
aria-label="Notifications"
|
|
@@ -6,66 +6,74 @@
|
|
|
6
6
|
gap: var(--memori-spacing-sm);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
/*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.memori-media-items--grid.memori-media-items--
|
|
16
|
-
.memori-media-
|
|
17
|
-
|
|
18
|
-
width:
|
|
9
|
+
/*
|
|
10
|
+
* Image galleries must use a real CSS grid with reserved tile size.
|
|
11
|
+
* Previously few/many set grid-template-* on a flex container, so tiles
|
|
12
|
+
* sized to intrinsic screenshots and caused Safari scroll jumps / blanking.
|
|
13
|
+
*/
|
|
14
|
+
.memori-media-items--grid.memori-media-items--single,
|
|
15
|
+
.memori-media-items--grid.memori-media-items--few,
|
|
16
|
+
.memori-media-items--grid.memori-media-items--many {
|
|
17
|
+
display: grid;
|
|
18
|
+
min-width: 0;
|
|
19
19
|
max-width: 100%;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
align-content: start;
|
|
21
|
+
justify-content: start;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/* Single image: one reserved tile */
|
|
25
|
+
.memori-media-items--grid.memori-media-items--single {
|
|
26
|
+
grid-template-columns: 120px;
|
|
27
|
+
justify-items: stretch;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
/* 2-4 images:
|
|
30
|
+
/* 2-4 images: two columns of reserved tiles */
|
|
29
31
|
.memori-media-items--grid.memori-media-items--few {
|
|
30
|
-
|
|
31
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
32
|
+
grid-template-columns: repeat(2, 120px);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
/*
|
|
35
|
-
@media (min-width: 641px) {
|
|
36
|
-
.memori-media-items--grid.memori-media-items--few {
|
|
37
|
-
grid-template-columns: repeat(2, minmax(200px, 1fr));
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/* 5+ images: Maximum 3 columns on desktop */
|
|
35
|
+
/* 5+ images: two columns by default, three on wide viewports */
|
|
42
36
|
.memori-media-items--grid.memori-media-items--many {
|
|
43
|
-
|
|
44
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
37
|
+
grid-template-columns: repeat(2, 120px);
|
|
45
38
|
}
|
|
46
39
|
|
|
47
|
-
/* Limit to 3 columns for 5+ images on desktop */
|
|
48
40
|
@media (min-width: 1025px) {
|
|
49
41
|
.memori-media-items--grid.memori-media-items--many {
|
|
50
|
-
grid-template-columns: repeat(3,
|
|
42
|
+
grid-template-columns: repeat(3, 120px);
|
|
51
43
|
}
|
|
52
44
|
}
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
.memori-media-items--grid.memori-media-items--single .memori-media-item,
|
|
47
|
+
.memori-media-items--grid.memori-media-items--few .memori-media-item,
|
|
48
|
+
.memori-media-items--grid.memori-media-items--many .memori-media-item,
|
|
49
|
+
.memori-media-item--link .memori-media-item--image {
|
|
50
|
+
width: 120px;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
max-width: 120px;
|
|
53
|
+
height: 120px;
|
|
54
|
+
min-height: 120px;
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
padding: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.memori-media-item--link .memori-media-item--image > div {
|
|
60
|
+
height: 100%;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* User media: keep chronological order; avoid direction:rtl (Safari scroll bugs) */
|
|
55
64
|
.memori-media-items--grid.memori-media-items--user {
|
|
56
65
|
max-width: 90%;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
margin-
|
|
60
|
-
|
|
66
|
+
justify-content: end;
|
|
67
|
+
margin-block: 0;
|
|
68
|
+
margin-inline-end: 0;
|
|
69
|
+
margin-inline-start: auto;
|
|
61
70
|
}
|
|
62
71
|
|
|
63
|
-
/*
|
|
72
|
+
/* Agent media: start-aligned */
|
|
64
73
|
.memori-media-items--grid.memori-media-items--agent {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
direction: ltr;
|
|
74
|
+
justify-content: start;
|
|
75
|
+
margin-block: 0;
|
|
76
|
+
margin-inline: 0;
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
.memori-media-item--card {
|
|
@@ -91,6 +99,8 @@
|
|
|
91
99
|
|
|
92
100
|
.memori-media-item--image .memori-card {
|
|
93
101
|
overflow: hidden;
|
|
102
|
+
width: 100%;
|
|
103
|
+
height: 100%;
|
|
94
104
|
border: 1px solid #e5e7eb;
|
|
95
105
|
border-radius: var(--memori-radius-box);
|
|
96
106
|
margin: 0;
|
|
@@ -130,8 +140,10 @@
|
|
|
130
140
|
border-radius: var(--memori-radius-box);
|
|
131
141
|
}
|
|
132
142
|
|
|
133
|
-
/*
|
|
134
|
-
.memori-media-items--single .memori-media-item--figure
|
|
143
|
+
/* Reserved tile for all image gallery sizes (prevents load-time layout shift) */
|
|
144
|
+
.memori-media-items--single .memori-media-item--figure,
|
|
145
|
+
.memori-media-items--few .memori-media-item--figure,
|
|
146
|
+
.memori-media-items--many .memori-media-item--figure {
|
|
135
147
|
min-height: 120px;
|
|
136
148
|
max-height: 120px;
|
|
137
149
|
background-color: var(--memori-secondary-background);
|
|
@@ -152,6 +164,15 @@
|
|
|
152
164
|
object-position: center;
|
|
153
165
|
}
|
|
154
166
|
|
|
167
|
+
.memori-media-items--single .memori-media-item--figure img,
|
|
168
|
+
.memori-media-items--few .memori-media-item--figure img,
|
|
169
|
+
.memori-media-items--many .memori-media-item--figure img {
|
|
170
|
+
width: 100%;
|
|
171
|
+
height: 100%;
|
|
172
|
+
max-height: none;
|
|
173
|
+
object-fit: cover;
|
|
174
|
+
}
|
|
175
|
+
|
|
155
176
|
.memori-media-item--figure-caption {
|
|
156
177
|
display: -webkit-box;
|
|
157
178
|
overflow: hidden;
|
|
@@ -730,39 +751,34 @@ div.memori-media-item--link:focus-visible {
|
|
|
730
751
|
}
|
|
731
752
|
|
|
732
753
|
/* Responsive design */
|
|
733
|
-
/* Mobile (≤640px):
|
|
754
|
+
/* Mobile (≤640px): stack image tiles in one column, keep reserved 120px size */
|
|
734
755
|
@media (max-width: 640px) {
|
|
735
756
|
.memori-media-items--grid {
|
|
736
757
|
padding: 0.75rem;
|
|
737
758
|
gap: var(--memori-spacing-sm);
|
|
738
|
-
grid-template-columns: 1fr !important;
|
|
739
759
|
}
|
|
740
760
|
|
|
741
761
|
.memori-media-items--grid.memori-media-items--single,
|
|
742
762
|
.memori-media-items--grid.memori-media-items--few,
|
|
743
763
|
.memori-media-items--grid.memori-media-items--many {
|
|
744
|
-
grid-template-columns:
|
|
764
|
+
grid-template-columns: 120px;
|
|
745
765
|
}
|
|
746
766
|
}
|
|
747
767
|
|
|
748
|
-
/* Tablet (641px-1024px):
|
|
768
|
+
/* Tablet (641px-1024px): two reserved tiles */
|
|
749
769
|
@media (min-width: 641px) and (max-width: 1024px) {
|
|
750
|
-
.memori-media-items--grid.memori-media-items--few
|
|
751
|
-
max-width: 100%;
|
|
752
|
-
grid-template-columns: repeat(2, minmax(250px, 1fr));
|
|
753
|
-
}
|
|
754
|
-
|
|
770
|
+
.memori-media-items--grid.memori-media-items--few,
|
|
755
771
|
.memori-media-items--grid.memori-media-items--many {
|
|
756
772
|
max-width: 100%;
|
|
757
|
-
grid-template-columns: repeat(2,
|
|
773
|
+
grid-template-columns: repeat(2, 120px);
|
|
758
774
|
}
|
|
759
775
|
}
|
|
760
776
|
|
|
761
|
-
/* Desktop (>1024px):
|
|
777
|
+
/* Desktop (>1024px): three tiles for 5+ images */
|
|
762
778
|
@media (min-width: 1025px) {
|
|
763
779
|
.memori-media-items--grid.memori-media-items--many {
|
|
764
780
|
max-width: 100%;
|
|
765
|
-
grid-template-columns: repeat(3,
|
|
781
|
+
grid-template-columns: repeat(3, 120px);
|
|
766
782
|
}
|
|
767
783
|
}
|
|
768
784
|
|
|
@@ -839,7 +855,7 @@ a.memori-media-item--document-link {
|
|
|
839
855
|
padding: calc(var(--memori-spacing-sm) + var(--memori-spacing-xs));
|
|
840
856
|
border: 1px solid var(--memori-border-color);
|
|
841
857
|
border-radius: var(--memori-radius-box);
|
|
842
|
-
background:
|
|
858
|
+
background: var(--memori-secondary-background);
|
|
843
859
|
cursor: pointer;
|
|
844
860
|
transition: box-shadow 0.2s ease;
|
|
845
861
|
}
|
|
@@ -901,14 +917,18 @@ a.memori-media-item--document-link {
|
|
|
901
917
|
text-transform: uppercase;
|
|
902
918
|
}
|
|
903
919
|
|
|
904
|
-
/* Document
|
|
920
|
+
/* Document tiles in grid: fill the reserved 120px cell */
|
|
905
921
|
.memori-media-items--grid .memori-media-item--document-link {
|
|
922
|
+
display: block;
|
|
906
923
|
width: 100%;
|
|
924
|
+
height: 100%;
|
|
907
925
|
}
|
|
908
926
|
|
|
909
927
|
.memori-media-items--grid .memori-media-item--document {
|
|
910
|
-
|
|
911
|
-
|
|
928
|
+
width: 100%;
|
|
929
|
+
min-width: 0;
|
|
930
|
+
max-width: none;
|
|
931
|
+
height: 100%;
|
|
912
932
|
min-height: 120px;
|
|
913
933
|
box-sizing: border-box;
|
|
914
934
|
background-color: var(--memori-secondary-background);
|
|
@@ -196,6 +196,39 @@ it('renders PDF as document card with title and PDF badge', () => {
|
|
|
196
196
|
expect(container.querySelector('.memori-media-item--document-link')).toBeInTheDocument();
|
|
197
197
|
});
|
|
198
198
|
|
|
199
|
+
it('lays out multiple document cards in the few-tile grid (not one per row)', () => {
|
|
200
|
+
const docs: (Medium & { type?: string })[] = [
|
|
201
|
+
{
|
|
202
|
+
mediumID: 'doc-a',
|
|
203
|
+
mimeType: 'application/pdf',
|
|
204
|
+
title: 'A.pdf',
|
|
205
|
+
url: 'https://example.com/a.pdf',
|
|
206
|
+
type: 'document',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
mediumID: 'doc-b',
|
|
210
|
+
mimeType: 'application/pdf',
|
|
211
|
+
title: 'B.pdf',
|
|
212
|
+
url: 'https://example.com/b.pdf',
|
|
213
|
+
type: 'document',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
mediumID: 'doc-c',
|
|
217
|
+
mimeType: 'application/pdf',
|
|
218
|
+
title: 'C.pdf',
|
|
219
|
+
url: 'https://example.com/c.pdf',
|
|
220
|
+
type: 'document',
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
const { container } = render(
|
|
224
|
+
<MediaItemWidget items={docs} sessionID={sessionID} />
|
|
225
|
+
);
|
|
226
|
+
expect(
|
|
227
|
+
container.querySelector('.memori-media-items--grid.memori-media-items--few')
|
|
228
|
+
).toBeInTheDocument();
|
|
229
|
+
expect(container.querySelectorAll('.memori-media-item')).toHaveLength(3);
|
|
230
|
+
});
|
|
231
|
+
|
|
199
232
|
it('renders HTML link as document card with Link badge when url present', () => {
|
|
200
233
|
const linkItem: Medium & { type?: string } = {
|
|
201
234
|
mediumID: 'link-1',
|
|
@@ -44,7 +44,6 @@ import {
|
|
|
44
44
|
getImageDisplaySource,
|
|
45
45
|
FALLBACK_IMAGE_BASE64,
|
|
46
46
|
TEXT_FILE_EXTENSIONS,
|
|
47
|
-
IMAGE_MIME_TYPES,
|
|
48
47
|
} from './MediaItemWidget.utils';
|
|
49
48
|
import { DocumentCard } from './DocumentCard';
|
|
50
49
|
import { MediaPreviewModal } from './MediaPreviewModal';
|
|
@@ -846,14 +845,9 @@ const MediaItemWidget: React.FC<Props> = ({
|
|
|
846
845
|
[media]
|
|
847
846
|
);
|
|
848
847
|
|
|
849
|
-
//
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
nonCodeDisplayMedia.filter(m =>
|
|
853
|
-
(IMAGE_MIME_TYPES as readonly string[]).includes(m.mimeType)
|
|
854
|
-
).length,
|
|
855
|
-
[nonCodeDisplayMedia]
|
|
856
|
-
);
|
|
848
|
+
// Tile count drives Claude-like row/column grid for images AND documents.
|
|
849
|
+
// (Previously only imageCount was used, so file cards stayed in a flex column.)
|
|
850
|
+
const tileCount = nonCodeDisplayMedia.length;
|
|
857
851
|
|
|
858
852
|
// Media "card open"/preview modal: pass the clicked item so the correct one opens
|
|
859
853
|
// (avoids wrong image when multiple items share the same mediumID)
|
|
@@ -888,9 +882,9 @@ const MediaItemWidget: React.FC<Props> = ({
|
|
|
888
882
|
className={cx('memori-media-items--grid memori-chat-scroll-item', {
|
|
889
883
|
'memori-media-items--user': fromUser,
|
|
890
884
|
'memori-media-items--agent': !fromUser,
|
|
891
|
-
'memori-media-items--single':
|
|
892
|
-
'memori-media-items--few':
|
|
893
|
-
'memori-media-items--many':
|
|
885
|
+
'memori-media-items--single': tileCount === 1,
|
|
886
|
+
'memori-media-items--few': tileCount >= 2 && tileCount <= 4,
|
|
887
|
+
'memori-media-items--many': tileCount >= 5,
|
|
894
888
|
})}
|
|
895
889
|
>
|
|
896
890
|
{nonCodeDisplayMedia.map((item, index) => (
|
|
@@ -80,6 +80,7 @@ exports[`renders MediaItemWidget unchanged with css snippet to show 1`] = `
|
|
|
80
80
|
class="memori-button__icon"
|
|
81
81
|
>
|
|
82
82
|
<svg
|
|
83
|
+
aria-hidden="true"
|
|
83
84
|
class="lucide lucide-copy"
|
|
84
85
|
fill="none"
|
|
85
86
|
height="24"
|
|
@@ -317,6 +318,7 @@ exports[`renders MediaItemWidget unchanged with js snippet to show 1`] = `
|
|
|
317
318
|
class="memori-button__icon"
|
|
318
319
|
>
|
|
319
320
|
<svg
|
|
321
|
+
aria-hidden="true"
|
|
320
322
|
class="lucide lucide-copy"
|
|
321
323
|
fill="none"
|
|
322
324
|
height="24"
|