diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss
index 1814919b61..2b181f366e 100644
--- a/res/css/views/rooms/_RoomTile.scss
+++ b/res/css/views/rooms/_RoomTile.scss
@@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
+Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -61,6 +62,14 @@ limitations under the License.
min-width: 0;
}
+.mx_RoomTile_online_dot {
+ border-radius: 50%;
+ background-color: $accent-color;
+ height: 5px;
+ width: 5px;
+ display: inline-block;
+}
+
.mx_RoomTile_subtext {
display: inline-block;
font-size: 11px;
diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js
index 817ada9706..797aa7b87a 100644
--- a/src/components/views/rooms/RoomTile.js
+++ b/src/components/views/rooms/RoomTile.js
@@ -32,6 +32,7 @@ import ActiveRoomObserver from '../../../ActiveRoomObserver';
import RoomViewStore from '../../../stores/RoomViewStore';
import SettingsStore from "../../../settings/SettingsStore";
import {_t} from "../../../languageHandler";
+import RoomTileOnlineDot from "./RoomTileOnlineDot";
module.exports = createReactClass({
displayName: 'RoomTile',
@@ -68,11 +69,6 @@ module.exports = createReactClass({
});
},
- _isDirectMessageRoom: function(roomId) {
- const dmRooms = DMRoomMap.shared().getUserIdForRoomId(roomId);
- return Boolean(dmRooms);
- },
-
_shouldShowStatusMessage() {
if (!SettingsStore.isFeatureEnabled("feature_custom_status")) {
return false;
@@ -371,8 +367,11 @@ module.exports = createReactClass({
let ariaLabel = name;
+ const dmUserId = DMRoomMap.shared().getUserIdForRoomId(this.props.room.roomId);
+
let dmIndicator;
- if (this._isDirectMessageRoom(this.props.room.roomId)) {
+ let dmOnline;
+ if (dmUserId) {
dmIndicator = ;
+
+ if (this.props.room.getMember(dmUserId).membership === "join") {
+ const RoomTileOnlineDot = sdk.getComponent('rooms.RoomTileOnlineDot');
+ dmOnline = ;
+ }
}
// The following labels are written in such a fashion to increase screen reader efficiency (speed).
@@ -428,6 +432,7 @@ module.exports = createReactClass({
{ label }
{ subtextLabel }
+ { dmOnline }
{ contextMenuButton }
{ badge }
diff --git a/src/components/views/rooms/RoomTileOnlineDot.js b/src/components/views/rooms/RoomTileOnlineDot.js
new file mode 100644
index 0000000000..a882aec613
--- /dev/null
+++ b/src/components/views/rooms/RoomTileOnlineDot.js
@@ -0,0 +1,48 @@
+/*
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React, {useContext, useEffect, useMemo, useState, useCallback} from "react";
+import PropTypes from "prop-types";
+
+import {useEventEmitter} from "../../../hooks/useEventEmitter";
+import MatrixClientContext from "../../../contexts/MatrixClientContext";
+
+const RoomTileOnlineDot = ({userId}) => {
+ const cli = useContext(MatrixClientContext);
+ const user = useMemo(() => cli.getUser(userId), [cli, userId]);
+
+ const [isOnline, setIsOnline] = useState(false);
+
+ // Recheck if the user or client changes
+ useEffect(() => {
+ setIsOnline(user && (user.currentlyActive || user.presence === "online"));
+ }, [cli, user]);
+ // Recheck also if we receive a User.currentlyActive event
+ const currentlyActiveHandler = useCallback((ev) => {
+ const content = ev.getContent();
+ setIsOnline(content.currently_active || content.presence === "online");
+ }, []);
+ useEventEmitter(user, "User.currentlyActive", currentlyActiveHandler);
+ useEventEmitter(user, "User.presence", currentlyActiveHandler);
+
+ return isOnline ? : null;
+};
+
+RoomTileOnlineDot.propTypes = {
+ userId: PropTypes.string.isRequired,
+};
+
+export default RoomTileOnlineDot;