Merge branch 'refs/heads/develop' into florianduros/tooltip-update

This commit is contained in:
Florian Duros 2024-04-15 15:13:51 +02:00
commit 79cbfafce3
No known key found for this signature in database
GPG key ID: A5BBB4041B493F15
23 changed files with 628 additions and 77 deletions

View file

@ -79,7 +79,6 @@ export const CallGuestLinkButton: React.FC<{ room: Room }> = ({ room }) => {
// If the user cannot invite the Knocking is not given as an option.
canInvite,
}).finished.then(() => {
// we need to use the function here because the callback got called before the state was updated.
if (isRoomJoinable()) showLinkModal();
});
}

View file

@ -58,6 +58,7 @@ import { Caption } from "../typography/Caption";
import { SettingsSubsectionHeading } from "./shared/SettingsSubsectionHeading";
import SettingsSubsection from "./shared/SettingsSubsection";
import { doesRoomHaveUnreadMessages } from "../../../Unread";
import SettingsFlag from "../elements/SettingsFlag";
// TODO: this "view" component still has far too much application logic in it,
// which should be factored out to other files.
@ -200,6 +201,18 @@ const maximumVectorState = (
return vectorState;
};
const NotificationActivitySettings = (): JSX.Element => {
return (
<div>
<SettingsFlag name="Notifications.showbold" level={SettingLevel.DEVICE} />
<SettingsFlag name="Notifications.tac_only_notifications" level={SettingLevel.DEVICE} />
</div>
);
};
/**
* The old, deprecated notifications tab view, only displayed if the user has the labs flag disabled.
*/
export default class Notifications extends React.PureComponent<IProps, IState> {
private settingWatchers: string[];
@ -731,43 +744,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
private renderCategory(category: RuleClass): ReactNode {
if (category !== RuleClass.VectorOther && this.isInhibited) {
if (this.isInhibited) {
return null; // nothing to show for the section
}
let clearNotifsButton: JSX.Element | undefined;
if (
category === RuleClass.VectorOther &&
MatrixClientPeg.safeGet()
.getRooms()
.some((r) => doesRoomHaveUnreadMessages(r, true))
) {
clearNotifsButton = (
<AccessibleButton
onClick={this.onClearNotificationsClicked}
disabled={this.state.clearingNotifications}
kind="danger"
className="mx_UserNotifSettings_clearNotifsButton"
data-testid="clear-notifications"
>
{_t("notifications|mark_all_read")}
</AccessibleButton>
);
}
if (category === RuleClass.VectorOther && this.isInhibited) {
// only render the utility buttons (if needed)
if (clearNotifsButton) {
return (
<div className="mx_UserNotifSettings_floatingSection">
<div>{_t("notifications|class_other")}</div>
{clearNotifsButton}
</div>
);
}
return null;
}
let keywordComposer: JSX.Element | undefined;
if (category === RuleClass.VectorMentions) {
const tags = filterBoolean<string>(this.state.vectorKeywordRuleInfo?.rules.map((r) => r.pattern) || []);
@ -842,7 +822,6 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
<span className="mx_UserNotifSettings_gridColumnLabel">{VectorStateToLabel[VectorState.Loud]}</span>
{fieldsetRows}
</div>
{clearNotifsButton}
{keywordComposer}
</div>
);
@ -878,6 +857,25 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
return <p data-testid="error-message">{_t("settings|notifications|error_loading")}</p>;
}
let clearNotifsButton: JSX.Element | undefined;
if (
MatrixClientPeg.safeGet()
.getRooms()
.some((r) => doesRoomHaveUnreadMessages(r, true))
) {
clearNotifsButton = (
<AccessibleButton
onClick={this.onClearNotificationsClicked}
disabled={this.state.clearingNotifications}
kind="danger"
className="mx_UserNotifSettings_clearNotifsButton"
data-testid="clear-notifications"
>
{_t("notifications|mark_all_read")}
</AccessibleButton>
);
}
return (
<>
{this.renderTopSection()}
@ -885,6 +883,8 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
{this.renderCategory(RuleClass.VectorMentions)}
{this.renderCategory(RuleClass.VectorOther)}
{this.renderTargets()}
<NotificationActivitySettings />
{clearNotifsButton}
</>
);
}

View file

@ -41,6 +41,7 @@ import { SettingsBanner } from "../shared/SettingsBanner";
import { SettingsSection } from "../shared/SettingsSection";
import SettingsSubsection from "../shared/SettingsSubsection";
import { NotificationPusherSettings } from "./NotificationPusherSettings";
import SettingsFlag from "../../elements/SettingsFlag";
enum NotificationDefaultLevels {
AllMessages = "all_messages",
@ -71,6 +72,9 @@ function useHasUnreadNotifications(): boolean {
return cli.getRooms().some((room) => room.getUnreadNotificationCount() > 0);
}
/**
* The new notification settings tab view, only displayed if the user has Features.NotificationSettings2 enabled
*/
export default function NotificationSettings2(): JSX.Element {
const cli = useMatrixClientContext();
@ -352,6 +356,9 @@ export default function NotificationSettings2(): JSX.Element {
label={_t("notifications|keyword")}
placeholder={_t("notifications|keyword_new")}
/>
<SettingsFlag name="Notifications.showbold" level={SettingLevel.DEVICE} />
<SettingsFlag name="Notifications.tac_only_notifications" level={SettingLevel.DEVICE} />
</SettingsSubsection>
<NotificationPusherSettings />
<SettingsSubsection heading={_t("settings|notifications|quick_actions_section")}>

View file

@ -43,13 +43,14 @@ type Result = {
*/
export function useUnreadThreadRooms(forceComputation: boolean): Result {
const msc3946ProcessDynamicPredecessor = useSettingValue<boolean>("feature_dynamic_room_predecessors");
const settingTACOnlyNotifs = useSettingValue<boolean>("Notifications.tac_only_notifications");
const mxClient = useMatrixClientContext();
const [result, setResult] = useState<Result>({ greatestNotificationLevel: NotificationLevel.None, rooms: [] });
const doUpdate = useCallback(() => {
setResult(computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor));
}, [mxClient, msc3946ProcessDynamicPredecessor]);
setResult(computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs));
}, [mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs]);
// The exhautive deps lint rule can't compute dependencies here since it's not a plain inline func.
// We make this as simple as possible so its only dep is doUpdate itself.
@ -83,7 +84,11 @@ export function useUnreadThreadRooms(forceComputation: boolean): Result {
* @param mxClient - MatrixClient
* @param msc3946ProcessDynamicPredecessor
*/
function computeUnreadThreadRooms(mxClient: MatrixClient, msc3946ProcessDynamicPredecessor: boolean): Result {
function computeUnreadThreadRooms(
mxClient: MatrixClient,
msc3946ProcessDynamicPredecessor: boolean,
settingTACOnlyNotifs: boolean,
): Result {
// Only count visible rooms to not torment the user with notification counts in rooms they can't see.
// This will include highlights from the previous version of the room internally
const visibleRooms = mxClient.getVisibleRooms(msc3946ProcessDynamicPredecessor);
@ -98,7 +103,7 @@ function computeUnreadThreadRooms(mxClient: MatrixClient, msc3946ProcessDynamicP
const notificationLevel = getThreadNotificationLevel(room);
// If the room has an activity notification or less, we ignore it
if (notificationLevel <= NotificationLevel.Activity) {
if (settingTACOnlyNotifs && notificationLevel <= NotificationLevel.Activity) {
continue;
}