Skip to content

Commit

Permalink
[Glitch] Further de-emphasize filtered notifications banner and add s…
Browse files Browse the repository at this point in the history
…etting to minimize it

Port ad95c98 to glitch-soc

Signed-off-by: Claire <[email protected]>
  • Loading branch information
ClearlyClaire committed Aug 2, 2024
1 parent f273671 commit 1ca81a1
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 106 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { PropsWithChildren } from 'react';
import { useCallback } from 'react';

import Toggle from 'react-toggle';

interface Props {
checked: boolean;
disabled?: boolean;
onChange: (checked: boolean) => void;
}

export const CheckboxWithLabel: React.FC<PropsWithChildren<Props>> = ({
checked,
disabled,
children,
onChange,
}) => {
const handleChange = useCallback(
({ target }: React.ChangeEvent<HTMLInputElement>) => {
onChange(target.checked);
},
[onChange],
);

return (
<label className='app-form__toggle'>
<div className='app-form__toggle__label'>{children}</div>

<div className='app-form__toggle__toggle'>
<div>
<Toggle
checked={checked}
onChange={handleChange}
disabled={disabled}
/>
</div>
</div>
</label>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'flavours/glitch/permissions';

import { CheckboxWithLabel } from './checkbox_with_label';
import ClearColumnButton from './clear_column_button';
import GrantPermissionButton from './grant_permission_button';
import PillBarButton from './pill_bar_button';
import { PolicyControls } from './policy_controls';
import SettingToggle from './setting_toggle';

class ColumnSettings extends PureComponent {
Expand All @@ -25,32 +25,14 @@ class ColumnSettings extends PureComponent {
alertsEnabled: PropTypes.bool,
browserSupport: PropTypes.bool,
browserPermission: PropTypes.string,
notificationPolicy: PropTypes.object.isRequired,
onChangePolicy: PropTypes.func.isRequired,
};

onPushChange = (path, checked) => {
this.props.onChange(['push', ...path], checked);
};

handleFilterNotFollowing = checked => {
this.props.onChangePolicy('filter_not_following', checked);
};

handleFilterNotFollowers = checked => {
this.props.onChangePolicy('filter_not_followers', checked);
};

handleFilterNewAccounts = checked => {
this.props.onChangePolicy('filter_new_accounts', checked);
};

handleFilterPrivateMentions = checked => {
this.props.onChangePolicy('filter_private_mentions', checked);
};

render () {
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission, notificationPolicy } = this.props;
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission } = this.props;

const unreadMarkersShowStr = <FormattedMessage id='notifications.column_settings.unread_notifications.highlight' defaultMessage='Highlight unread notifications' />;
const groupingShowStr = <FormattedMessage id='notifications.column_settings.beta.grouping' defaultMessage='Group notifications' />;
Expand Down Expand Up @@ -81,31 +63,7 @@ class ColumnSettings extends PureComponent {
</section>
)}

<section>
<h3><FormattedMessage id='notifications.policy.title' defaultMessage='Filter out notifications from…' /></h3>

<div className='column-settings__row'>
<CheckboxWithLabel checked={notificationPolicy.filter_not_following} onChange={this.handleFilterNotFollowing}>
<strong><FormattedMessage id='notifications.policy.filter_not_following_title' defaultMessage="People you don't follow" /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_following_hint' defaultMessage='Until you manually approve them' /></span>
</CheckboxWithLabel>

<CheckboxWithLabel checked={notificationPolicy.filter_not_followers} onChange={this.handleFilterNotFollowers}>
<strong><FormattedMessage id='notifications.policy.filter_not_followers_title' defaultMessage='People not following you' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_followers_hint' defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}' values={{ days: 3 }} /></span>
</CheckboxWithLabel>

<CheckboxWithLabel checked={notificationPolicy.filter_new_accounts} onChange={this.handleFilterNewAccounts}>
<strong><FormattedMessage id='notifications.policy.filter_new_accounts_title' defaultMessage='New accounts' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_new_accounts.hint' defaultMessage='Created within the past {days, plural, one {one day} other {# days}}' values={{ days: 30 }} /></span>
</CheckboxWithLabel>

<CheckboxWithLabel checked={notificationPolicy.filter_private_mentions} onChange={this.handleFilterPrivateMentions}>
<strong><FormattedMessage id='notifications.policy.filter_private_mentions_title' defaultMessage='Unsolicited private mentions' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_private_mentions_hint' defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender" /></span>
</CheckboxWithLabel>
</div>
</section>
<PolicyControls />

<section role='group' aria-labelledby='notifications-filter-bar'>
<h3 id='notifications-filter-bar'><FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' /></h3>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
import { useEffect } from 'react';
import { useCallback, useEffect } from 'react';

import { FormattedMessage } from 'react-intl';
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';

import { Link } from 'react-router-dom';
import { Link, useHistory } from 'react-router-dom';

import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react';
import { fetchNotificationPolicy } from 'flavours/glitch/actions/notification_policies';
import { Icon } from 'flavours/glitch/components/icon';
import { selectSettingsNotificationsMinimizeFilteredBanner } from 'flavours/glitch/selectors/settings';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
import { toCappedNumber } from 'flavours/glitch/utils/numbers';

const messages = defineMessages({
filteredNotifications: {
id: 'notification_requests.title',
defaultMessage: 'Filtered notifications',
},
});

export const FilteredNotificationsIconButton: React.FC<{
className?: string;
}> = ({ className }) => {
const intl = useIntl();
const history = useHistory();
const policy = useAppSelector((state) => state.notificationPolicy);
const minimizeSetting = useAppSelector(
selectSettingsNotificationsMinimizeFilteredBanner,
);

const handleClick = useCallback(() => {
history.push('/notifications/requests');
}, [history]);

if (policy === null || policy.summary.pending_notifications_count === 0) {
return null;
}

if (!minimizeSetting) {
return null;
}

return (
<button
aria-label={intl.formatMessage(messages.filteredNotifications)}
title={intl.formatMessage(messages.filteredNotifications)}
onClick={handleClick}
className={className}
>
<Icon id='filtered-notifications' icon={InventoryIcon} />
</button>
);
};

export const FilteredNotificationsBanner: React.FC = () => {
const dispatch = useAppDispatch();
const policy = useAppSelector((state) => state.notificationPolicy);
const minimizeSetting = useAppSelector(
selectSettingsNotificationsMinimizeFilteredBanner,
);

useEffect(() => {
void dispatch(fetchNotificationPolicy());
Expand All @@ -30,6 +74,10 @@ export const FilteredNotificationsBanner: React.FC = () => {
return null;
}

if (minimizeSetting) {
return null;
}

return (
<Link
className='filtered-notifications-banner'
Expand All @@ -54,10 +102,6 @@ export const FilteredNotificationsBanner: React.FC = () => {
/>
</span>
</div>

<div className='filtered-notifications-banner__badge'>
{toCappedNumber(policy.summary.pending_notifications_count)}
</div>
</Link>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { useCallback } from 'react';

import { FormattedMessage } from 'react-intl';

import { updateNotificationsPolicy } from 'flavours/glitch/actions/notification_policies';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';

import { CheckboxWithLabel } from './checkbox_with_label';

export const PolicyControls: React.FC = () => {
const dispatch = useAppDispatch();

const notificationPolicy = useAppSelector(
(state) => state.notificationPolicy,
);

const handleFilterNotFollowing = useCallback(
(checked: boolean) => {
void dispatch(
updateNotificationsPolicy({ filter_not_following: checked }),
);
},
[dispatch],
);

const handleFilterNotFollowers = useCallback(
(checked: boolean) => {
void dispatch(
updateNotificationsPolicy({ filter_not_followers: checked }),
);
},
[dispatch],
);

const handleFilterNewAccounts = useCallback(
(checked: boolean) => {
void dispatch(
updateNotificationsPolicy({ filter_new_accounts: checked }),
);
},
[dispatch],
);

const handleFilterPrivateMentions = useCallback(
(checked: boolean) => {
void dispatch(
updateNotificationsPolicy({ filter_private_mentions: checked }),
);
},
[dispatch],
);

if (!notificationPolicy) return null;

return (
<section>
<h3>
<FormattedMessage
id='notifications.policy.title'
defaultMessage='Filter out notifications from…'
/>
</h3>

<div className='column-settings__row'>
<CheckboxWithLabel
checked={notificationPolicy.filter_not_following}
onChange={handleFilterNotFollowing}
>
<strong>
<FormattedMessage
id='notifications.policy.filter_not_following_title'
defaultMessage="People you don't follow"
/>
</strong>
<span className='hint'>
<FormattedMessage
id='notifications.policy.filter_not_following_hint'
defaultMessage='Until you manually approve them'
/>
</span>
</CheckboxWithLabel>

<CheckboxWithLabel
checked={notificationPolicy.filter_not_followers}
onChange={handleFilterNotFollowers}
>
<strong>
<FormattedMessage
id='notifications.policy.filter_not_followers_title'
defaultMessage='People not following you'
/>
</strong>
<span className='hint'>
<FormattedMessage
id='notifications.policy.filter_not_followers_hint'
defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}'
values={{ days: 3 }}
/>
</span>
</CheckboxWithLabel>

<CheckboxWithLabel
checked={notificationPolicy.filter_new_accounts}
onChange={handleFilterNewAccounts}
>
<strong>
<FormattedMessage
id='notifications.policy.filter_new_accounts_title'
defaultMessage='New accounts'
/>
</strong>
<span className='hint'>
<FormattedMessage
id='notifications.policy.filter_new_accounts.hint'
defaultMessage='Created within the past {days, plural, one {one day} other {# days}}'
values={{ days: 30 }}
/>
</span>
</CheckboxWithLabel>

<CheckboxWithLabel
checked={notificationPolicy.filter_private_mentions}
onChange={handleFilterPrivateMentions}
>
<strong>
<FormattedMessage
id='notifications.policy.filter_private_mentions_title'
defaultMessage='Unsolicited private mentions'
/>
</strong>
<span className='hint'>
<FormattedMessage
id='notifications.policy.filter_private_mentions_hint'
defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender"
/>
</span>
</CheckboxWithLabel>
</div>
</section>
);
};
Loading

0 comments on commit 1ca81a1

Please sign in to comment.