Fix unread reset and notification settings (#1824)

* reset unread with client sync state change

* fix notification toggle setting not working

* revert formatOnSave vscode setting
This commit is contained in:
Ajay Bura 2024-07-23 10:44:32 +05:30 committed by GitHub
parent e2228a18c1
commit e6d6b0349e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 62 additions and 100 deletions

View file

@ -1,28 +0,0 @@
/* eslint-disable import/prefer-default-export */
import { useEffect, useState } from 'react';
export function usePermission(name, initial) {
const [state, setState] = useState(initial);
useEffect(() => {
let descriptor;
const update = () => setState(descriptor.state);
if (navigator.permissions?.query) {
navigator.permissions.query({ name }).then((_descriptor) => {
descriptor = _descriptor;
update();
descriptor.addEventListener('change', update);
});
}
return () => {
if (descriptor) descriptor.removeEventListener('change', update);
};
}, []);
return [state, setState];
}

View file

@ -0,0 +1,30 @@
import { useEffect, useState } from "react";
export function usePermissionState(name: PermissionName, initialValue: PermissionState = 'prompt') {
const [permissionState, setPermissionState] = useState<PermissionState>(initialValue);
useEffect(() => {
let permissionStatus: PermissionStatus;
function handlePermissionChange(this: PermissionStatus) {
setPermissionState(this.state);
}
navigator.permissions
.query({ name })
.then((permStatus: PermissionStatus) => {
permissionStatus = permStatus;
handlePermissionChange.apply(permStatus);
permStatus.addEventListener("change", handlePermissionChange);
})
.catch(() => {
// Silence error since FF doesn't support microphone permission
});
return () => {
permissionStatus?.removeEventListener("change", handlePermissionChange);
};
}, [name]);
return permissionState;
}

View file

@ -7,9 +7,8 @@ import settings from '../../../client/state/settings';
import navigation from '../../../client/state/navigation';
import {
toggleSystemTheme,
toggleNotifications, toggleNotificationSounds,
} from '../../../client/action/settings';
import { usePermission } from '../../hooks/usePermission';
import { usePermissionState } from '../../hooks/usePermission';
import Text from '../../atoms/text/Text';
import IconButton from '../../atoms/button/IconButton';
@ -230,23 +229,25 @@ function AppearanceSection() {
}
function NotificationsSection() {
const [permission, setPermission] = usePermission('notifications', window.Notification?.permission);
const [, updateState] = useState({});
const notifPermission = usePermissionState('notifications', window.Notification?.permission ?? "denied");
const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications')
const [isNotificationSounds, setIsNotificationSounds] = useSetting(settingsAtom, 'isNotificationSounds')
const renderOptions = () => {
if (window.Notification === undefined) {
return <Text className="settings-notifications__not-supported">Not supported in this browser.</Text>;
}
if (permission === 'granted') {
if (notifPermission === 'denied') {
return <Text>Permission Denied</Text>
}
if (notifPermission === 'granted') {
return (
<Toggle
isActive={settings._showNotifications}
isActive={showNotifications}
onToggle={() => {
toggleNotifications();
setPermission(window.Notification?.permission);
updateState({});
setShowNotifications(!showNotifications);
}}
/>
);
@ -255,7 +256,9 @@ function NotificationsSection() {
return (
<Button
variant="primary"
onClick={() => window.Notification.requestPermission().then(setPermission)}
onClick={() => window.Notification.requestPermission().then(() => {
setShowNotifications(window.Notification?.permission === 'granted');
})}
>
Request permission
</Button>
@ -275,8 +278,8 @@ function NotificationsSection() {
title="Notification Sound"
options={(
<Toggle
isActive={settings.isNotificationSounds}
onToggle={() => { toggleNotificationSounds(); updateState({}); }}
isActive={isNotificationSounds}
onToggle={() => setIsNotificationSounds(!isNotificationSounds)}
/>
)}
content={<Text variant="b3">Play sound when new messages arrive.</Text>}

View file

@ -58,6 +58,7 @@ function InviteNotifications() {
const mx = useMatrixClient();
const navigate = useNavigate();
const [showNotifications] = useSetting(settingsAtom, 'showNotifications');
const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds');
const notify = useCallback(
@ -84,7 +85,7 @@ function InviteNotifications() {
useEffect(() => {
if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') {
if (Notification.permission === 'granted') {
if (showNotifications && Notification.permission === 'granted') {
notify(invites.length - perviousInviteLen);
}
@ -92,7 +93,7 @@ function InviteNotifications() {
playSound();
}
}
}, [mx, invites, perviousInviteLen, notificationSound, notify, playSound]);
}, [mx, invites, perviousInviteLen, showNotifications, notificationSound, notify, playSound]);
return (
// eslint-disable-next-line jsx-a11y/media-has-caption

View file

@ -185,8 +185,11 @@ export const useBindRoomToUnreadAtom = (
useSyncState(
mx,
useCallback(
(state) => {
if (state === SyncState.Prepared) {
(state, prevState) => {
if (
(state === SyncState.Prepared && prevState === null) ||
(state === SyncState.Syncing && prevState !== SyncState.Syncing)
) {
setUnreadAtom({
type: 'RESET',
unreadInfos: getUnreadInfos(mx),