mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-14 03:00:29 +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
|
|
@ -2,7 +2,6 @@ import { MatrixClient } from 'matrix-js-sdk';
|
|||
import { allInvitesAtom, useBindAllInvitesAtom } from '../room-list/inviteList';
|
||||
import { allRoomsAtom, useBindAllRoomsAtom } from '../room-list/roomList';
|
||||
import { mDirectAtom, useBindMDirectAtom } from '../mDirectList';
|
||||
import { muteChangesAtom, mutedRoomsAtom, useBindMutedRoomsAtom } from '../room-list/mutedRoomList';
|
||||
import { roomToUnreadAtom, useBindRoomToUnreadAtom } from '../room/roomToUnread';
|
||||
import { roomToParentsAtom, useBindRoomToParentsAtom } from '../room/roomToParents';
|
||||
import { roomIdToTypingMembersAtom, useBindRoomIdToTypingMembersAtom } from '../typingMembers';
|
||||
|
|
@ -12,8 +11,7 @@ export const useBindAtoms = (mx: MatrixClient) => {
|
|||
useBindAllInvitesAtom(mx, allInvitesAtom);
|
||||
useBindAllRoomsAtom(mx, allRoomsAtom);
|
||||
useBindRoomToParentsAtom(mx, roomToParentsAtom);
|
||||
useBindMutedRoomsAtom(mx, mutedRoomsAtom);
|
||||
useBindRoomToUnreadAtom(mx, roomToUnreadAtom, muteChangesAtom);
|
||||
useBindRoomToUnreadAtom(mx, roomToUnreadAtom);
|
||||
|
||||
useBindRoomIdToTypingMembersAtom(mx, roomIdToTypingMembersAtom);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
import { atom, useSetAtom } from 'jotai';
|
||||
import { ClientEvent, IPushRule, IPushRules, MatrixClient, MatrixEvent } from 'matrix-js-sdk';
|
||||
import { useEffect } from 'react';
|
||||
import { MuteChanges } from '../../../types/matrix/room';
|
||||
import { findMutedRule, isMutedRule } from '../../utils/room';
|
||||
|
||||
export type MutedRoomsUpdate =
|
||||
| {
|
||||
type: 'INITIALIZE';
|
||||
addRooms: string[];
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE';
|
||||
addRooms: string[];
|
||||
removeRooms: string[];
|
||||
};
|
||||
|
||||
export const muteChangesAtom = atom<MuteChanges>({
|
||||
added: [],
|
||||
removed: [],
|
||||
});
|
||||
|
||||
const baseMutedRoomsAtom = atom(new Set<string>());
|
||||
export const mutedRoomsAtom = atom<Set<string>, [MutedRoomsUpdate], undefined>(
|
||||
(get) => get(baseMutedRoomsAtom),
|
||||
(get, set, action) => {
|
||||
const mutedRooms = new Set([...get(mutedRoomsAtom)]);
|
||||
if (action.type === 'INITIALIZE') {
|
||||
set(baseMutedRoomsAtom, new Set([...action.addRooms]));
|
||||
set(muteChangesAtom, {
|
||||
added: [...action.addRooms],
|
||||
removed: [],
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (action.type === 'UPDATE') {
|
||||
action.removeRooms.forEach((roomId) => mutedRooms.delete(roomId));
|
||||
action.addRooms.forEach((roomId) => mutedRooms.add(roomId));
|
||||
set(baseMutedRoomsAtom, mutedRooms);
|
||||
set(muteChangesAtom, {
|
||||
added: [...action.addRooms],
|
||||
removed: [...action.removeRooms],
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const useBindMutedRoomsAtom = (mx: MatrixClient, mutedAtom: typeof mutedRoomsAtom) => {
|
||||
const setMuted = useSetAtom(mutedAtom);
|
||||
|
||||
useEffect(() => {
|
||||
const overrideRules = mx.getAccountData('m.push_rules')?.getContent<IPushRules>()
|
||||
?.global?.override;
|
||||
if (overrideRules) {
|
||||
const mutedRooms = overrideRules.reduce<string[]>((rooms, rule) => {
|
||||
if (isMutedRule(rule)) rooms.push(rule.rule_id);
|
||||
return rooms;
|
||||
}, []);
|
||||
setMuted({
|
||||
type: 'INITIALIZE',
|
||||
addRooms: mutedRooms,
|
||||
});
|
||||
}
|
||||
}, [mx, setMuted]);
|
||||
|
||||
useEffect(() => {
|
||||
const handlePushRules = (mEvent: MatrixEvent, oldMEvent?: MatrixEvent) => {
|
||||
if (mEvent.getType() === 'm.push_rules') {
|
||||
const override = mEvent?.getContent()?.global?.override as IPushRule[] | undefined;
|
||||
const oldOverride = oldMEvent?.getContent()?.global?.override as IPushRule[] | undefined;
|
||||
if (!override || !oldOverride) return;
|
||||
|
||||
const isMuteToggled = (rule: IPushRule, otherOverride: IPushRule[]) => {
|
||||
const roomId = rule.rule_id;
|
||||
|
||||
const isMuted = isMutedRule(rule);
|
||||
if (!isMuted) return false;
|
||||
const isOtherMuted = findMutedRule(otherOverride, roomId);
|
||||
if (isOtherMuted) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
const mutedRules = override.filter((rule) => isMuteToggled(rule, oldOverride));
|
||||
const unMutedRules = oldOverride.filter((rule) => isMuteToggled(rule, override));
|
||||
|
||||
setMuted({
|
||||
type: 'UPDATE',
|
||||
addRooms: mutedRules.map((rule) => rule.rule_id),
|
||||
removeRooms: unMutedRules.map((rule) => rule.rule_id),
|
||||
});
|
||||
}
|
||||
};
|
||||
mx.on(ClientEvent.AccountData, handlePushRules);
|
||||
return () => {
|
||||
mx.removeListener(ClientEvent.AccountData, handlePushRules);
|
||||
};
|
||||
}, [mx, setMuted]);
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import produce from 'immer';
|
||||
import { atom, useSetAtom, PrimitiveAtom, useAtomValue } from 'jotai';
|
||||
import { atom, useSetAtom } from 'jotai';
|
||||
import {
|
||||
IRoomTimelineData,
|
||||
MatrixClient,
|
||||
|
|
@ -11,7 +11,6 @@ import {
|
|||
import { ReceiptContent, ReceiptType } from 'matrix-js-sdk/lib/@types/read_receipts';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import {
|
||||
MuteChanges,
|
||||
Membership,
|
||||
NotificationType,
|
||||
RoomToUnread,
|
||||
|
|
@ -25,11 +24,11 @@ import {
|
|||
getUnreadInfo,
|
||||
getUnreadInfos,
|
||||
isNotificationEvent,
|
||||
roomHaveUnread,
|
||||
} from '../../utils/room';
|
||||
import { roomToParentsAtom } from './roomToParents';
|
||||
import { useStateEventCallback } from '../../hooks/useStateEventCallback';
|
||||
import { useSyncState } from '../../hooks/useSyncState';
|
||||
import { useRoomsNotificationPreferencesContext } from '../../hooks/useRoomsNotificationPreferences';
|
||||
|
||||
export type RoomToUnreadAction =
|
||||
| {
|
||||
|
|
@ -167,13 +166,9 @@ export const roomToUnreadAtom = atom<RoomToUnread, [RoomToUnreadAction], undefin
|
|||
}
|
||||
);
|
||||
|
||||
export const useBindRoomToUnreadAtom = (
|
||||
mx: MatrixClient,
|
||||
unreadAtom: typeof roomToUnreadAtom,
|
||||
muteChangesAtom: PrimitiveAtom<MuteChanges>
|
||||
) => {
|
||||
export const useBindRoomToUnreadAtom = (mx: MatrixClient, unreadAtom: typeof roomToUnreadAtom) => {
|
||||
const setUnreadAtom = useSetAtom(unreadAtom);
|
||||
const muteChanges = useAtomValue(muteChangesAtom);
|
||||
const roomsNotificationPreferences = useRoomsNotificationPreferencesContext();
|
||||
|
||||
useEffect(() => {
|
||||
setUnreadAtom({
|
||||
|
|
@ -249,16 +244,11 @@ export const useBindRoomToUnreadAtom = (
|
|||
}, [mx, setUnreadAtom]);
|
||||
|
||||
useEffect(() => {
|
||||
muteChanges.removed.forEach((roomId) => {
|
||||
const room = mx.getRoom(roomId);
|
||||
if (!room) return;
|
||||
if (!roomHaveUnread(mx, room)) return;
|
||||
setUnreadAtom({ type: 'PUT', unreadInfo: getUnreadInfo(room) });
|
||||
setUnreadAtom({
|
||||
type: 'RESET',
|
||||
unreadInfos: getUnreadInfos(mx),
|
||||
});
|
||||
muteChanges.added.forEach((roomId) => {
|
||||
setUnreadAtom({ type: 'DELETE', roomId });
|
||||
});
|
||||
}, [mx, setUnreadAtom, muteChanges]);
|
||||
}, [mx, setUnreadAtom, roomsNotificationPreferences]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleMembershipChange = (room: Room, membership: string) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue