Skip to content

Commit

Permalink
Merge branch 'master' into feat/threads-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
arnautov-anton authored Sep 3, 2024
2 parents a09b0ab + 0480b46 commit 5d3f006
Show file tree
Hide file tree
Showing 18 changed files with 354 additions and 244 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [12.0.0-rc.10](https://github.com/GetStream/stream-chat-react/compare/v12.0.0-rc.9...v12.0.0-rc.10) (2024-08-30)


### Bug Fixes

* address the circular dependencies among TranslationContext and Streami18n ([#2483](https://github.com/GetStream/stream-chat-react/issues/2483)) ([b91fd9a](https://github.com/GetStream/stream-chat-react/commit/b91fd9aa6fcdbdd9ec1fe7342c58011a0d34116d))

## [12.0.0-rc.9](https://github.com/GetStream/stream-chat-react/compare/v12.0.0-rc.8...v12.0.0-rc.9) (2024-08-22)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,87 @@ const App = () => {
};
```

To organize the components in a chat messenger layout, we provide the following CSS:

```css
html,
body,
#root {
margin: unset;
padding: unset;
height: 100%;
}

#root {
display: flex;
height: 100%;

.str-chat-channel-list {
position: fixed;
z-index: 1;
width: 0;

&--open {
width: 100%;
}
}

.str-chat-channel {
width: 100%;
}

.str-chat__thread {
width: 100%;
height: 100%;
position: fixed;
z-index: 1;
}

.str-chat__channel-header .str-chat__header-hamburger {
width: 30px;
height: 38px;
padding: var(--xxs-p);
margin-right: var(--xs-m);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: none;
background: transparent;

&:hover {
svg path {
fill: var(--primary-color);
}
}
}

@media screen and (min-width: 768px) {
.str-chat-channel-list {
width: 30%;
max-width: 420px;
position: initial;
z-index: 0;
}

.str-chat__thread {
position: initial;
z-index: 0;
}
}

@media screen and (min-width: 1024px) {
.str-chat__thread {
width: 45%;
}

.str-chat__channel-header .str-chat__header-hamburger {
display: none;
}
}
}
```

## Chat Client & Connecting User

To communicate with the Stream Chat API the SDK requires a client with an established connection. The hook mentioned in the code above (`useCreateChatClient`) handles client instantiation, establishes proper connection and handles cleanups and disconnects for you. If you wish to have more control over how all of the previously mentioned is being handled see [Client and User](../guides/client-and-user.mdx) guide.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
}
},
"sideEffects": [
"*.css"
"*.css",
"./dist/i18n/Streami18n.js"
],
"keywords": [
"chat",
Expand Down Expand Up @@ -204,7 +205,7 @@
"core-js": "^3.6.5",
"dotenv": "^8.6.0",
"emoji-mart": "^5.5.2",
"esbuild": "^0.20.2",
"esbuild": "^0.23.1",
"eslint": "7.14.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^6.15.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';

import { isDate, isDayOrMoment } from '../../../context/TranslationContext';
import { isDate, isDayOrMoment } from '../../../i18n';

import type { ChannelStateContextValue } from '../../../context/ChannelStateContext';

Expand Down
4 changes: 2 additions & 2 deletions src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { useCreateChatContext } from './hooks/useCreateChatContext';
import { useChannelsQueryState } from './hooks/useChannelsQueryState';

import { ChatProvider, CustomClasses } from '../../context/ChatContext';
import { SupportedTranslations, TranslationProvider } from '../../context/TranslationContext';
import { TranslationProvider } from '../../context/TranslationContext';

import type { StreamChat } from 'stream-chat';

import type { SupportedTranslations } from '../../i18n/types';
import type { Streami18n } from '../../i18n/Streami18n';

import type { DefaultStreamChatGenerics } from '../../types/types';

export type ChatProps<
Expand Down
6 changes: 3 additions & 3 deletions src/components/Chat/hooks/useChat.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useCallback, useEffect, useRef, useState } from 'react';

import { TranslationContextValue } from '../../../context/TranslationContext';
import {
defaultDateTimeParser,
isLanguageSupported,
Streami18n,
SupportedTranslations,
TranslationContextValue,
} from '../../../context/TranslationContext';
import { Streami18n } from '../../../i18n';
} from '../../../i18n';
import { version } from '../../../version';

import type { AppSettingsAPIResponse, Channel, Event, Mute, StreamChat } from 'stream-chat';
Expand Down
4 changes: 3 additions & 1 deletion src/components/DateSeparator/DateSeparator.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';

import { useTranslationContext } from '../../context/TranslationContext';
import { getDateString, TimestampFormatterOptions } from '../../i18n/utils';
import { getDateString } from '../../i18n/utils';

import type { TimestampFormatterOptions } from '../../i18n/types';

export type DateSeparatorProps = TimestampFormatterOptions & {
/** The date to format */
Expand Down
4 changes: 2 additions & 2 deletions src/components/EventComponent/EventComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import React from 'react';
import { AvatarProps, Avatar as DefaultAvatar } from '../Avatar';

import { useTranslationContext } from '../../context/TranslationContext';
import { getDateString } from '../../i18n/utils';

import type { StreamMessage } from '../../context/ChannelStateContext';

import type { DefaultStreamChatGenerics } from '../../types/types';
import { getDateString, TimestampFormatterOptions } from '../../i18n/utils';
import type { TimestampFormatterOptions } from '../../i18n/types';

export type EventComponentProps<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
Expand Down
2 changes: 1 addition & 1 deletion src/components/Message/MessageTimestamp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Timestamp as DefaultTimestamp } from './Timestamp';
import { useComponentContext } from '../../context';

import type { StreamMessage } from '../../context/ChannelStateContext';
import type { TimestampFormatterOptions } from '../../i18n/types';
import type { DefaultStreamChatGenerics } from '../../types/types';
import type { TimestampFormatterOptions } from '../../i18n/utils';

export type MessageTimestampProps<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
Expand Down
5 changes: 3 additions & 2 deletions src/components/Message/Timestamp.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useMemo } from 'react';

import { useMessageContext } from '../../context/MessageContext';
import { isDate, useTranslationContext } from '../../context/TranslationContext';
import { getDateString, TimestampFormatterOptions } from '../../i18n/utils';
import { useTranslationContext } from '../../context/TranslationContext';
import { getDateString, isDate } from '../../i18n/utils';
import type { TimestampFormatterOptions } from '../../i18n/types';

export interface TimestampProps extends TimestampFormatterOptions {
/* Adds a CSS class name to the component's outer `time` container. */
Expand Down
8 changes: 5 additions & 3 deletions src/components/Message/__tests__/MessageTimestamp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ const calendarFormats = {
const dateMock = 'the date';
const formatDate = () => dateMock;

const createdAt = new Date('2019-04-03T14:42:47.087869Z');

const messageMock = generateMessage({
created_at: new Date('2019-04-03T14:42:47.087869Z'),
created_at: createdAt,
});

const renderComponent = async ({ chatProps, componentCtx, messageCtx, props } = {}) => {
Expand Down Expand Up @@ -124,7 +126,7 @@ describe('<MessageTimestamp />', () => {
}),
},
});
expect(container).toHaveTextContent('2019-04-03T14:42:47+00:00');
expect(container).toHaveTextContent('2019-04-03T14:42:47Z');
});

it('should render with custom format provided via i18n service', async () => {
Expand Down Expand Up @@ -172,7 +174,7 @@ describe('<MessageTimestamp />', () => {
},
props: { calendarFormats },
});
expect(container).toHaveTextContent('2019-04-03T14:42:47+00:00');
expect(container).toHaveTextContent('2019-04-03T14:42:47Z');
});

it('should reflect the custom calendarFormats if calendar is enabled', async () => {
Expand Down
5 changes: 2 additions & 3 deletions src/components/MessageList/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
import { nanoid } from 'nanoid';

import { CUSTOM_MESSAGE_TYPE } from '../../constants/messageTypes';

import { isDate } from '../../context/TranslationContext';
import { isMessageEdited } from '../Message/utils';
import { isDate } from '../../i18n';

import type { MessageLabel, UserResponse } from 'stream-chat';
import type { DefaultStreamChatGenerics } from '../../types/types';
import type { StreamMessage } from '../../context/ChannelStateContext';
import { isMessageEdited } from '../Message/utils';

type ProcessMessagesContext = {
/** the connected user ID */
Expand Down
40 changes: 2 additions & 38 deletions src/context/TranslationContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,23 @@ import calendar from 'dayjs/plugin/calendar';
import localizedFormat from 'dayjs/plugin/localizedFormat';

import { getDisplayName } from './utils/getDisplayName';
import { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';

import type { TFunction } from 'i18next';
import type { Moment } from 'moment-timezone';
import type { TranslationLanguages } from 'stream-chat';

import type { UnknownType } from '../types/types';
import { defaultTranslatorFunction } from '../i18n';
import type { TDateTimeParser } from '../i18n/types';

Dayjs.extend(calendar);
Dayjs.extend(localizedFormat);

export type SupportedTranslations =
| 'de'
| 'en'
| 'es'
| 'fr'
| 'hi'
| 'it'
| 'ja'
| 'ko'
| 'nl'
| 'pt'
| 'ru'
| 'tr';

export const isLanguageSupported = (language: string): language is SupportedTranslations => {
const translations = ['de', 'en', 'es', 'fr', 'hi', 'it', 'ja', 'ko', 'nl', 'pt', 'ru', 'tr'];
return translations.some((translation) => language === translation);
};

export const isDayOrMoment = (output: TDateTimeParserOutput): output is Dayjs.Dayjs | Moment =>
!!(output as Dayjs.Dayjs | Moment)?.isSame;

export const isDate = (output: TDateTimeParserOutput): output is Date =>
!!(output as Date)?.getMonth;

export const isNumberOrString = (output: TDateTimeParserOutput): output is number | string =>
typeof output === 'string' || typeof output === 'number';

export type TDateTimeParserInput = string | number | Date;

export type TDateTimeParserOutput = string | number | Date | Dayjs.Dayjs | Moment;

export type TDateTimeParser = (input?: TDateTimeParserInput) => TDateTimeParserOutput;

export type TranslationContextValue = {
t: TFunction;
tDateTimeParser: TDateTimeParser;
userLanguage: TranslationLanguages;
};

export const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);

export const TranslationContext = React.createContext<TranslationContextValue>({
t: defaultTranslatorFunction,
tDateTimeParser: defaultDateTimeParser,
Expand Down
8 changes: 2 additions & 6 deletions src/i18n/Streami18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import localeData from 'dayjs/plugin/localeData';
import relativeTime from 'dayjs/plugin/relativeTime';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { predefinedFormatters } from './utils';
import { defaultTranslatorFunction, predefinedFormatters } from './utils';

import type momentTimezone from 'moment-timezone';
import type { TranslationLanguages } from 'stream-chat';

import type { CustomFormatters, PredefinedFormatters } from './utils';
import type { TDateTimeParser } from '../context/TranslationContext';

import type { UnknownType } from '../types/types';
import type { CustomFormatters, PredefinedFormatters, TDateTimeParser } from './types';

import {
deTranslations,
Expand Down Expand Up @@ -418,8 +416,6 @@ const defaultStreami18nOptions = {
logger: (message?: string) => console.warn(message),
};

export const defaultTranslatorFunction: TFunction = <tResult = string>(key: tResult) => key;

export class Streami18n {
i18nInstance = i18n.createInstance();
Dayjs = null;
Expand Down
10 changes: 9 additions & 1 deletion src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export * from './translations';
export * from './Streami18n';
export type { FormatterFactory, TimestampFormatterOptions } from './utils';
export {
defaultDateTimeParser,
defaultTranslatorFunction,
isDate,
isDayOrMoment,
isLanguageSupported,
isNumberOrString,
} from './utils';
export * from './types';
Loading

0 comments on commit 5d3f006

Please sign in to comment.