From cb7db3c13f9432902254d65804875ea700ae6c39 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:32:20 +0530 Subject: [PATCH] add special messages notification settings --- .../settings/notifications/AllMessages.tsx | 15 +- .../settings/notifications/Notifications.tsx | 2 + .../notifications/SpecialMessages.tsx | 222 ++++++++++++++++++ src/app/hooks/useNotificationMode.ts | 2 +- src/app/hooks/usePushRule.ts | 29 ++- 5 files changed, 261 insertions(+), 9 deletions(-) create mode 100644 src/app/features/settings/notifications/SpecialMessages.tsx diff --git a/src/app/features/settings/notifications/AllMessages.tsx b/src/app/features/settings/notifications/AllMessages.tsx index 8334fd38..301cb9a7 100644 --- a/src/app/features/settings/notifications/AllMessages.tsx +++ b/src/app/features/settings/notifications/AllMessages.tsx @@ -50,13 +50,14 @@ type PushRulesProps = { encrypted?: boolean; oneToOne?: boolean; }; -function AllMessagesModeSwitcher({ ruleId, pushRules, encrypted, oneToOne }: PushRulesProps) { +function AllMessagesModeSwitcher({ + ruleId, + pushRules, + encrypted = false, + oneToOne = false, +}: PushRulesProps) { const mx = useMatrixClient(); - const defaultPushRuleData = getAllMessageDefaultRule( - ruleId, - encrypted ?? false, - oneToOne ?? false - ); + const defaultPushRuleData = getAllMessageDefaultRule(ruleId, encrypted, oneToOne); const { kind, pushRule } = usePushRule(pushRules, ruleId) ?? defaultPushRuleData; const getModeActions = useNotificationModeActions(); @@ -83,7 +84,7 @@ export function AllMessagesNotifications() { All Messages - Hint: + Badge: 1 diff --git a/src/app/features/settings/notifications/Notifications.tsx b/src/app/features/settings/notifications/Notifications.tsx index c9e4ef72..d3f938dd 100644 --- a/src/app/features/settings/notifications/Notifications.tsx +++ b/src/app/features/settings/notifications/Notifications.tsx @@ -8,6 +8,7 @@ import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; import { usePermissionState } from '../../../hooks/usePermission'; import { AllMessagesNotifications } from './AllMessages'; +import { SpecialMessagesNotifications } from './SpecialMessages'; function SystemNotification() { const notifPermission = usePermissionState( @@ -102,6 +103,7 @@ export function Notifications({ requestClose }: NotificationsProps) { + diff --git a/src/app/features/settings/notifications/SpecialMessages.tsx b/src/app/features/settings/notifications/SpecialMessages.tsx new file mode 100644 index 00000000..cbebf648 --- /dev/null +++ b/src/app/features/settings/notifications/SpecialMessages.tsx @@ -0,0 +1,222 @@ +import React, { useCallback, useMemo } from 'react'; +import { ConditionKind, IPushRules, PushRuleKind, RuleId } from 'matrix-js-sdk'; +import { Box, Text, Badge } from 'folds'; +import { useAccountData } from '../../../hooks/useAccountData'; +import { AccountDataEvent } from '../../../../types/matrix/accountData'; +import { SequenceCard } from '../../../components/sequence-card'; +import { SequenceCardStyle } from '../styles.css'; +import { SettingTile } from '../../../components/setting-tile'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { useUserProfile } from '../../../hooks/useUserProfile'; +import { getMxIdLocalPart } from '../../../utils/matrix'; +import { makePushRuleData, PushRuleData, usePushRule } from '../../../hooks/usePushRule'; +import { + getNotificationModeActions, + NotificationMode, + NotificationModeOptions, + useNotificationModeActions, +} from '../../../hooks/useNotificationMode'; +import { NotificationModeSwitcher } from './NotificationModeSwitcher'; + +const NOTIFY_MODE_OPS: NotificationModeOptions = { + highlight: true, +}; +const getDefaultIsUserMention = (userId: string): PushRuleData => + makePushRuleData( + PushRuleKind.Override, + RuleId.IsUserMention, + getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }), + [ + { + kind: ConditionKind.EventPropertyContains, + key: 'content.m\\.mentions.user_ids', + value: userId, + }, + ] + ); + +const DefaultContainsDisplayName = makePushRuleData( + PushRuleKind.Override, + RuleId.ContainsDisplayName, + getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }), + [ + { + kind: ConditionKind.ContainsDisplayName, + }, + ] +); + +const getDefaultContainsUsername = (username: string) => + makePushRuleData( + PushRuleKind.ContentSpecific, + RuleId.ContainsUserName, + getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }), + undefined, + username + ); + +const DefaultIsRoomMention = makePushRuleData( + PushRuleKind.Override, + RuleId.IsRoomMention, + getNotificationModeActions(NotificationMode.Notify, { highlight: true }), + [ + { + kind: ConditionKind.EventPropertyIs, + key: 'content.m\\.mentions.room', + value: true, + }, + { + kind: ConditionKind.SenderNotificationPermission, + key: 'room', + }, + ] +); + +const DefaultAtRoomNotification = makePushRuleData( + PushRuleKind.Override, + RuleId.AtRoomNotification, + getNotificationModeActions(NotificationMode.Notify, { highlight: true }), + [ + { + kind: ConditionKind.EventMatch, + key: 'content.body', + pattern: '@room', + }, + { + kind: ConditionKind.SenderNotificationPermission, + key: 'room', + }, + ] +); + +type PushRulesProps = { + ruleId: RuleId; + pushRules: IPushRules; + defaultPushRuleData: PushRuleData; +}; +function MentionModeSwitcher({ ruleId, pushRules, defaultPushRuleData }: PushRulesProps) { + const mx = useMatrixClient(); + + const { kind, pushRule } = usePushRule(pushRules, ruleId) ?? defaultPushRuleData; + const getModeActions = useNotificationModeActions(NOTIFY_MODE_OPS); + + const handleChange = useCallback( + async (mode: NotificationMode) => { + const actions = getModeActions(mode); + await mx.setPushRuleActions('global', kind, ruleId, actions); + }, + [mx, getModeActions, kind, ruleId] + ); + + return ; +} + +export function SpecialMessagesNotifications() { + const mx = useMatrixClient(); + const userId = mx.getUserId()!; + const { displayName } = useUserProfile(userId); + const pushRulesEvt = useAccountData(AccountDataEvent.PushRules); + const pushRules = useMemo( + () => pushRulesEvt?.getContent() ?? { global: {} }, + [pushRulesEvt] + ); + + return ( + + + Special Messages + + Badge: + + 1 + + + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + ); +} diff --git a/src/app/hooks/useNotificationMode.ts b/src/app/hooks/useNotificationMode.ts index 8487d5f6..1c2267e6 100644 --- a/src/app/hooks/useNotificationMode.ts +++ b/src/app/hooks/useNotificationMode.ts @@ -7,7 +7,7 @@ export enum NotificationMode { NotifyLoud = 'NotifyLoud', } -type NotificationModeOptions = { +export type NotificationModeOptions = { soundValue?: string; highlight?: boolean; }; diff --git a/src/app/hooks/usePushRule.ts b/src/app/hooks/usePushRule.ts index 04f560c0..ec87c217 100644 --- a/src/app/hooks/usePushRule.ts +++ b/src/app/hooks/usePushRule.ts @@ -1,4 +1,11 @@ -import { IPushRule, IPushRules, PushRuleKind, RuleId } from 'matrix-js-sdk'; +import { + IPushRule, + IPushRules, + PushRuleAction, + PushRuleCondition, + PushRuleKind, + RuleId, +} from 'matrix-js-sdk'; import { useMemo } from 'react'; export type PushRuleData = { @@ -6,6 +13,26 @@ export type PushRuleData = { pushRule: IPushRule; }; +export const makePushRuleData = ( + kind: PushRuleKind, + ruleId: RuleId, + actions: PushRuleAction[], + conditions?: PushRuleCondition[], + pattern?: string, + enabled?: boolean, + _default?: boolean +): PushRuleData => ({ + kind, + pushRule: { + rule_id: ruleId, + default: _default ?? true, + enabled: enabled ?? true, + pattern, + conditions, + actions, + }, +}); + export const orderedPushRuleKinds: PushRuleKind[] = [ PushRuleKind.Override, PushRuleKind.ContentSpecific,