├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── firebase-messaging-sw.js
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.test.tsx
├── IsMobileViewContext.ts
├── assets
│ ├── Image-518@1x.png
│ ├── add-members.svg
│ ├── audio-bubble.svg
│ ├── avatar.png
│ ├── badge.png
│ ├── ban-members.svg
│ ├── captainamerica_avatar.png
│ ├── cometchat_logo.png
│ ├── composer.png
│ ├── contacts.svg
│ ├── conversation.png
│ ├── create-group.svg
│ ├── cyclops_avatar.png
│ ├── details.svg
│ ├── file-bubble.svg
│ ├── group-member.svg
│ ├── image-bubble.svg
│ ├── info.svg
│ ├── ironman_avatar.png
│ ├── list.png
│ ├── listwrapper.png
│ ├── loading_icon.gif
│ ├── localize.png
│ ├── new.svg
│ ├── password-group.svg
│ ├── power-off.png
│ ├── receipt.png
│ ├── right-arrow.png
│ ├── sample.mp3
│ ├── sidebar.png
│ ├── sound-small.png
│ ├── spiderman_avatar.png
│ ├── status.png
│ ├── switch-mode.png
│ ├── text-bubble.svg
│ ├── theme.png
│ ├── transfer-ownership-icon.svg
│ ├── video-bubble.svg
│ └── wolverine_avatar.png
├── components
│ ├── App
│ │ ├── App.tsx
│ │ └── style.ts
│ ├── Button
│ │ ├── effects.ts
│ │ └── index.tsx
│ ├── ConversationsWithMessages.tsx
│ ├── Login
│ │ ├── index.tsx
│ │ └── style.ts
│ ├── LoginSignup
│ │ ├── index.tsx
│ │ └── style.ts
│ ├── Signup
│ │ ├── index.tsx
│ │ └── style.ts
│ └── TextInput
│ │ ├── index.tsx
│ │ └── style.ts
├── const.ts
├── custom-hooks.ts
├── firebase.js
├── index.css
├── index.tsx
├── logo.svg
├── react-app-env.d.ts
├── reportWebVitals.ts
├── sampleApp
│ └── sampledata.js
├── setupTests.ts
└── subject.js
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # React Enhanced Push notifications (Beta) Sample app
6 |
7 | The CometChat React [Enhanced Push notifications (Beta)](https://www.cometchat.com/docs-beta/notifications/push-overview) Sample app is a fully functional push notification app capable of one-on-one (private) and group messaging, and Calling. This sample app enables users to send and receive push notifications for text and multimedia messages like **images, videos, documents** and **Custom Messages**.
8 |
9 | > [!NOTE]
10 | > If you are using Push Notifications (Extension), please refer to our [React Push Notifications (Extension)](https://github.com/cometchat/cometchat-push-notification-app-react/tree/v4-push-notifications-extension) Sample app for guidance.
11 |
12 | ## Pre-requisite
13 |
14 | 1. Login to the [CometChat Dashboard](https://app.cometchat.com/).
15 | 2. Select an existing app or create a new one.
16 | 3. Click on the Notifications section from the menu on the left.
17 | 4. Enable Push Notifications by clicking on the toggle bar and configure the push notifications.
18 | 5. Add credentials for FCM and make a note of the provider id.
19 |
20 | ## Run the Sample App
21 |
22 | 1. Clone this repository.
23 | 2. Install the dependencies:
24 |
25 | ```
26 | npm i
27 | ```
28 |
29 | 3. Paste the `firebaseConfig` in the correct location as per FCM's documentation.
30 | 4. Add your app credentials like `appId`, `region`, `authKey` in the `src/const.ts`.
31 | 5. Also add the `fcmProviderId` in `src/const.ts` as that is required while registering push token.
32 | 6. Add `vapidKey` obtained from the Firebase console -> Cloud Messaging -> Web Push Certificates to the `firebase.js`.
33 | 7. Run the sample app.
34 | ```
35 | npm start
36 | ```
37 |
38 | 8. Once the app opens up in a browser, login with a user.
39 | 9. Allow the permission to display push notifications.
40 | 10. Send a message or call to the logged in user from another browser/device.
41 | 11. You should see a push notification for a message.
42 | 12. Tap on the notification to open the Sample app for message.
43 |
44 | ## Help and Support
45 |
46 | For issues running the project or integrating with our UI Kits, consult our [documentation](https://www.cometchat.com/docs-beta/notifications/push-overview) or create a [support ticket](https://help.cometchat.com/hc/en-us) or seek real-time support via the [CometChat Dashboard](https://app.cometchat.com/).
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v4-react-push",
3 | "version": "0.1.1",
4 | "private": true,
5 | "dependencies": {
6 | "@cometchat/calls-sdk-javascript": "^4.0.9",
7 | "@cometchat/chat-sdk-javascript": "^4.0.6",
8 | "@cometchat/chat-uikit-react": "^4.3.8",
9 | "@cometchat/uikit-elements": "^4.3.9",
10 | "@cometchat/uikit-resources": "^4.3.8",
11 | "@cometchat/uikit-shared": "^4.3.10",
12 | "@testing-library/jest-dom": "^5.17.0",
13 | "@testing-library/react": "^13.4.0",
14 | "@testing-library/user-event": "^13.5.0",
15 | "@types/jest": "^27.5.2",
16 | "@types/node": "^16.18.48",
17 | "@types/react": "^18.2.21",
18 | "@types/react-dom": "^18.2.7",
19 | "@types/react-router-dom": "^5.3.3",
20 | "firebase": "^10.3.1",
21 | "react": "^18.2.0",
22 | "react-dom": "^18.2.0",
23 | "react-hot-toast": "^2.4.1",
24 | "react-router-dom": "^6.16.0",
25 | "react-scripts": "5.0.1",
26 | "typescript": "^4.9.5",
27 | "web-vitals": "^2.1.4"
28 | },
29 | "scripts": {
30 | "start": "react-scripts start",
31 | "build": "react-scripts build",
32 | "test": "react-scripts test",
33 | "eject": "react-scripts eject"
34 | },
35 | "eslintConfig": {
36 | "extends": [
37 | "react-app",
38 | "react-app/jest"
39 | ]
40 | },
41 | "browserslist": {
42 | "production": [
43 | ">0.2%",
44 | "not dead",
45 | "not op_mini all"
46 | ],
47 | "development": [
48 | "last 1 chrome version",
49 | "last 1 firefox version",
50 | "last 1 safari version"
51 | ]
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/public/favicon.ico
--------------------------------------------------------------------------------
/public/firebase-messaging-sw.js:
--------------------------------------------------------------------------------
1 | // /* eslint-disable no-restricted-globals */
2 | // /* eslint-disable no-undef */
3 | // // required to setup background notification handler when browser is not in focus or in background and
4 | // // In order to receive the onMessage event, app must define the Firebase messaging service worker
5 | // // self.importScripts("localforage.js");
6 |
7 | importScripts(
8 | "https://www.gstatic.com/firebasejs/9.15.0/firebase-app-compat.js"
9 | );
10 | importScripts(
11 | "https://www.gstatic.com/firebasejs/9.15.0/firebase-messaging-compat.js"
12 | );
13 | var TAG = "[Firebase-sw.js]";
14 |
15 | self.addEventListener("notificationclick", async function (event) {
16 | console.log(TAG, "notificationclick", event, event.clientId);
17 | if (event?.notification?.data) {
18 | let data = event.notification.data;
19 | event.waitUntil(
20 | self.clients
21 | .matchAll({ type: "window", includeUncontrolled: true })
22 | .then((clientList) => {
23 | if (clientList.length > 0) {
24 | clientList[0].postMessage({
25 | message: data,
26 | });
27 | return (
28 | clientList[0]
29 | .focus()
30 | .catch((error) => {
31 | console.log(error);
32 | return self.clients.openWindow(clientList[0].url); // Adjust this URL as necessary for your application
33 | })
34 | );
35 | } else {
36 | // Open a new client (tab) if there are no existing clients
37 | self.clients.openWindow("/");
38 | setTimeout(() => {
39 | self.clients
40 | .matchAll({ type: "window", includeUncontrolled: true })
41 | .then((clientList) => {
42 | if (clientList.length > 0) {
43 | clientList[0].postMessage({
44 | message: {...data,fromBackground: true},
45 | });
46 | }
47 | return;
48 | });
49 | }, 1500);
50 | }
51 | })
52 | );
53 | }
54 |
55 | event.notification.close();
56 | });
57 | // "Default" Firebase configuration (prevents errors)
58 | const defaultConfig = {
59 | apiKey: true,
60 | projectId: true,
61 | messagingSenderId: true,
62 | appId: true,
63 | };
64 |
65 | // Initialize Firebase app
66 | firebase.initializeApp(self.firebaseConfig || defaultConfig);
67 | let messaging;
68 | try {
69 | messaging = firebase.messaging();
70 | // Customize background notification handling here
71 | messaging.onBackgroundMessage((payload) => {
72 | console.log("Background Message:", payload);
73 | const notificationTitle = payload.data.title;
74 | if (
75 | payload.data.type === "call" &&
76 | (payload.data.callAction === "unanswered" ||
77 | payload.data.callAction === "busy" ||
78 | payload.data.callAction === "ongoing")
79 | ) {
80 | return;
81 | }
82 | let body = payload.data.body;
83 | if (payload.data.type === "call") {
84 | switch (payload.data.callAction) {
85 | case "cancelled":
86 | body = `Call cancelled`;
87 | break;
88 | case "initiated":
89 | body = `Incoming ${payload.data.callType} call`;
90 | break;
91 | default:
92 | break;
93 | }
94 | }
95 | const notificationOptions = {
96 | title: payload.data.title,
97 | icon: payload.data.senderAvatar,
98 | data: payload.data,
99 | tag: payload.data.tag,
100 | body: body,
101 | };
102 | self.registration.showNotification(notificationTitle, notificationOptions);
103 | });
104 | } catch (err) {
105 | console.error("Failed to initialize Firebase Messaging", err);
106 | }
107 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/App.css
--------------------------------------------------------------------------------
/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render, screen } from "@testing-library/react";
3 | import App from "./components/App/App";
4 |
5 | test("renders learn react link", () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/IsMobileViewContext.ts:
--------------------------------------------------------------------------------
1 | import { createContext } from "react";
2 |
3 | export const IsMobileViewContext = createContext(false);
4 |
--------------------------------------------------------------------------------
/src/assets/Image-518@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/Image-518@1x.png
--------------------------------------------------------------------------------
/src/assets/add-members.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/audio-bubble.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/src/assets/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/avatar.png
--------------------------------------------------------------------------------
/src/assets/badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/badge.png
--------------------------------------------------------------------------------
/src/assets/ban-members.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/captainamerica_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/captainamerica_avatar.png
--------------------------------------------------------------------------------
/src/assets/cometchat_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/cometchat_logo.png
--------------------------------------------------------------------------------
/src/assets/composer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/composer.png
--------------------------------------------------------------------------------
/src/assets/contacts.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/conversation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/conversation.png
--------------------------------------------------------------------------------
/src/assets/create-group.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/cyclops_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/cyclops_avatar.png
--------------------------------------------------------------------------------
/src/assets/details.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/src/assets/file-bubble.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/group-member.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
71 |
--------------------------------------------------------------------------------
/src/assets/image-bubble.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/info.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/ironman_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/ironman_avatar.png
--------------------------------------------------------------------------------
/src/assets/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/list.png
--------------------------------------------------------------------------------
/src/assets/listwrapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/listwrapper.png
--------------------------------------------------------------------------------
/src/assets/loading_icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/loading_icon.gif
--------------------------------------------------------------------------------
/src/assets/localize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/localize.png
--------------------------------------------------------------------------------
/src/assets/new.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/password-group.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/power-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/power-off.png
--------------------------------------------------------------------------------
/src/assets/receipt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/receipt.png
--------------------------------------------------------------------------------
/src/assets/right-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/right-arrow.png
--------------------------------------------------------------------------------
/src/assets/sample.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/sample.mp3
--------------------------------------------------------------------------------
/src/assets/sidebar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/sidebar.png
--------------------------------------------------------------------------------
/src/assets/sound-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/sound-small.png
--------------------------------------------------------------------------------
/src/assets/spiderman_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/spiderman_avatar.png
--------------------------------------------------------------------------------
/src/assets/status.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/status.png
--------------------------------------------------------------------------------
/src/assets/switch-mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/switch-mode.png
--------------------------------------------------------------------------------
/src/assets/text-bubble.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
63 |
--------------------------------------------------------------------------------
/src/assets/theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/theme.png
--------------------------------------------------------------------------------
/src/assets/transfer-ownership-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/video-bubble.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/assets/wolverine_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cometchat/cometchat-push-notification-app-react/769451dad40e9d6f25fc7f7c27a82f2144eb8006/src/assets/wolverine_avatar.png
--------------------------------------------------------------------------------
/src/components/App/App.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-unused-vars */
2 | import { Navigate, Route, Routes, useNavigate } from "react-router-dom";
3 |
4 | import { CometChatTheme } from "@cometchat/chat-uikit-react";
5 | import { useEffect, useLayoutEffect, useState } from "react";
6 | import { CometChat } from "@cometchat/chat-sdk-javascript";
7 | import { Login } from "../Login";
8 | import { IsMobileViewContext } from "../../IsMobileViewContext";
9 | import { appStyle } from "./style";
10 |
11 | import firebaseInitialize from "../../firebase";
12 | import ConversationsWithMessages from "../ConversationsWithMessages";
13 | function App() {
14 | const navigate = useNavigate();
15 | const [isMobileView, setIsMobileView] = useState(false);
16 | const [theme, setTheme] = useState(new CometChatTheme({}));
17 |
18 |
19 | useEffect(() => {
20 | // Assuming the service worker has already been registered elsewhere
21 | if (navigator.serviceWorker) {
22 | // Listen for messages from the service worker
23 | const handleServiceWorkerMessage = (event: any) => {
24 | console.log(
25 | "Received a message from service worker:",
26 | event,
27 | event.data.message
28 | );
29 | // Handle the message or payload here
30 | // You can pass the message to your component's state or context
31 | if (navigate) {
32 | navigate("/conversationsWithMessages", { state: event.data.message });
33 | return;
34 | }
35 | };
36 |
37 | navigator.serviceWorker.addEventListener(
38 | "message",
39 | handleServiceWorkerMessage
40 | );
41 |
42 | // Cleanup listener when the component unmounts
43 | return () => {
44 | navigator.serviceWorker.removeEventListener(
45 | "message",
46 | handleServiceWorkerMessage
47 | );
48 | };
49 | }
50 | }, []);
51 |
52 | useLayoutEffect(() => {
53 | firebaseInitialize(navigate);
54 | },[])
55 |
56 | useEffect(() => {
57 | function handleResize() {
58 | if (window.innerWidth <= 768) setIsMobileView(true);
59 | else setIsMobileView(false);
60 | }
61 | window.addEventListener("resize", handleResize);
62 | }, [setIsMobileView]);
63 |
64 | return (
65 |
66 |
72 |
83 |
84 |
85 |
86 | }>
87 | }
90 | />
91 |
92 | } />
93 |
94 |
95 |
96 |
97 |
98 |
99 | );
100 | }
101 |
102 | const CheckLogin = () => {
103 | const [loggedInUser, setLoggedInUser] = useState<
104 | CometChat.User | null | undefined
105 | >(null);
106 | const [interestingAsyncOpStarted, setInterestingAsyncOpStarted] = useState(
107 | false
108 | );
109 | const navigate = useNavigate();
110 | useLayoutEffect(() => {
111 | (async () => {
112 | try {
113 | setLoggedInUser(await CometChat.getLoggedinUser());
114 | } catch (error) {
115 | console.log(error);
116 | }
117 | })();
118 | }, []);
119 |
120 | useEffect(() => {
121 | if (loggedInUser) {
122 | navigate("/conversationsWithMessages");
123 | }
124 | }, [loggedInUser])
125 |
126 | return (
127 |
132 | );
133 | };
134 |
135 | export default App;
136 |
--------------------------------------------------------------------------------
/src/components/App/style.ts:
--------------------------------------------------------------------------------
1 | import { CSSProperties } from "react";
2 | import { CometChatTheme } from "@cometchat/uikit-resources";
3 |
4 | const LOGGED_IN_USER_INFO_CONTAINER_HEIGHT = "48px";
5 | const FOOTER_HEIGHT = "48px";
6 |
7 | export function appStyle(theme: CometChatTheme): CSSProperties {
8 | return {
9 | height: "100%",
10 | boxSizing: "border-box",
11 | backgroundColor: theme.palette.getBackground(),
12 | position: "relative",
13 | overflowX: "hidden",
14 | };
15 | }
16 |
17 | export function footerStyle(): CSSProperties {
18 | return {
19 | display: "flex",
20 | justifyContent: "center",
21 | alignItems: "center",
22 | height: FOOTER_HEIGHT,
23 | };
24 | }
25 |
26 | export function messageStyle(isError: boolean): CSSProperties {
27 | return {
28 | padding: "16px",
29 | color: "white",
30 | textAlign: "center",
31 | backgroundColor: isError ? "red" : "green",
32 | borderRadius: "8px",
33 | width: "300px",
34 | boxSizing: "border-box",
35 | position: "fixed",
36 | top: "32px",
37 | left: "50%",
38 | transform: "translateX(-50%)",
39 | };
40 | }
41 |
42 | export function loggedInUserInfoContainerStyle(): CSSProperties {
43 | return {
44 | height: LOGGED_IN_USER_INFO_CONTAINER_HEIGHT,
45 | display: "flex",
46 | justifyContent: "flex-end",
47 | alignItems: "center",
48 | columnGap: "8px",
49 | padding: "0 16px",
50 | };
51 | }
52 |
53 | export function uidStyle(): CSSProperties {
54 | return {
55 | fontWeight: "600",
56 | };
57 | }
58 |
59 | export function logoutBtnStyle(): CSSProperties {
60 | return {
61 | cursor: "pointer",
62 | backgroundColor: "transparent",
63 | border: "none",
64 | };
65 | }
66 |
67 | export function logoutImgStyle(): CSSProperties {
68 | return {
69 | width: "24px",
70 | height: "24px",
71 | };
72 | }
73 |
74 | export function loadingModalStyle(showModal: boolean): CSSProperties {
75 | return {
76 | display: showModal ? "flex" : "none",
77 | width: "100vw",
78 | height: "100vh",
79 | backgroundColor: "#393b39",
80 | position: "fixed",
81 | top: "0",
82 | left: "0",
83 | justifyContent: "center",
84 | alignItems: "center",
85 | };
86 | }
87 |
88 | export function imageStyle(): CSSProperties {
89 | return {
90 | backgroundSize: "cover",
91 | };
92 | }
93 |
--------------------------------------------------------------------------------
/src/components/Button/effects.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | interface IEffectsProps {
4 | ref : React.MutableRefObject,
5 | onClickPropRef : React.MutableRefObject<((customEvent: CustomEvent<{event: PointerEvent}>) => void) | undefined>
6 | };
7 |
8 | export function Effects(props : IEffectsProps) {
9 | const {
10 | ref,
11 | onClickPropRef
12 | } = props;
13 |
14 | useEffect(() => {
15 | const buttonElement = ref.current;
16 | const eventName = "cc-button-clicked";
17 | const handleEvent = (e : CustomEvent<{event : PointerEvent}>) => onClickPropRef.current?.(e);
18 | buttonElement.addEventListener(eventName, handleEvent);
19 | return () => {
20 | buttonElement.removeEventListener(eventName, handleEvent);
21 | };
22 | }, [onClickPropRef, ref]); // Refs are in the dependency array to satisfy ESlint
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/Button/index.tsx:
--------------------------------------------------------------------------------
1 | import { CSSProperties, useRef } from "react";
2 | import { useRefSync } from "../../custom-hooks";
3 | import { Effects } from "./effects";
4 |
5 | export type ButtonStyle = {
6 | buttonTextFont?: string;
7 | buttonTextColor?: string;
8 | buttonIconTint?: string;
9 | } & CSSProperties;
10 |
11 | interface IButtonProps {
12 | text?: string;
13 | hoverText?: string;
14 | iconURL?: string;
15 | disabled?: boolean;
16 | buttonStyle?: ButtonStyle;
17 | onClick?: (customEvent: CustomEvent<{ event: PointerEvent }>) => void;
18 | }
19 |
20 | export function Button(props: IButtonProps) {
21 | const { text, hoverText, iconURL, disabled, buttonStyle, onClick } = props;
22 |
23 | const ref = useRef();
24 | const onClickPropRef = useRefSync(onClick);
25 |
26 | function getDisabledPropSpreadObject(): { disabled?: true } {
27 | return disabled ? { disabled } : {};
28 | }
29 |
30 | function getStylePropSpreadObject(
31 | styleObject: T1,
32 | stylePropName: T2
33 | ): { T2?: string } {
34 | return styleObject ? { [stylePropName]: JSON.stringify(styleObject) } : {};
35 | }
36 |
37 | Effects({
38 | ref,
39 | onClickPropRef,
40 | });
41 |
42 | return (
43 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/ConversationsWithMessages.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { CometChat, CometChatNotifications } from "@cometchat/chat-sdk-javascript";
3 | import {
4 | CometChatContacts,
5 | CometChatConversationsWithMessages,
6 | CometChatIncomingCall,
7 | CometChatTheme,
8 | CometChatUIKit,
9 | CometChatUIKitConstants,
10 | ConversationsConfiguration,
11 | } from "@cometchat/chat-uikit-react";
12 | import { useLocation, useNavigate } from "react-router-dom";
13 | import { Button } from "./Button";
14 | import PowerOff from "../assets/power-off.png";
15 | import newIcon from "../assets/new.svg";
16 |
17 | const incomingcallListenerId = "incomingcall_listener_id";
18 |
19 | function ConversationsWithMessages() {
20 | const [user, setUser] = useState();
21 | const [call, setCall] = useState();
22 | const [theme, setTheme] = useState(new CometChatTheme({}));
23 | const [group, setGroup] = useState();
24 | const [contacts, setContacts] = useState(false);
25 |
26 | const navigate = useNavigate();
27 |
28 | const { state } = useLocation();
29 |
30 | const logout = () => {
31 | CometChatNotifications.unregisterPushToken().then((res)=>{
32 | console.log(res);
33 | })
34 | CometChatUIKit.logout()!.then(
35 | () => {
36 | console.log("Logout completed successfully");
37 | navigate("/");
38 | },
39 | (error: any) => {
40 | console.log("Logout failed with exception:", { error });
41 | }
42 | );
43 | };
44 |
45 | useEffect(() => {
46 | CometChat.addCallListener(
47 | incomingcallListenerId,
48 | new CometChat.CallListener({
49 | onIncomingCallCancelled: (call: CometChat.Call) => {
50 | console.log("onIncomingCallCancelled", call);
51 | setCall(undefined);
52 | CometChat.removeCallListener(incomingcallListenerId);
53 | },
54 | onOutgoingCallRejected: (call: CometChat.Call) => {
55 | console.log("onOutgoingCallRejected", call);
56 | setCall(undefined);
57 | CometChat.removeCallListener(incomingcallListenerId);
58 | },
59 | })
60 | );
61 | return () => {
62 | CometChat.removeCallListener(incomingcallListenerId);
63 | };
64 | }, []);
65 |
66 | useEffect(() => {
67 | if (state && state.receiverType === "user" && state.sender) {
68 | CometChat.getUser(state.sender).then(async (user) => {
69 | setGroup(null);
70 | setUser(user);
71 | if (state.fromBackground && state.type === "call") {
72 | let newCall = new CometChat.Call(
73 | state.receiver,
74 | state.callType,
75 | state.receiverType
76 | );
77 | newCall.setSessionId(state.sessionId);
78 | newCall.setCallInitiator(new CometChat.User(user));
79 | newCall.setSender(user);
80 | setCall(newCall);
81 | }
82 | });
83 | } else if (state && state.receiverType === "group") {
84 | CometChat.getGroup(state.receiver).then((group) => {
85 | setUser(null);
86 | setGroup(group);
87 | });
88 | }
89 | }, [state]);
90 |
91 | return (
92 | <>
93 | {call ? (
94 | <>
95 | {
98 | CometChat.rejectCall(
99 | call.sessionId,
100 | CometChatUIKitConstants.calls.rejected
101 | )
102 | .then((rejectedCall: CometChat.Call) => {
103 | console.log("rejectedCall", rejectedCall);
104 | })
105 | .finally(() => {
106 | setCall(undefined);
107 | });
108 | CometChat.removeCallListener(incomingcallListenerId);
109 | }}
110 | onError={() => {
111 | console.log("onError");
112 | setCall(undefined);
113 | CometChat.removeCallListener(incomingcallListenerId);
114 | }}
115 | />
116 | >
117 | ) : (
118 |
119 | )}
120 | {contacts ? (
121 | {
123 | setUser(user);
124 | setGroup(group);
125 | setContacts(false);
126 | }}
127 | />
128 | ):
129 |
139 |
140 |
151 |
152 |