diff --git a/src/components/CurrentUserMessage.tsx b/src/components/CurrentUserMessage.tsx index d006ca93c..3e759da1f 100644 --- a/src/components/CurrentUserMessage.tsx +++ b/src/components/CurrentUserMessage.tsx @@ -1,34 +1,12 @@ import { styled } from '@linaria/react'; -import { SendingStatus, UserMessage } from '@sendbird/chat/message'; +import { UserMessage } from '@sendbird/chat/message'; +import { useTheme } from 'styled-components'; -import { DefaultSentTime, BodyContainer, BodyComponent } from './MessageComponent'; +import { BodyContainer, BodyComponent } from './MessageComponent'; +import MyMessageStatus from './MyMessageStatus'; import { useConstantState } from '../context/ConstantContext'; -import { useWidgetSetting } from '../context/WidgetSettingContext'; -import { Icon } from '../foundation/components/Icon'; -import { formatCreatedAtToAMPM } from '../utils/messageTimestamp'; -const SpinnerSize = '16px'; - -interface IconContainerProps { - isSpinning?: boolean; -} - -const IconContainer = styled.div` - display: grid; - justify-content: center; - align-items: center; - margin-bottom: 2px; - animation: ${({ isSpinning }) => (isSpinning ? 'spinner 1.5s linear infinite' : 'unset')}; - - @keyframes spinner { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } - } -`; +import '../css/index.css'; const Root = styled.div<{ enableEmojiFeedback: boolean }>` display: flex; @@ -43,31 +21,13 @@ type Props = { export default function CurrentUserMessage(props: Props) { const { enableEmojiFeedback, dateLocale } = useConstantState(); - const { theme } = useWidgetSetting(); - const { message } = props; + const theme = useTheme(); - const MessageStatus = () => { - switch (message.sendingStatus) { - case SendingStatus.PENDING: - return ( - - - - ); - case SendingStatus.FAILED: - return ( - - - - ); - default: - return {formatCreatedAtToAMPM(message.createdAt, dateLocale)}; - } - }; + const { message } = props; return ( - +
{message.message}
diff --git a/src/components/MyMessageStatus.tsx b/src/components/MyMessageStatus.tsx new file mode 100644 index 000000000..24be90311 --- /dev/null +++ b/src/components/MyMessageStatus.tsx @@ -0,0 +1,35 @@ +import { SendableMessage } from '@sendbird/chat/lib/__definition'; +import { SendingStatus } from '@sendbird/chat/message'; +import { Locale } from 'date-fns'; + +import { DefaultSentTime } from './MessageComponent'; +import { Icon } from '../foundation/components/Icon'; +import { Loader } from '../foundation/components/Loader'; +import { CommonTheme } from '../theme'; +import { formatCreatedAtToAMPM } from '../utils/messageTimestamp'; + +interface MyMessageStatusProps { + message: SendableMessage; + dateLocale: Locale; + theme: CommonTheme; +} + +export default function MyMessageStatus(props: MyMessageStatusProps) { + const { message, dateLocale, theme } = props; + switch (message.sendingStatus) { + case SendingStatus.PENDING: + return ( + + + + ); + case SendingStatus.FAILED: + return ( + + + + ); + default: + return {formatCreatedAtToAMPM(message.createdAt, dateLocale)}; + } +} diff --git a/src/components/messages/OutgoingFileMessage.tsx b/src/components/messages/OutgoingFileMessage.tsx index b02693bcf..7f68b4515 100644 --- a/src/components/messages/OutgoingFileMessage.tsx +++ b/src/components/messages/OutgoingFileMessage.tsx @@ -2,14 +2,15 @@ import { css } from '@linaria/core'; import { styled } from '@linaria/react'; import { FileMessage } from '@sendbird/chat/message'; import { useState } from 'react'; +import { useTheme } from 'styled-components'; import { useConstantState } from '../../context/ConstantContext'; import { Icon } from '../../foundation/components/Icon'; import { Label } from '../../foundation/components/Label'; import { Loader } from '../../foundation/components/Loader'; import { META_ARRAY_ASPECT_RATIO_KEY } from '../../utils/getImageAspectRatio'; -import { formatCreatedAtToAMPM } from '../../utils/messageTimestamp'; -import { BodyComponent, BodyContainer, DefaultSentTime } from '../MessageComponent'; +import { BodyComponent, BodyContainer } from '../MessageComponent'; +import MyMessageStatus from '../MyMessageStatus'; import { FileViewer } from '../ui/FileViewer'; type Props = { @@ -18,6 +19,7 @@ type Props = { export const OutgoingFileMessage = ({ message }: Props) => { const { dateLocale } = useConstantState(); + const theme = useTheme(); const hasMessageBubble = !!message.message; const type = (() => { @@ -36,7 +38,7 @@ export const OutgoingFileMessage = ({ message }: Props) => { const renderTimestamp = () => { return (
- {formatCreatedAtToAMPM(message.createdAt, dateLocale)} +
); }; diff --git a/src/components/widget/ProviderContainer.tsx b/src/components/widget/ProviderContainer.tsx index 9f114194b..d57c557ea 100644 --- a/src/components/widget/ProviderContainer.tsx +++ b/src/components/widget/ProviderContainer.tsx @@ -5,10 +5,12 @@ import { StyleSheetManager, ThemeProvider } from 'styled-components'; import SendbirdProvider from '@uikit/lib/Sendbird'; import { ChatAiWidgetProps } from './ChatAiWidget'; +import { generateCSSVariables } from '../../colors'; import { ConstantStateProvider, useConstantState } from '../../context/ConstantContext'; import { useWidgetSession, useWidgetSetting, WidgetSettingProvider } from '../../context/WidgetSettingContext'; import { useWidgetState, WidgetStateProvider } from '../../context/WidgetStateContext'; import { useStyledComponentsTarget } from '../../hooks/useStyledComponentsTarget'; +import { getTheme } from '../../theme'; import { DragDropProvider } from '../../tools/hooks/useDragDropFiles'; import { isDashboardPreview } from '../../utils'; @@ -32,7 +34,7 @@ const SBComponent = ({ children }: { children: React.ReactElement }) => { } = useConstantState(); const { setIsVisible } = useWidgetState(); - const { botConfigs, botStyle, theme, colorSet } = useWidgetSetting(); + const { botConfigs, botStyle } = useWidgetSetting(); const session = useWidgetSession(); const target = useStyledComponentsTarget(); @@ -49,9 +51,27 @@ const SBComponent = ({ children }: { children: React.ReactElement }) => { return userAgent; }, []); + const { theme, accentColor, botMessageBGColor } = botStyle; + + const styledTheme = getTheme({ + accentColor, + botMessageBGColor, + })[theme]; + + const customColorSet = useMemo(() => { + if (!accentColor) return undefined; + + return ['light', 'dark'].reduce((acc, cur) => { + return { + ...acc, + ...generateCSSVariables(accentColor, cur), + }; + }, {}); + }, [accentColor]); + return ( - + {applicationId && session.userId && ( { customExtensionParams={userAgentCustomParams} breakpoint={isMobileView} // A property that determines whether to show it with a layout that fits the mobile screen. Or you can put the width size with `px`. theme={botStyle.theme} - colorSet={colorSet} + colorSet={customColorSet} stringSet={stringSet} dateLocale={dateLocale} eventHandlers={{ diff --git a/src/context/WidgetSettingContext.tsx b/src/context/WidgetSettingContext.tsx index 0560d66af..0c9814fd6 100644 --- a/src/context/WidgetSettingContext.tsx +++ b/src/context/WidgetSettingContext.tsx @@ -1,12 +1,10 @@ import { SendbirdChatWith } from '@sendbird/chat'; import { GroupChannelModule } from '@sendbird/chat/groupChannel'; -import React, { createContext, useContext, useLayoutEffect, useMemo, useState } from 'react'; +import React, { createContext, useContext, useLayoutEffect, useState } from 'react'; import { useConstantState } from './ConstantContext'; -import { generateCSSVariables } from '../colors'; import { widgetSettingHandler } from '../libs/api/widgetSetting'; import { getWidgetSessionCache, saveWidgetSessionCache, WidgetSessionCache } from '../libs/storage/widgetSessionCache'; -import { CommonTheme, getTheme } from '../theme'; import { getDateNDaysLater, isPastTime } from '../utils'; interface WidgetSession { @@ -33,8 +31,6 @@ export interface BotConfigs { type Context = { initialized: boolean; botStyle: BotStyle; - theme: CommonTheme; - colorSet?: Record; botConfigs: BotConfigs; widgetSession: WidgetSession | null; initManualSession: (sdk: SendbirdChatWith<[GroupChannelModule]>) => void; @@ -196,24 +192,6 @@ export const WidgetSettingProvider = ({ children }: React.PropsWithChildren) => }); }, [sessionStrategy]); - const { theme, accentColor, botMessageBGColor } = botStyle; - - const styledTheme = getTheme({ - accentColor, - botMessageBGColor, - })[theme]; - - const customColorSet = useMemo(() => { - if (!accentColor) return undefined; - - return ['light', 'dark'].reduce((acc, cur) => { - return { - ...acc, - ...generateCSSVariables(accentColor, cur), - }; - }, {}); - }, [accentColor]); - return ( botStudioEditProps?.styles?.accentColor ?? botStudioEditProps?.styles?.primaryColor ?? botStyle.accentColor, autoOpen: autoOpen ?? botStyle.autoOpen, }, - theme: styledTheme, - colorSet: customColorSet, botConfigs, widgetSession, initManualSession, diff --git a/src/css/index.css b/src/css/index.css index e1d6f44b6..c514875ee 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -111,3 +111,10 @@ input:focus { .sendbird-form-chip { padding: 0px 12px; } + +.sendbird-loader { + margin-bottom: 2px; + &.no-animation { + animation: unset; + } +}