diff --git a/global.d.ts b/global.d.ts
new file mode 100644
index 0000000..98af3d3
--- /dev/null
+++ b/global.d.ts
@@ -0,0 +1,7 @@
+declare global {
+ interface Window {
+ webkitAudioContext: typeof AudioContext;
+ }
+}
+
+export {};
diff --git a/public/audio/notification-new-message-1.mp3 b/public/audio/notification-new-message-1.mp3
new file mode 100644
index 0000000..3860589
Binary files /dev/null and b/public/audio/notification-new-message-1.mp3 differ
diff --git a/public/audio/notification-new-message-1.wav b/public/audio/notification-new-message-1.wav
new file mode 100644
index 0000000..c7017ad
Binary files /dev/null and b/public/audio/notification-new-message-1.wav differ
diff --git a/src/app/[locale]/(chat)/chat/[assistantId]/page.tsx b/src/app/[locale]/(chat)/chat/[assistantId]/page.tsx
index 1313da7..eef4ad4 100644
--- a/src/app/[locale]/(chat)/chat/[assistantId]/page.tsx
+++ b/src/app/[locale]/(chat)/chat/[assistantId]/page.tsx
@@ -4,14 +4,13 @@ import {
ChatModalsWrapper,
MessageInputWrapper,
} from "@/components/domains/chat";
-import { loadChatsList } from "@/entities/chats/loaders";
import styles from "./page.module.scss";
export default function Chat() {
return (
-
+
diff --git a/src/app/[locale]/(chat)/chat/page.tsx b/src/app/[locale]/(chat)/chat/page.tsx
index 1c19638..6199b68 100644
--- a/src/app/[locale]/(chat)/chat/page.tsx
+++ b/src/app/[locale]/(chat)/chat/page.tsx
@@ -10,7 +10,6 @@ import {
NewMessagesWrapperSkeleton,
} from "@/components/domains/chat";
import { NavigationBar } from "@/components/layout";
-import { loadChatsList } from "@/entities/chats/loaders";
import styles from "./page.module.scss";
@@ -19,23 +18,21 @@ export const revalidate = 0;
export const fetchCache = "force-no-store";
export default function Chats() {
- const chatsPromise = loadChatsList();
-
return (
-
+
);
}
diff --git a/src/app/[locale]/(core)/layout.tsx b/src/app/[locale]/(core)/layout.tsx
index 654e78a..a2730b8 100644
--- a/src/app/[locale]/(core)/layout.tsx
+++ b/src/app/[locale]/(core)/layout.tsx
@@ -1,5 +1,4 @@
import { DrawerProvider, Header, NavigationBar } from "@/components/layout";
-import { loadChatsList } from "@/entities/chats/loaders";
import { ChatStoreProvider } from "@/providers/chat-store-provider";
import styles from "./layout.module.scss";
@@ -9,13 +8,12 @@ export default function CoreLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
- const chatsPromise = loadChatsList();
return (
-
+
{children}
-
+
);
diff --git a/src/app/[locale]/(core)/page.tsx b/src/app/[locale]/(core)/page.tsx
index 11cb9ab..54a0512 100644
--- a/src/app/[locale]/(core)/page.tsx
+++ b/src/app/[locale]/(core)/page.tsx
@@ -28,7 +28,7 @@ export default function Home() {
return (
}>
-
+
diff --git a/src/app/[locale]/(payment)/layout.tsx b/src/app/[locale]/(payment)/layout.tsx
index a717e7d..f8c99ba 100644
--- a/src/app/[locale]/(payment)/layout.tsx
+++ b/src/app/[locale]/(payment)/layout.tsx
@@ -1,5 +1,4 @@
import { DrawerProvider, Header } from "@/components/layout";
-import { loadChatsList } from "@/entities/chats/loaders";
import styles from "./layout.module.scss";
@@ -10,7 +9,7 @@ export default function CoreLayout({
}>) {
return (
-
+
{children}
);
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx
index 10550cf..f9b67b4 100644
--- a/src/app/[locale]/layout.tsx
+++ b/src/app/[locale]/layout.tsx
@@ -10,10 +10,13 @@ import { getMessages } from "next-intl/server";
import clsx from "clsx";
import YandexMetrika from "@/components/analytics/YandexMetrika";
+import { loadChatsList } from "@/entities/chats/loaders";
import { loadUser, loadUserId } from "@/entities/user/loaders";
import { routing } from "@/i18n/routing";
import { AppUiStoreProvider } from "@/providers/app-ui-store-provider";
+import { AudioProvider } from "@/providers/audio-provider";
import { ChatsInitializationProvider } from "@/providers/chats-initialization-provider";
+import { ChatsProvider } from "@/providers/chats-provider";
import { RetainingStoreProvider } from "@/providers/retaining-store-provider";
import SocketProvider from "@/providers/socket-provider";
import { ToastProvider } from "@/providers/toast-provider";
@@ -60,6 +63,7 @@ export default async function RootLayout({
const user = await loadUser();
const userId = await loadUserId();
+ const chats = await loadChatsList();
return (
@@ -69,11 +73,15 @@ export default async function RootLayout({
-
-
- {children}
-
-
+
+
+
+
+ {children}
+
+
+
+
diff --git a/src/components/domains/chat/ChatCategories/ChatCategories.tsx b/src/components/domains/chat/ChatCategories/ChatCategories.tsx
index 33a3b13..8dadc63 100644
--- a/src/components/domains/chat/ChatCategories/ChatCategories.tsx
+++ b/src/components/domains/chat/ChatCategories/ChatCategories.tsx
@@ -1,23 +1,17 @@
"use client";
-import { use, useState } from "react";
+import { useState } from "react";
import { Skeleton } from "@/components/ui";
import { Chips } from "@/components/widgets";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
+import { useChats } from "@/providers/chats-provider";
import { CategoryChats, ChatItemsList } from "..";
const MAX_HIDE_VISIBLE_COUNT = 3;
-interface ChatCategoriesProps {
- chatsPromise: Promise;
-}
-
-export default function ChatCategories({ chatsPromise }: ChatCategoriesProps) {
- const chats = use(chatsPromise);
- const { categorizedChats } = useChatsSocket({ initialChats: chats });
+export default function ChatCategories() {
+ const { categorizedChats } = useChats();
const [activeChip, setActiveChip] = useState("All");
const [maxVisibleChats, setMaxVisibleChats] = useState<
diff --git a/src/components/domains/chat/ChatHeader/ChatHeader.tsx b/src/components/domains/chat/ChatHeader/ChatHeader.tsx
index 4cb8074..f54befe 100644
--- a/src/components/domains/chat/ChatHeader/ChatHeader.tsx
+++ b/src/components/domains/chat/ChatHeader/ChatHeader.tsx
@@ -1,6 +1,6 @@
"use client";
-import { use, useEffect, useState } from "react";
+import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
@@ -13,26 +13,20 @@ import {
UserAvatar,
} from "@/components/ui";
import { revalidateChatsPage } from "@/entities/chats/actions";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
import { useChat } from "@/providers/chat-provider";
import { useChatStore } from "@/providers/chat-store-provider";
+import { useChats } from "@/providers/chats-provider";
import { formatSecondsToHHMMSS } from "@/shared/utils/date";
import { delay } from "@/shared/utils/delay";
import styles from "./ChatHeader.module.scss";
-interface ChatHeaderProps {
- chatsPromise: Promise;
-}
-
-export default function ChatHeader({ chatsPromise }: ChatHeaderProps) {
+export default function ChatHeader() {
const t = useTranslations("Chat");
const router = useRouter();
const currentChat = useChatStore(state => state.currentChat);
const { isLoadingAdvisorMessage, isAvailableChatting } = useChat();
- const chats = use(chatsPromise);
- const { totalUnreadCount } = useChatsSocket({ initialChats: chats });
+ const { totalUnreadCount } = useChats();
const [timer, setTimer] = useState(0);
useEffect(() => {
diff --git a/src/components/domains/chat/CorrespondenceStartedWrapper/CorrespondenceStartedWrapper.tsx b/src/components/domains/chat/CorrespondenceStartedWrapper/CorrespondenceStartedWrapper.tsx
index 658bfea..b488bab 100644
--- a/src/components/domains/chat/CorrespondenceStartedWrapper/CorrespondenceStartedWrapper.tsx
+++ b/src/components/domains/chat/CorrespondenceStartedWrapper/CorrespondenceStartedWrapper.tsx
@@ -1,25 +1,16 @@
"use client";
-import { use } from "react";
import { useTranslations } from "next-intl";
import { Skeleton } from "@/components/ui";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
import { useAppUiStore } from "@/providers/app-ui-store-provider";
+import { useChats } from "@/providers/chats-provider";
import { ChatItemsList, CorrespondenceStarted } from "..";
-interface CorrespondenceStartedWrapperProps {
- chatsPromise: Promise;
-}
-
-export default function CorrespondenceStartedWrapper({
- chatsPromise,
-}: CorrespondenceStartedWrapperProps) {
+export default function CorrespondenceStartedWrapper() {
const t = useTranslations("Chat");
- const chats = use(chatsPromise);
- const { startedChats } = useChatsSocket({ initialChats: chats });
+ const { startedChats } = useChats();
const { isVisibleAll } = useAppUiStore(
state => state.chats.correspondenceStarted
diff --git a/src/components/domains/chat/NewMessagesWrapper/NewMessagesWrapper.tsx b/src/components/domains/chat/NewMessagesWrapper/NewMessagesWrapper.tsx
index 18ab9b4..282a007 100644
--- a/src/components/domains/chat/NewMessagesWrapper/NewMessagesWrapper.tsx
+++ b/src/components/domains/chat/NewMessagesWrapper/NewMessagesWrapper.tsx
@@ -1,25 +1,16 @@
"use client";
-import { use } from "react";
import { useTranslations } from "next-intl";
import { Skeleton } from "@/components/ui";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
import { useAppUiStore } from "@/providers/app-ui-store-provider";
+import { useChats } from "@/providers/chats-provider";
import { ChatItemsList, NewMessages } from "..";
-interface NewMessagesWrapperProps {
- chatsPromise: Promise;
-}
-
-export default function NewMessagesWrapper({
- chatsPromise,
-}: NewMessagesWrapperProps) {
+export default function NewMessagesWrapper() {
const t = useTranslations("Chat");
- const chats = use(chatsPromise);
- const { unreadChats } = useChatsSocket({ initialChats: chats });
+ const { unreadChats } = useChats();
const { isVisibleAll } = useAppUiStore(state => state.chats.newMessages);
const hasHydrated = useAppUiStore(state => state._hasHydrated);
diff --git a/src/components/domains/dashboard/sections/NewMessagesSection/NewMessagesSection.tsx b/src/components/domains/dashboard/sections/NewMessagesSection/NewMessagesSection.tsx
index c5a31ca..3b8d670 100644
--- a/src/components/domains/dashboard/sections/NewMessagesSection/NewMessagesSection.tsx
+++ b/src/components/domains/dashboard/sections/NewMessagesSection/NewMessagesSection.tsx
@@ -1,24 +1,14 @@
"use client";
-import { use } from "react";
-
import { NewMessages, ViewAll } from "@/components/domains/chat";
import { Skeleton } from "@/components/ui";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
import { useAppUiStore } from "@/providers/app-ui-store-provider";
+import { useChats } from "@/providers/chats-provider";
import styles from "./NewMessagesSection.module.scss";
-interface NewMessagesSectionProps {
- chatsPromise: Promise;
-}
-
-export default function NewMessagesSection({
- chatsPromise,
-}: NewMessagesSectionProps) {
- const chats = use(chatsPromise);
- const { unreadChats } = useChatsSocket({ initialChats: chats });
+export default function NewMessagesSection() {
+ const { unreadChats } = useChats();
const { isVisibleAll } = useAppUiStore(state => state.home.newMessages);
const hasHydrated = useAppUiStore(state => state._hasHydrated);
diff --git a/src/components/layout/Header/Header.tsx b/src/components/layout/Header/Header.tsx
index 1aa5253..5a10f1a 100644
--- a/src/components/layout/Header/Header.tsx
+++ b/src/components/layout/Header/Header.tsx
@@ -1,12 +1,10 @@
"use client";
-import { use } from "react";
import Link from "next/link";
import clsx from "clsx";
import { Badge, Button, Icon, IconName, Typography } from "@/components/ui";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
+import { useChats } from "@/providers/chats-provider";
import { ROUTES } from "@/shared/constants/client-routes";
import { useDrawer } from "..";
@@ -16,13 +14,11 @@ import styles from "./Header.module.scss";
interface HeaderProps {
className?: string;
- chatsPromise: Promise;
}
-export default function Header({ className, chatsPromise }: HeaderProps) {
+export default function Header({ className }: HeaderProps) {
const { open } = useDrawer();
- const chats = use(chatsPromise);
- const { totalUnreadCount } = useChatsSocket({ initialChats: chats });
+ const { totalUnreadCount } = useChats();
return (
diff --git a/src/components/layout/NavigationBar/NavigationBar.tsx b/src/components/layout/NavigationBar/NavigationBar.tsx
index eb3639d..45a0aee 100644
--- a/src/components/layout/NavigationBar/NavigationBar.tsx
+++ b/src/components/layout/NavigationBar/NavigationBar.tsx
@@ -1,14 +1,12 @@
"use client";
-import { use } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useLocale } from "next-intl";
import clsx from "clsx";
import { Badge, Icon, Typography } from "@/components/ui";
-import { IGetChatsListResponse } from "@/entities/chats/types";
-import { useChatsSocket } from "@/hooks/chats/useChatsSocket";
+import { useChats } from "@/providers/chats-provider";
import { ROUTES } from "@/shared/constants/client-routes";
import { NavItem, navItems } from "@/shared/constants/navigation";
import { stripLocale } from "@/shared/utils/path";
@@ -20,16 +18,11 @@ const getBadge = (item: NavItem, totalUnreadCount: number) => {
return null;
};
-interface NavigationBarProps {
- chatsPromise: Promise;
-}
-
-export default function NavigationBar({ chatsPromise }: NavigationBarProps) {
+export default function NavigationBar() {
const pathname = usePathname();
const locale = useLocale();
const pathnameWithoutLocale = stripLocale(pathname, locale);
- const chats = use(chatsPromise);
- const { totalUnreadCount } = useChatsSocket({ initialChats: chats });
+ const { totalUnreadCount } = useChats();
return (