Notifications: Fix pinned message ignore mute (#6897)
This commit is contained in:
parent
d8f913b3a0
commit
881c09acdf
@ -1909,6 +1909,7 @@
|
|||||||
"ActionPinnedTextYou" = "You pinned \"{text}\"";
|
"ActionPinnedTextYou" = "You pinned \"{text}\"";
|
||||||
"ActionPinnedNotFound" = "{from} pinned a message";
|
"ActionPinnedNotFound" = "{from} pinned a message";
|
||||||
"ActionPinnedNotFoundYou" = "You pinned a message";
|
"ActionPinnedNotFoundYou" = "You pinned a message";
|
||||||
|
"PinnedMessagesNotifications" = "Pinned Messages";
|
||||||
"ActionPinnedMedia" = "{from} pinned {media}";
|
"ActionPinnedMedia" = "{from} pinned {media}";
|
||||||
"ActionPinnedMediaYou" = "You pinned {media}";
|
"ActionPinnedMediaYou" = "You pinned {media}";
|
||||||
"ActionPinnedMediaPhoto" = "a photo";
|
"ActionPinnedMediaPhoto" = "a photo";
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import type { ChangeEvent } from 'react';
|
|
||||||
import type { FC } from '../../../lib/teact/teact';
|
|
||||||
import { memo, useCallback, useEffect } from '../../../lib/teact/teact';
|
import { memo, useCallback, useEffect } from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
@ -26,22 +24,25 @@ type OwnProps = {
|
|||||||
type StateProps = {
|
type StateProps = {
|
||||||
notifyDefaults?: Record<ApiNotifyPeerType, ApiPeerNotifySettings>;
|
notifyDefaults?: Record<ApiNotifyPeerType, ApiPeerNotifySettings>;
|
||||||
hasContactJoinedNotifications: boolean;
|
hasContactJoinedNotifications: boolean;
|
||||||
|
shouldNotifyAboutPinnedMessages: boolean;
|
||||||
hasWebNotifications: boolean;
|
hasWebNotifications: boolean;
|
||||||
hasPushNotifications: boolean;
|
hasPushNotifications: boolean;
|
||||||
notificationSoundVolume: number;
|
notificationSoundVolume: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SettingsNotifications: FC<OwnProps & StateProps> = ({
|
const SettingsNotifications = ({
|
||||||
isActive,
|
isActive,
|
||||||
onReset,
|
onReset,
|
||||||
notifyDefaults,
|
notifyDefaults,
|
||||||
hasContactJoinedNotifications,
|
hasContactJoinedNotifications,
|
||||||
|
shouldNotifyAboutPinnedMessages,
|
||||||
hasPushNotifications,
|
hasPushNotifications,
|
||||||
hasWebNotifications,
|
hasWebNotifications,
|
||||||
notificationSoundVolume,
|
notificationSoundVolume,
|
||||||
}) => {
|
}: OwnProps & StateProps) => {
|
||||||
const {
|
const {
|
||||||
loadNotificationSettings,
|
loadNotificationSettings,
|
||||||
|
setSettingOption,
|
||||||
updateContactSignUpNotification,
|
updateContactSignUpNotification,
|
||||||
updateNotificationSettings,
|
updateNotificationSettings,
|
||||||
updateWebNotificationSettings,
|
updateWebNotificationSettings,
|
||||||
@ -61,7 +62,7 @@ const SettingsNotifications: FC<OwnProps & StateProps> = ({
|
|||||||
const areUsersMuted = Boolean(notifyDefaults?.users?.mutedUntil);
|
const areUsersMuted = Boolean(notifyDefaults?.users?.mutedUntil);
|
||||||
|
|
||||||
const handleSettingsChange = useCallback((
|
const handleSettingsChange = useCallback((
|
||||||
e: ChangeEvent<HTMLInputElement>,
|
e: React.ChangeEvent<HTMLInputElement>,
|
||||||
peerType: ApiNotifyPeerType,
|
peerType: ApiNotifyPeerType,
|
||||||
setting: 'mute' | 'showPreviews',
|
setting: 'mute' | 'showPreviews',
|
||||||
) => {
|
) => {
|
||||||
@ -73,52 +74,56 @@ const SettingsNotifications: FC<OwnProps & StateProps> = ({
|
|||||||
isMuted: setting === 'mute' ? !e.target.checked : currentIsMuted,
|
isMuted: setting === 'mute' ? !e.target.checked : currentIsMuted,
|
||||||
shouldShowPreviews: setting === 'showPreviews' ? e.target.checked : currentShouldShowPreviews,
|
shouldShowPreviews: setting === 'showPreviews' ? e.target.checked : currentShouldShowPreviews,
|
||||||
});
|
});
|
||||||
}, [notifyDefaults]);
|
}, [notifyDefaults, updateNotificationSettings]);
|
||||||
|
|
||||||
const handleWebNotificationsChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleWebNotificationsChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const isEnabled = e.target.checked;
|
const isEnabled = e.target.checked;
|
||||||
updateWebNotificationSettings({
|
updateWebNotificationSettings({
|
||||||
hasWebNotifications: isEnabled,
|
hasWebNotifications: isEnabled,
|
||||||
...(!isEnabled && { hasPushNotifications: false }),
|
hasPushNotifications: isEnabled ? undefined : false,
|
||||||
});
|
});
|
||||||
}, [updateWebNotificationSettings]);
|
}, [updateWebNotificationSettings]);
|
||||||
|
|
||||||
const handlePushNotificationsChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handlePushNotificationsChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
updateWebNotificationSettings({
|
updateWebNotificationSettings({
|
||||||
hasPushNotifications: e.target.checked,
|
hasPushNotifications: e.target.checked,
|
||||||
});
|
});
|
||||||
}, [updateWebNotificationSettings]);
|
}, [updateWebNotificationSettings]);
|
||||||
|
|
||||||
const handlePrivateChatsNotificationsChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handlePrivateChatsNotificationsChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'users', 'mute');
|
handleSettingsChange(e, 'users', 'mute');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handlePrivateChatsPreviewChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handlePrivateChatsPreviewChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'users', 'showPreviews');
|
handleSettingsChange(e, 'users', 'showPreviews');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handleGroupsNotificationsChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleGroupsNotificationsChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'groups', 'mute');
|
handleSettingsChange(e, 'groups', 'mute');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handleGroupsPreviewChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleGroupsPreviewChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'groups', 'showPreviews');
|
handleSettingsChange(e, 'groups', 'showPreviews');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handleChannelsNotificationsChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleChannelsNotificationsChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'channels', 'mute');
|
handleSettingsChange(e, 'channels', 'mute');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handleChannelsPreviewChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleChannelsPreviewChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
handleSettingsChange(e, 'channels', 'showPreviews');
|
handleSettingsChange(e, 'channels', 'showPreviews');
|
||||||
}, [handleSettingsChange]);
|
}, [handleSettingsChange]);
|
||||||
|
|
||||||
const handleContactNotificationChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const handleContactNotificationChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
updateContactSignUpNotification({
|
updateContactSignUpNotification({
|
||||||
isSilent: !e.target.checked,
|
isSilent: !e.target.checked,
|
||||||
});
|
});
|
||||||
}, [updateContactSignUpNotification]);
|
}, [updateContactSignUpNotification]);
|
||||||
|
|
||||||
|
const handlePinnedMessagesNotificationChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setSettingOption({ shouldNotifyAboutPinnedMessages: e.target.checked });
|
||||||
|
}, [setSettingOption]);
|
||||||
|
|
||||||
const handleVolumeChange = useCallback((volume: number) => {
|
const handleVolumeChange = useCallback((volume: number) => {
|
||||||
updateWebNotificationSettings({
|
updateWebNotificationSettings({
|
||||||
notificationSoundVolume: volume,
|
notificationSoundVolume: volume,
|
||||||
@ -233,6 +238,11 @@ const SettingsNotifications: FC<OwnProps & StateProps> = ({
|
|||||||
checked={hasContactJoinedNotifications}
|
checked={hasContactJoinedNotifications}
|
||||||
onChange={handleContactNotificationChange}
|
onChange={handleContactNotificationChange}
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={lang('PinnedMessagesNotifications')}
|
||||||
|
checked={shouldNotifyAboutPinnedMessages}
|
||||||
|
onChange={handlePinnedMessagesNotificationChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -242,6 +252,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global): Complete<StateProps> => {
|
(global): Complete<StateProps> => {
|
||||||
return {
|
return {
|
||||||
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
|
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
|
||||||
|
shouldNotifyAboutPinnedMessages: global.settings.byKey.shouldNotifyAboutPinnedMessages,
|
||||||
hasWebNotifications: global.settings.byKey.hasWebNotifications,
|
hasWebNotifications: global.settings.byKey.hasWebNotifications,
|
||||||
hasPushNotifications: global.settings.byKey.hasPushNotifications,
|
hasPushNotifications: global.settings.byKey.hasPushNotifications,
|
||||||
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
|
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type {
|
import type {
|
||||||
ApiChat,
|
ApiChat,
|
||||||
|
ApiMessage,
|
||||||
ApiNotifyPeerType,
|
ApiNotifyPeerType,
|
||||||
ApiPeer,
|
ApiPeer,
|
||||||
ApiPeerNotifySettings,
|
ApiPeerNotifySettings,
|
||||||
@ -39,6 +40,20 @@ export function getShouldShowMessagePreview(
|
|||||||
return Boolean(settings?.shouldShowPreviews);
|
return Boolean(settings?.shouldShowPreviews);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getShouldIgnoreNotificationMute(
|
||||||
|
message: Partial<ApiMessage>,
|
||||||
|
shouldNotifyAboutPinnedMessages: boolean,
|
||||||
|
) {
|
||||||
|
if (!message.isMentioned) return false;
|
||||||
|
|
||||||
|
const isPinMessage = message.content?.action?.type === 'pinMessage';
|
||||||
|
if (isPinMessage) {
|
||||||
|
return shouldNotifyAboutPinnedMessages && !message.isSilent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
export function getChatNotifySettings(
|
export function getChatNotifySettings(
|
||||||
chat: ApiChat,
|
chat: ApiChat,
|
||||||
notifyDefaults?: Record<ApiNotifyPeerType, ApiPeerNotifySettings>,
|
notifyDefaults?: Record<ApiNotifyPeerType, ApiPeerNotifySettings>,
|
||||||
|
|||||||
@ -300,6 +300,7 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
|
|||||||
autoLoadFileMaxSizeMb: 10,
|
autoLoadFileMaxSizeMb: 10,
|
||||||
hasWebNotifications: true,
|
hasWebNotifications: true,
|
||||||
hasPushNotifications: true,
|
hasPushNotifications: true,
|
||||||
|
shouldNotifyAboutPinnedMessages: true,
|
||||||
notificationSoundVolume: 5,
|
notificationSoundVolume: 5,
|
||||||
shouldSuggestStickers: true,
|
shouldSuggestStickers: true,
|
||||||
shouldSuggestCustomEmoji: true,
|
shouldSuggestCustomEmoji: true,
|
||||||
|
|||||||
@ -139,6 +139,7 @@ export interface AccountSettings {
|
|||||||
hasWebNotifications: boolean;
|
hasWebNotifications: boolean;
|
||||||
hasPushNotifications: boolean;
|
hasPushNotifications: boolean;
|
||||||
hasContactJoinedNotifications?: boolean;
|
hasContactJoinedNotifications?: boolean;
|
||||||
|
shouldNotifyAboutPinnedMessages: boolean;
|
||||||
notificationSoundVolume: number;
|
notificationSoundVolume: number;
|
||||||
canAutoLoadPhotoFromContacts: boolean;
|
canAutoLoadPhotoFromContacts: boolean;
|
||||||
canAutoLoadPhotoInPrivateChats: boolean;
|
canAutoLoadPhotoInPrivateChats: boolean;
|
||||||
|
|||||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -1543,6 +1543,7 @@ export interface LangPair {
|
|||||||
'ActionFallbackSomeone': undefined;
|
'ActionFallbackSomeone': undefined;
|
||||||
'ActionUnsupported': undefined;
|
'ActionUnsupported': undefined;
|
||||||
'ActionPinnedNotFoundYou': undefined;
|
'ActionPinnedNotFoundYou': undefined;
|
||||||
|
'PinnedMessagesNotifications': undefined;
|
||||||
'ActionPinnedMediaPhoto': undefined;
|
'ActionPinnedMediaPhoto': undefined;
|
||||||
'ActionPinnedMediaVideo': undefined;
|
'ActionPinnedMediaVideo': undefined;
|
||||||
'ActionPinnedMediaAudio': undefined;
|
'ActionPinnedMediaAudio': undefined;
|
||||||
|
|||||||
@ -13,7 +13,12 @@ import {
|
|||||||
getMessageRecentReaction,
|
getMessageRecentReaction,
|
||||||
getUserFullName,
|
getUserFullName,
|
||||||
} from '../global/helpers';
|
} from '../global/helpers';
|
||||||
import { getIsChatMuted, getIsChatSilent, getShouldShowMessagePreview } from '../global/helpers/notifications';
|
import {
|
||||||
|
getIsChatMuted,
|
||||||
|
getIsChatSilent,
|
||||||
|
getShouldIgnoreNotificationMute,
|
||||||
|
getShouldShowMessagePreview,
|
||||||
|
} from '../global/helpers/notifications';
|
||||||
import { getMessageSenderName } from '../global/helpers/peers';
|
import { getMessageSenderName } from '../global/helpers/peers';
|
||||||
import {
|
import {
|
||||||
selectCurrentMessageList,
|
selectCurrentMessageList,
|
||||||
@ -291,10 +296,13 @@ function checkIfShouldNotify(chat: ApiChat, message: Partial<ApiMessage>) {
|
|||||||
const topic = selectTopicFromMessage(global, message as ApiMessage);
|
const topic = selectTopicFromMessage(global, message as ApiMessage);
|
||||||
const topicMutedUntil = topic?.notifySettings.mutedUntil;
|
const topicMutedUntil = topic?.notifySettings.mutedUntil;
|
||||||
const isMuted = topicMutedUntil === undefined ? isChatMuted : topicMutedUntil > getServerTime();
|
const isMuted = topicMutedUntil === undefined ? isChatMuted : topicMutedUntil > getServerTime();
|
||||||
const shouldIgnoreMute = message.isMentioned;
|
const shouldNotifyAboutPinnedMessages = global.settings.byKey.shouldNotifyAboutPinnedMessages;
|
||||||
|
const shouldIgnoreMute = getShouldIgnoreNotificationMute(message, shouldNotifyAboutPinnedMessages);
|
||||||
|
|
||||||
|
const isPinMessage = message.content?.action?.type === 'pinMessage';
|
||||||
|
const shouldSkipPinnedMessageNotification = isPinMessage && !shouldNotifyAboutPinnedMessages;
|
||||||
const shouldNotifyAboutMessage = message.content?.action?.type !== 'phoneCall';
|
const shouldNotifyAboutMessage = message.content?.action?.type !== 'phoneCall';
|
||||||
if ((isMuted && !shouldIgnoreMute) || !shouldNotifyAboutMessage
|
if (shouldSkipPinnedMessageNotification || (isMuted && !shouldIgnoreMute) || !shouldNotifyAboutMessage
|
||||||
|| chat.isNotJoined || !chat.isListed || selectIsChatWithSelf(global, chat.id)) {
|
|| chat.isNotJoined || !chat.isListed || selectIsChatWithSelf(global, chat.id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -496,7 +504,7 @@ export async function notifyAboutMessage({
|
|||||||
// Play sound when notification is displayed
|
// Play sound when notification is displayed
|
||||||
notification.onshow = () => {
|
notification.onshow = () => {
|
||||||
// TODO Update when reaction badges are implemented
|
// TODO Update when reaction badges are implemented
|
||||||
if (isReaction || message.isSilent || IS_TAURI) return;
|
if (isSilent || isReaction || message.isSilent || IS_TAURI) return;
|
||||||
playNotifySoundDebounced(String(message.id) || chat.id);
|
playNotifySoundDebounced(String(message.id) || chat.id);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user