mirror of
https://github.com/danog/telegram-tt.git
synced 2025-01-22 05:11:55 +01:00
Notifications: Play sound when notifications are turned off (#1553)
This commit is contained in:
parent
7ea9dd116f
commit
04f8d03e82
@ -1,4 +1,5 @@
|
||||
import { ChangeEvent } from 'react';
|
||||
import useDebounce from '../../../hooks/useDebounce';
|
||||
import React, {
|
||||
FC, memo, useCallback, useEffect,
|
||||
} from '../../../lib/teact/teact';
|
||||
@ -10,6 +11,7 @@ import { SettingsScreens } from '../../../types';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
import { playNotifySound } from '../../../util/notifications';
|
||||
|
||||
import Checkbox from '../../ui/Checkbox';
|
||||
import RangeSlider from '../../ui/RangeSlider';
|
||||
@ -61,6 +63,8 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
loadNotificationSettings();
|
||||
}, [loadNotificationSettings]);
|
||||
|
||||
const runDebounced = useDebounce(500, false, true);
|
||||
|
||||
const handleSettingsChange = useCallback((
|
||||
e: ChangeEvent<HTMLInputElement>,
|
||||
peerType: 'contact' | 'group' | 'broadcast',
|
||||
@ -123,12 +127,12 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
<div className="settings-item-slider">
|
||||
<RangeSlider
|
||||
label="Sound"
|
||||
disabled={!hasWebNotifications}
|
||||
min={0}
|
||||
max={10}
|
||||
value={notificationSoundVolume}
|
||||
onChange={(volume) => {
|
||||
updateWebNotificationSettings({ notificationSoundVolume: volume });
|
||||
runDebounced(() => playNotifySound(undefined, volume));
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@ import { ApiUpdate, MAIN_THREAD_ID } from '../../../api/types';
|
||||
|
||||
import { ARCHIVED_FOLDER_ID, MAX_ACTIVE_PINNED_CHATS } from '../../../config';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import { closeMessageNotifications, showNewMessageNotification } from '../../../util/notifications';
|
||||
import { closeMessageNotifications, notifyAboutNewMessage } from '../../../util/notifications';
|
||||
import { updateAppBadge } from '../../../util/appBadge';
|
||||
import {
|
||||
updateChat,
|
||||
@ -20,7 +20,6 @@ import {
|
||||
selectChatListType,
|
||||
selectCurrentMessageList,
|
||||
selectCountNotMutedUnread,
|
||||
selectNotifySettings,
|
||||
} from '../../selectors';
|
||||
import { throttle } from '../../../util/schedulers';
|
||||
|
||||
@ -131,15 +130,11 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
}
|
||||
|
||||
updateAppBadge(selectCountNotMutedUnread(getGlobal()));
|
||||
|
||||
const { hasWebNotifications } = selectNotifySettings(global);
|
||||
if (hasWebNotifications) {
|
||||
showNewMessageNotification({
|
||||
chat,
|
||||
message,
|
||||
isActiveChat,
|
||||
});
|
||||
}
|
||||
notifyAboutNewMessage({
|
||||
chat,
|
||||
message,
|
||||
isActiveChat,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -90,22 +90,24 @@ const expirationTime = 12 * 60 * 60 * 1000; // 12 hours
|
||||
const soundPlayedDelay = 3 * 1000;
|
||||
const soundPlayedIds = new Set<string>();
|
||||
|
||||
async function playSound(id: string) {
|
||||
if (soundPlayedIds.has(id)) return;
|
||||
export async function playNotifySound(id?: string, volume?: number) {
|
||||
if (id !== undefined && soundPlayedIds.has(id)) return;
|
||||
const { notificationSoundVolume } = selectNotifySettings(getGlobal());
|
||||
const volume = notificationSoundVolume / 10;
|
||||
if (volume === 0) return;
|
||||
const currentVolume = volume ? volume / 10 : notificationSoundVolume / 10;
|
||||
if (currentVolume === 0) return;
|
||||
|
||||
const audio = new Audio('./notification.mp3');
|
||||
audio.volume = volume;
|
||||
audio.volume = currentVolume;
|
||||
audio.setAttribute('mozaudiochannel', 'notification');
|
||||
audio.addEventListener('ended', () => {
|
||||
soundPlayedIds.add(id);
|
||||
}, { once: true });
|
||||
if (id !== undefined) {
|
||||
audio.addEventListener('ended', () => {
|
||||
soundPlayedIds.add(id);
|
||||
}, { once: true });
|
||||
|
||||
setTimeout(() => {
|
||||
soundPlayedIds.delete(id);
|
||||
}, soundPlayedDelay);
|
||||
setTimeout(() => {
|
||||
soundPlayedIds.delete(id);
|
||||
}, soundPlayedDelay);
|
||||
}
|
||||
|
||||
try {
|
||||
await audio.play();
|
||||
@ -117,7 +119,7 @@ async function playSound(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export const playNotificationSound = debounce(playSound, 1000, true, false);
|
||||
export const playNotifySoundDebounced = debounce(playNotifySound, 1000, true, false);
|
||||
|
||||
function checkIfShouldResubscribe(subscription: PushSubscription | null) {
|
||||
const global = getGlobal();
|
||||
@ -168,7 +170,7 @@ let areSettingsLoaded = false;
|
||||
|
||||
// Load notification settings from the api
|
||||
async function loadNotificationSettings() {
|
||||
if (areSettingsLoaded) return;
|
||||
if (areSettingsLoaded) return selectNotifySettings(getGlobal());
|
||||
const [resultSettings, resultExceptions] = await Promise.all([
|
||||
callApi('fetchNotificationSettings', {
|
||||
serverTimeOffset: getGlobal().serverTimeOffset,
|
||||
@ -177,7 +179,7 @@ async function loadNotificationSettings() {
|
||||
serverTimeOffset: getGlobal().serverTimeOffset,
|
||||
}),
|
||||
]);
|
||||
if (!resultSettings) return;
|
||||
if (!resultSettings) return selectNotifySettings(getGlobal());
|
||||
|
||||
let global = replaceSettings(getGlobal(), resultSettings);
|
||||
if (resultExceptions) {
|
||||
@ -185,6 +187,7 @@ async function loadNotificationSettings() {
|
||||
}
|
||||
setGlobal(global);
|
||||
areSettingsLoaded = true;
|
||||
return selectNotifySettings(global);
|
||||
}
|
||||
|
||||
export async function subscribe() {
|
||||
@ -313,17 +316,21 @@ async function getAvatar(chat: ApiChat) {
|
||||
return mediaData;
|
||||
}
|
||||
|
||||
export async function showNewMessageNotification({
|
||||
export async function notifyAboutNewMessage({
|
||||
chat,
|
||||
message,
|
||||
isActiveChat,
|
||||
}: { chat: ApiChat; message: Partial<ApiMessage>; isActiveChat: boolean }) {
|
||||
const { hasWebNotifications } = await loadNotificationSettings();
|
||||
if (!checkIfShouldNotify(chat, isActiveChat)) return;
|
||||
if (!hasWebNotifications) {
|
||||
// only play sound if web notifications are disabled
|
||||
playNotifySoundDebounced(String(message.id) || chat.id);
|
||||
return;
|
||||
}
|
||||
if (!checkIfNotificationsSupported()) return;
|
||||
if (!message.id) return;
|
||||
|
||||
await loadNotificationSettings();
|
||||
if (!checkIfShouldNotify(chat, isActiveChat)) return;
|
||||
|
||||
const {
|
||||
title,
|
||||
body,
|
||||
@ -373,7 +380,7 @@ export async function showNewMessageNotification({
|
||||
|
||||
// Play sound when notification is displayed
|
||||
notification.onshow = () => {
|
||||
playNotificationSound(String(message.id) || chat.id);
|
||||
playNotifySoundDebounced(String(message.id) || chat.id);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { DEBUG } from '../config';
|
||||
import { getDispatch } from '../lib/teact/teactn';
|
||||
import { IS_ANDROID, IS_IOS, IS_SERVICE_WORKER_SUPPORTED } from './environment';
|
||||
import { notifyClientReady, playNotificationSound } from './notifications';
|
||||
import { notifyClientReady, playNotifySoundDebounced } from './notifications';
|
||||
|
||||
type WorkerAction = {
|
||||
type: string;
|
||||
@ -23,7 +23,7 @@ function handleWorkerMessage(e: MessageEvent) {
|
||||
}
|
||||
break;
|
||||
case 'playNotificationSound':
|
||||
playNotificationSound(action.payload.id);
|
||||
playNotifySoundDebounced(action.payload.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user