Skip to content

Commit

Permalink
Merge remote-tracking branch 'alangecker/mark-unread' into sc
Browse files Browse the repository at this point in the history
Conflicts:
	src/components/structures/TimelinePanel.tsx
	src/components/views/rooms/RoomTile.tsx
	src/stores/notifications/RoomNotificationState.ts
  • Loading branch information
SpiritCroc committed Nov 16, 2021
2 parents 23edea8 + 8d3b16e commit 0692440
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 10 deletions.
8 changes: 4 additions & 4 deletions res/css/views/rooms/_NotificationBadge.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ limitations under the License.
align-items: center;
justify-content: center;

&.mx_NotificationBadge_highlighted {
&.mx_NotificationBadge_highlighted, &.mx_NotificationBadge_highlighted.mx_NotificationBadge_dot {
// TODO: Use a more specific variable
background-color: $warning-color;
}
Expand All @@ -44,9 +44,9 @@ limitations under the License.
&.mx_NotificationBadge_dot {
background-color: $primary-content; // increased visibility

width: 6px;
height: 6px;
border-radius: 6px;
width: 8px;
height: 8px;
border-radius: 8px;
}

&.mx_NotificationBadge_2char {
Expand Down
16 changes: 16 additions & 0 deletions src/Rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,19 @@ function guessDMRoomTargetId(room: Room, myUserId: string): string {
if (oldestUser === undefined) return myUserId;
return oldestUser.userId;
}

export const UNSTABLE_MSC2867_MARKED_UNREAD_TYPE = 'com.famedly.marked_unread';

export function isRoomMarkedAsUnread(room: Room): boolean {
return !!room.getAccountData(UNSTABLE_MSC2867_MARKED_UNREAD_TYPE)?.getContent()?.unread;
}

export async function setRoomMarkedAsUnread(room: Room, value = true): Promise<void> {
await MatrixClientPeg.get().setRoomAccountData(
room.roomId,
UNSTABLE_MSC2867_MARKED_UNREAD_TYPE,
{
unread: value,
},
);
}
17 changes: 17 additions & 0 deletions src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import { UserNameColorMode } from '../../settings/UserNameColorMode';

import { logger } from "matrix-js-sdk/src/logger";

import { isRoomMarkedAsUnread, setRoomMarkedAsUnread } from '../../Rooms';

const PAGINATE_SIZE = 20;
const INITIAL_SIZE = 20;
const READ_RECEIPT_INTERVAL_MS = 500;
Expand Down Expand Up @@ -870,6 +872,20 @@ class TimelinePanel extends React.Component<IProps, IState> {
this.sendReadReceipt();
};

private removeUnreadMarker = () => {
// This happens on user_activity_end which is delayed, and it's
// very possible have logged out within that timeframe, so check
// we still have a client.
const cli = MatrixClientPeg.get();
// if no client or client is guest don't send mark room as read
if (!cli || cli.isGuest()) return;

const markUnreadEnabled = SettingsStore.getValue("feature_mark_unread");
if (markUnreadEnabled && isRoomMarkedAsUnread(this.props.timelineSet.room)) {
setRoomMarkedAsUnread(this.props.timelineSet.room, false);
}
};

// advance the read marker past any events we sent ourselves.
private advanceReadMarkerPastMyEvents(): void {
if (!this.props.manageReadMarkers) return;
Expand Down Expand Up @@ -1121,6 +1137,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
if (this.props.sendReadReceiptOnLoad) {
this.sendReadReceipt();
}
this.removeUnreadMarker();
});
};

Expand Down
17 changes: 17 additions & 0 deletions src/components/views/rooms/RoomTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";

import { logger } from "matrix-js-sdk/src/logger";

import { setRoomMarkedAsUnread } from "../../../Rooms";
import SettingsStore from "../../../settings/SettingsStore";

interface IProps {
room: Room;
showMessagePreview: boolean;
Expand Down Expand Up @@ -283,6 +286,13 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
this.setState({ generalMenuPosition: null });
};

private onMarkUnreadClick = (ev: ButtonEvent) => {
ev.preventDefault();
ev.stopPropagation();
setRoomMarkedAsUnread(this.props.room);
this.setState({ generalMenuPosition: null }); // hide the menu
};

