Skip to content

Commit

Permalink
Fix unread reset and notification settings (cinnyapp#1824)
Browse files Browse the repository at this point in the history
* reset unread with client sync state change

* fix notification toggle setting not working

* revert formatOnSave vscode setting
  • Loading branch information
ajbura authored Jul 23, 2024
1 parent e2228a1 commit e6d6b03
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 100 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ module.exports = {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-shadow": "error"
},
overrides: [
{
files: ['*.ts'],
rules: {
'no-undef': 'off',
},
},
],
};
28 changes: 0 additions & 28 deletions src/app/hooks/usePermission.js

This file was deleted.

30 changes: 30 additions & 0 deletions src/app/hooks/usePermission.ts
Original file line number Diff line number Diff line change
@@ -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;
}
29 changes: 16 additions & 13 deletions src/app/organisms/settings/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
}}
/>
);
Expand All @@ -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>
Expand All @@ -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>}
Expand Down
5 changes: 3 additions & 2 deletions src/app/pages/client/ClientNonUIFeatures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -84,15 +85,15 @@ function InviteNotifications() {

useEffect(() => {
if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') {
if (Notification.permission === 'granted') {
if (showNotifications && Notification.permission === 'granted') {
notify(invites.length - perviousInviteLen);
}

if (notificationSound) {
playSound();
}
}
}, [mx, invites, perviousInviteLen, notificationSound, notify, playSound]);
}, [mx, invites, perviousInviteLen, showNotifications, notificationSound, notify, playSound]);

return (
// eslint-disable-next-line jsx-a11y/media-has-caption
Expand Down
7 changes: 5 additions & 2 deletions src/app/state/room/roomToUnread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
12 changes: 0 additions & 12 deletions src/client/action/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,3 @@ export function toggleNickAvatarEvents() {
type: cons.actions.settings.TOGGLE_NICKAVATAR_EVENT,
});
}

export function toggleNotifications() {
appDispatcher.dispatch({
type: cons.actions.settings.TOGGLE_NOTIFICATIONS,
});
}

export function toggleNotificationSounds() {
appDispatcher.dispatch({
type: cons.actions.settings.TOGGLE_NOTIFICATION_SOUNDS,
});
}
4 changes: 0 additions & 4 deletions src/client/state/cons.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ const cons = {
TOGGLE_PEOPLE_DRAWER: 'TOGGLE_PEOPLE_DRAWER',
TOGGLE_MEMBERSHIP_EVENT: 'TOGGLE_MEMBERSHIP_EVENT',
TOGGLE_NICKAVATAR_EVENT: 'TOGGLE_NICKAVATAR_EVENT',
TOGGLE_NOTIFICATIONS: 'TOGGLE_NOTIFICATIONS',
TOGGLE_NOTIFICATION_SOUNDS: 'TOGGLE_NOTIFICATION_SOUNDS',
},
},
events: {
Expand Down Expand Up @@ -81,8 +79,6 @@ const cons = {
PEOPLE_DRAWER_TOGGLED: 'PEOPLE_DRAWER_TOGGLED',
MEMBERSHIP_EVENTS_TOGGLED: 'MEMBERSHIP_EVENTS_TOGGLED',
NICKAVATAR_EVENTS_TOGGLED: 'NICKAVATAR_EVENTS_TOGGLED',
NOTIFICATIONS_TOGGLED: 'NOTIFICATIONS_TOGGLED',
NOTIFICATION_SOUNDS_TOGGLED: 'NOTIFICATION_SOUNDS_TOGGLED',
},
},
};
Expand Down
39 changes: 0 additions & 39 deletions src/client/state/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ class Settings extends EventEmitter {
this.isPeopleDrawer = this.getIsPeopleDrawer();
this.hideMembershipEvents = this.getHideMembershipEvents();
this.hideNickAvatarEvents = this.getHideNickAvatarEvents();
this._showNotifications = this.getShowNotifications();
this.isNotificationSounds = this.getIsNotificationSounds();

this.darkModeQueryList = window.matchMedia('(prefers-color-scheme: dark)');

Expand Down Expand Up @@ -137,29 +135,6 @@ class Settings extends EventEmitter {
return settings.isPeopleDrawer;
}

get showNotifications() {
if (window.Notification?.permission !== 'granted') return false;
return this._showNotifications;
}

getShowNotifications() {
if (typeof this._showNotifications === 'boolean') return this._showNotifications;

const settings = getSettings();
if (settings === null) return true;
if (typeof settings.showNotifications === 'undefined') return true;
return settings.showNotifications;
}

getIsNotificationSounds() {
if (typeof this.isNotificationSounds === 'boolean') return this.isNotificationSounds;

const settings = getSettings();
if (settings === null) return true;
if (typeof settings.isNotificationSounds === 'undefined') return true;
return settings.isNotificationSounds;
}

setter(action) {
const actions = {
[cons.actions.settings.TOGGLE_SYSTEM_THEME]: () => {
Expand All @@ -185,20 +160,6 @@ class Settings extends EventEmitter {
setSettings('hideNickAvatarEvents', this.hideNickAvatarEvents);
this.emit(cons.events.settings.NICKAVATAR_EVENTS_TOGGLED, this.hideNickAvatarEvents);
},
[cons.actions.settings.TOGGLE_NOTIFICATIONS]: async () => {
if (window.Notification?.permission !== 'granted') {
this._showNotifications = false;
} else {
this._showNotifications = !this._showNotifications;
}
setSettings('showNotifications', this._showNotifications);
this.emit(cons.events.settings.NOTIFICATIONS_TOGGLED, this._showNotifications);
},
[cons.actions.settings.TOGGLE_NOTIFICATION_SOUNDS]: () => {
this.isNotificationSounds = !this.isNotificationSounds;
setSettings('isNotificationSounds', this.isNotificationSounds);
this.emit(cons.events.settings.NOTIFICATION_SOUNDS_TOGGLED, this.isNotificationSounds);
},
};

actions[action.type]?.();
Expand Down

0 comments on commit e6d6b03

Please sign in to comment.