feautre/IO-3377-Add-Notification-Tone-For-Messaging - Complete

This commit is contained in:
Dave
2025-09-24 12:02:20 -04:00
parent 33579c3e6a
commit dfd88308e0
17 changed files with 404 additions and 95 deletions

View File

@@ -9,13 +9,13 @@ import "./chat-affix.styles.scss";
import { registerMessagingHandlers, unregisterMessagingHandlers } from "./registerMessagingSocketHandlers";
import { useSocket } from "../../contexts/SocketIO/useSocket.js";
export function ChatAffixContainer({ bodyshop, chatVisible }) {
export function ChatAffixContainer({ bodyshop, chatVisible, currentUser }) {
const { t } = useTranslation();
const client = useApolloClient();
const { socket } = useSocket();
useEffect(() => {
if (!bodyshop || !bodyshop.messagingservicesid) return;
if (!bodyshop?.messagingservicesid) return;
async function SubscribeToTopicForFCMNotification() {
try {
@@ -35,8 +35,8 @@ export function ChatAffixContainer({ bodyshop, chatVisible }) {
SubscribeToTopicForFCMNotification();
// Register WebSocket handlers
if (socket && socket.connected) {
registerMessagingHandlers({ socket, client });
if (socket?.connected) {
registerMessagingHandlers({ socket, client, currentUser });
return () => {
unregisterMessagingHandlers({ socket });
@@ -44,11 +44,11 @@ export function ChatAffixContainer({ bodyshop, chatVisible }) {
}
}, [bodyshop, socket, t, client]);
if (!bodyshop || !bodyshop.messagingservicesid) return <></>;
if (!bodyshop?.messagingservicesid) return <></>;
return (
<div className={`chat-affix ${chatVisible ? "chat-affix-open" : ""}`}>
{bodyshop && bodyshop.messagingservicesid ? <ChatPopupComponent /> : null}
{bodyshop?.messagingservicesid ? <ChatPopupComponent /> : null}
</div>
);
}

View File

@@ -1,5 +1,7 @@
import { CONVERSATION_LIST_QUERY, GET_CONVERSATION_DETAILS } from "../../graphql/conversations.queries";
import { gql } from "@apollo/client";
import { QUERY_ACTIVE_ASSOCIATION_SOUND } from "../../graphql/user.queries"; // the query you added earlier
import { playNewMessageSound } from "../../utils/soundManager.js";
const logLocal = (message, ...args) => {
if (import.meta.env.VITE_APP_IS_TEST || !import.meta.env.PROD) {
@@ -26,16 +28,48 @@ const enrichConversation = (conversation, isOutbound) => ({
__typename: "conversations"
});
export const registerMessagingHandlers = ({ socket, client }) => {
// Can be uncommonted to test the playback of the notification sound
// window.testTone = () => {
// const notificationSound = new Audio(newMessageSound);
// notificationSound.play().catch((error) => {
// console.error("Error playing notification sound:", error);
// });
// };
export const registerMessagingHandlers = ({ socket, client, currentUser }) => {
if (!(socket && client)) return;
const handleNewMessageSummary = async (message) => {
const { conversationId, newConversation, existingConversation, isoutbound } = message;
// True only when DB value is strictly true; falls back to true on cache miss
const isNewMessageSoundEnabled = (client) => {
try {
const email = currentUser?.email; // adjust if you keep email elsewhere
if (!email) return true; // default allow if we can't resolve user
const res = client.readQuery({
query: QUERY_ACTIVE_ASSOCIATION_SOUND,
variables: { email }
});
const flag = res?.associations?.[0]?.new_message_sound;
return flag === true; // strictly true => enabled
} catch {
// If the query hasn't been seeded in cache yet, default ON
return true;
}
};
logLocal("handleNewMessageSummary - Start", { message, isNew: !existingConversation });
const queryVariables = { offset: 0 };
if (!isoutbound) {
// Play notification sound for new inbound message
if (isNewMessageSoundEnabled(client)) {
playNewMessageSound();
}
}
if (!existingConversation && conversationId) {
// Attempt to read from the cache to determine if this is actually a new conversation
try {
@@ -328,7 +362,8 @@ export const registerMessagingHandlers = ({ socket, client }) => {
}
break;
case "tag-added": { // Ensure `job_conversations` is properly formatted
case "tag-added": {
// Ensure `job_conversations` is properly formatted
const formattedJobConversations = job_conversations.map((jc) => ({
__typename: "job_conversations",
jobid: jc.jobid || jc.job?.id,