private onTagRoom = (ev: ButtonEvent, tagId: TagID) => {
ev.preventDefault();
ev.stopPropagation();
Expand Down Expand Up @@ -487,13 +497,20 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {

const userId = MatrixClientPeg.get().getUserId();
const canInvite = this.props.room.canInvite(userId);
const markUnreadEnabled = SettingsStore.getValue("feature_mark_unread");

contextMenu = <IconizedContextMenu
{...contextMenuBelow(this.state.generalMenuPosition)}
onFinished={this.onCloseGeneralMenu}
className="mx_RoomTile_contextMenu"
compact
>
<IconizedContextMenuOptionList>
{markUnreadEnabled ? (<IconizedContextMenuOption
onClick={this.onMarkUnreadClick}
label={_t("Mark as unread")}
iconClassName="mx_RoomTile_iconStar"
/>) : null }
<IconizedContextMenuCheckbox
onClick={(e) => this.onTagRoom(e, DefaultTagID.Favourite)}
active={isFavorite}
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@
"Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators": "Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators",
"Show options to enable 'Do not disturb' mode": "Show options to enable 'Do not disturb' mode",
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
"Mark rooms as unread": "Mark rooms as unread",
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
"Message Pinning": "Message Pinning",
"Threaded messaging": "Threaded messaging",
Expand Down Expand Up @@ -1780,6 +1781,7 @@
"Favourited": "Favourited",
"Favourite": "Favourite",
"Low Priority": "Low Priority",
"Mark as unread": "Mark as unread",
"Invite People": "Invite People",
"Copy Room Link": "Copy Room Link",
"Settings": "Settings",
Expand Down
6 changes: 6 additions & 0 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_mark_unread": {
isFeature: true,
displayName: _td("Mark rooms as unread"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_communities_v2_prototypes": {
isFeature: true,
displayName: _td(
Expand Down
37 changes: 31 additions & 6 deletions src/stores/notifications/RoomNotificationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,26 @@ import * as Unread from '../../Unread';
import { NotificationState } from "./NotificationState";
import { getUnsentMessages } from "../../components/structures/RoomStatusBar";

import { isRoomMarkedAsUnread, UNSTABLE_MSC2867_MARKED_UNREAD_TYPE } from "../../Rooms";
import SettingsStore from "../../settings/SettingsStore";

export class RoomNotificationState extends NotificationState implements IDestroyable {
private featureMarkedUnreadWatcherRef = null;
constructor(public readonly room: Room) {
super();
this.room.on("Room.receipt", this.handleReadReceipt);
this.room.on("Room.timeline", this.handleRoomEventUpdate);
this.room.on("Room.redaction", this.handleRoomEventUpdate);
this.room.on("Room.myMembership", this.handleMembershipUpdate);
this.room.on("Room.localEchoUpdated", this.handleLocalEchoUpdated);
this.room.on("Room.accountData", this.handleRoomAccountDataUpdate);
MatrixClientPeg.get().on("Event.decrypted", this.handleRoomEventUpdate);
MatrixClientPeg.get().on("accountData", this.handleAccountDataUpdate);

this.featureMarkedUnreadWatcherRef = SettingsStore.watchSetting("feature_mark_unread", null, () => {
this.updateNotificationState();
});

this.updateNotificationState();
}

Expand All @@ -50,10 +60,12 @@ export class RoomNotificationState extends NotificationState implements IDestroy
this.room.removeListener("Room.redaction", this.handleRoomEventUpdate);
this.room.removeListener("Room.myMembership", this.handleMembershipUpdate);
this.room.removeListener("Room.localEchoUpdated", this.handleLocalEchoUpdated);
this.room.removeListener("Room.accountData", this.handleRoomAccountDataUpdate);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Event.decrypted", this.handleRoomEventUpdate);
MatrixClientPeg.get().removeListener("accountData", this.handleAccountDataUpdate);
}
SettingsStore.unwatchSetting(this.featureMarkedUnreadWatcherRef);
}

private handleLocalEchoUpdated = () => {
Expand Down Expand Up @@ -83,6 +95,12 @@ export class RoomNotificationState extends NotificationState implements IDestroy
}
};

private handleRoomAccountDataUpdate = (ev: MatrixEvent) => {
if (ev.getType() === UNSTABLE_MSC2867_MARKED_UNREAD_TYPE) {
this.updateNotificationState();
}
};

private updateNotificationState() {
const snapshot = this.snapshot();

Expand Down Expand Up @@ -122,13 +140,20 @@ export class RoomNotificationState extends NotificationState implements IDestroy
this._count = trueCount;
this._symbol = null; // symbol calculated by component
} else {
// We don't have any notified messages, but we might have unread messages. Let's
// find out.
const hasUnread = Unread.doesRoomHaveUnreadMessages(this.room);
if (hasUnread) {
this._color = NotificationColor.Bold;
const markUnreadEnabled = SettingsStore.getValue("feature_mark_unread");

if (markUnreadEnabled && isRoomMarkedAsUnread(this.room)) {
this._color = NotificationColor.Red;
} else {
this._color = NotificationColor.None;
// We don't have any notified messages, but we might have unread messages. Let's
// find out.
const hasUnread = Unread.doesRoomHaveUnreadMessages(this.room);

if (hasUnread) {
this._color = NotificationColor.Bold;
} else {
this._color = NotificationColor.None;
}
}

// no symbol or count for this state
Expand Down

0 comments on commit 0692440

Please sign in to comment.