mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-09 16:50:28 +03:00
Add option to change room notification settings (#2281)
This commit is contained in:
parent
074a5e855d
commit
71bfc96b5c
12 changed files with 409 additions and 164 deletions
|
|
@ -7,6 +7,19 @@ export enum NotificationMode {
|
|||
NotifyLoud = 'NotifyLoud',
|
||||
}
|
||||
|
||||
export const getNotificationMode = (actions: PushRuleAction[]): NotificationMode => {
|
||||
const soundTweak = actions.find(
|
||||
(action) => typeof action === 'object' && action.set_tweak === TweakName.Sound
|
||||
);
|
||||
const notify = actions.find(
|
||||
(action) => typeof action === 'string' && action === PushRuleActionName.Notify
|
||||
);
|
||||
|
||||
if (notify && soundTweak) return NotificationMode.NotifyLoud;
|
||||
if (notify) return NotificationMode.Notify;
|
||||
return NotificationMode.OFF;
|
||||
};
|
||||
|
||||
export type NotificationModeOptions = {
|
||||
soundValue?: string;
|
||||
highlight?: boolean;
|
||||
|
|
@ -49,18 +62,7 @@ export const useNotificationModeActions = (
|
|||
};
|
||||
|
||||
export const useNotificationActionsMode = (actions: PushRuleAction[]): NotificationMode => {
|
||||
const mode: NotificationMode = useMemo(() => {
|
||||
const soundTweak = actions.find(
|
||||
(action) => typeof action === 'object' && action.set_tweak === TweakName.Sound
|
||||
);
|
||||
const notify = actions.find(
|
||||
(action) => typeof action === 'string' && action === PushRuleActionName.Notify
|
||||
);
|
||||
|
||||
if (notify && soundTweak) return NotificationMode.NotifyLoud;
|
||||
if (notify) return NotificationMode.Notify;
|
||||
return NotificationMode.OFF;
|
||||
}, [actions]);
|
||||
const mode: NotificationMode = useMemo(() => getNotificationMode(actions), [actions]);
|
||||
|
||||
return mode;
|
||||
};
|
||||
|
|
|
|||
169
src/app/hooks/useRoomsNotificationPreferences.ts
Normal file
169
src/app/hooks/useRoomsNotificationPreferences.ts
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
import { createContext, useCallback, useContext, useMemo } from 'react';
|
||||
import { ConditionKind, IPushRules, MatrixClient, PushRuleKind } from 'matrix-js-sdk';
|
||||
import { Icons, IconSrc } from 'folds';
|
||||
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||
import { useAccountData } from './useAccountData';
|
||||
import { isRoomId } from '../utils/matrix';
|
||||
import {
|
||||
getNotificationMode,
|
||||
getNotificationModeActions,
|
||||
NotificationMode,
|
||||
} from './useNotificationMode';
|
||||
import { useAsyncCallback } from './useAsyncCallback';
|
||||
import { useMatrixClient } from './useMatrixClient';
|
||||
|
||||
export type RoomsNotificationPreferences = {
|
||||
mute: Set<string>;
|
||||
specialMessages: Set<string>;
|
||||
allMessages: Set<string>;
|
||||
};
|
||||
|
||||
const RoomsNotificationPreferencesContext = createContext<RoomsNotificationPreferences | null>(
|
||||
null
|
||||
);
|
||||
export const RoomsNotificationPreferencesProvider = RoomsNotificationPreferencesContext.Provider;
|
||||
|
||||
export const useRoomsNotificationPreferencesContext = (): RoomsNotificationPreferences => {
|
||||
const preferences = useContext(RoomsNotificationPreferencesContext);
|
||||
|
||||
if (!preferences) {
|
||||
throw new Error('No RoomsNotificationPreferences provided!');
|
||||
}
|
||||
|
||||
return preferences;
|
||||
};
|
||||
|
||||
export const useRoomsNotificationPreferences = (): RoomsNotificationPreferences => {
|
||||
const pushRules = useAccountData(AccountDataEvent.PushRules)?.getContent<IPushRules>();
|
||||
|
||||
const preferences: RoomsNotificationPreferences = useMemo(() => {
|
||||
const global = pushRules?.global;
|
||||
const room = global?.room ?? [];
|
||||
const override = global?.override ?? [];
|
||||
|
||||
const pref: RoomsNotificationPreferences = {
|
||||
mute: new Set(),
|
||||
specialMessages: new Set(),
|
||||
allMessages: new Set(),
|
||||
};
|
||||
|
||||
override.forEach((rule) => {
|
||||
if (isRoomId(rule.rule_id) && getNotificationMode(rule.actions) === NotificationMode.OFF) {
|
||||
pref.mute.add(rule.rule_id);
|
||||
}
|
||||
});
|
||||
room.forEach((rule) => {
|
||||
if (getNotificationMode(rule.actions) === NotificationMode.OFF) {
|
||||
pref.specialMessages.add(rule.rule_id);
|
||||
}
|
||||
});
|
||||
room.forEach((rule) => {
|
||||
if (getNotificationMode(rule.actions) !== NotificationMode.OFF) {
|
||||
pref.allMessages.add(rule.rule_id);
|
||||
}
|
||||
});
|
||||
|
||||
return pref;
|
||||
}, [pushRules]);
|
||||
|
||||
return preferences;
|
||||
};
|
||||
|
||||
export enum RoomNotificationMode {
|
||||
Unset = 'Unset',
|
||||
Mute = 'Mute',
|
||||
SpecialMessages = 'SpecialMessages',
|
||||
AllMessages = 'AllMessages',
|
||||
}
|
||||
|
||||
export const getRoomNotificationMode = (
|
||||
preferences: RoomsNotificationPreferences,
|
||||
roomId: string
|
||||
): RoomNotificationMode => {
|
||||
if (preferences.mute.has(roomId)) {
|
||||
return RoomNotificationMode.Mute;
|
||||
}
|
||||
if (preferences.specialMessages.has(roomId)) {
|
||||
return RoomNotificationMode.SpecialMessages;
|
||||
}
|
||||
if (preferences.allMessages.has(roomId)) {
|
||||
return RoomNotificationMode.AllMessages;
|
||||
}
|
||||
|
||||
return RoomNotificationMode.Unset;
|
||||
};
|
||||
|
||||
export const useRoomNotificationPreference = (
|
||||
preferences: RoomsNotificationPreferences,
|
||||
roomId: string
|
||||
): RoomNotificationMode =>
|
||||
useMemo(() => getRoomNotificationMode(preferences, roomId), [preferences, roomId]);
|
||||
|
||||
export const getRoomNotificationModeIcon = (mode?: RoomNotificationMode): IconSrc => {
|
||||
if (mode === RoomNotificationMode.Mute) return Icons.BellMute;
|
||||
if (mode === RoomNotificationMode.SpecialMessages) return Icons.BellPing;
|
||||
if (mode === RoomNotificationMode.AllMessages) return Icons.BellRing;
|
||||
|
||||
return Icons.Bell;
|
||||
};
|
||||
|
||||
export const setRoomNotificationPreference = async (
|
||||
mx: MatrixClient,
|
||||
roomId: string,
|
||||
mode: RoomNotificationMode,
|
||||
previousMode: RoomNotificationMode
|
||||
): Promise<void> => {
|
||||
// remove the old preference
|
||||
if (
|
||||
previousMode === RoomNotificationMode.AllMessages ||
|
||||
previousMode === RoomNotificationMode.SpecialMessages
|
||||
) {
|
||||
await mx.deletePushRule('global', PushRuleKind.RoomSpecific, roomId);
|
||||
}
|
||||
if (previousMode === RoomNotificationMode.Mute) {
|
||||
await mx.deletePushRule('global', PushRuleKind.Override, roomId);
|
||||
}
|
||||
|
||||
// set new preference
|
||||
if (mode === RoomNotificationMode.Unset) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === RoomNotificationMode.Mute) {
|
||||
await mx.addPushRule('global', PushRuleKind.Override, roomId, {
|
||||
conditions: [
|
||||
{
|
||||
kind: ConditionKind.EventMatch,
|
||||
key: 'room_id',
|
||||
pattern: roomId,
|
||||
},
|
||||
],
|
||||
actions: getNotificationModeActions(NotificationMode.OFF),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await mx.addPushRule('global', PushRuleKind.RoomSpecific, roomId, {
|
||||
actions:
|
||||
mode === RoomNotificationMode.AllMessages
|
||||
? getNotificationModeActions(NotificationMode.NotifyLoud)
|
||||
: getNotificationModeActions(NotificationMode.OFF),
|
||||
});
|
||||
};
|
||||
|
||||
export const useSetRoomNotificationPreference = (roomId: string) => {
|
||||
const mx = useMatrixClient();
|
||||
|
||||
const [modeState, setMode] = useAsyncCallback(
|
||||
useCallback(
|
||||
(mode: RoomNotificationMode, previousMode: RoomNotificationMode) =>
|
||||
setRoomNotificationPreference(mx, roomId, mode, previousMode),
|
||||
[mx, roomId]
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
modeState,
|
||||
setMode,
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue