From bcebef7e5631e98e6ad7df5b2f1e5c082dbd3bbb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 12:13:12 -0600 Subject: [PATCH 1/6] Add a globe icon to public rooms For https://github.com/vector-im/riot-web/issues/14039 --- res/css/views/rooms/_RoomTile2.scss | 25 +++++++++++++++++++++ res/img/globe.svg | 6 +++++ src/components/views/rooms/RoomSublist2.tsx | 1 + src/components/views/rooms/RoomTile2.tsx | 13 +++++++++++ 4 files changed, 45 insertions(+) create mode 100644 res/img/globe.svg diff --git a/res/css/views/rooms/_RoomTile2.scss b/res/css/views/rooms/_RoomTile2.scss index f74d0ff5a4..2e9fe4a31e 100644 --- a/res/css/views/rooms/_RoomTile2.scss +++ b/res/css/views/rooms/_RoomTile2.scss @@ -32,6 +32,31 @@ limitations under the License. .mx_RoomTile2_avatarContainer { margin-right: 8px; + position: relative; + + .mx_RoomTile2_publicRoom { + width: 12px; + height: 12px; + border-radius: 12px; + background-color: $roomlist2-bg-color; // to match the room list itself + position: absolute; + bottom: 0; + right: 0; + + &::before { + content: ''; + width: 8px; + height: 8px; + top: 2px; + left: 2px; + position: absolute; + mask-position: center; + mask-size: contain; + mask-repeat: no-repeat; + background: $primary-fg-color; + mask-image: url('$(res)/img/globe.svg'); + } + } } .mx_RoomTile2_nameContainer { diff --git a/res/img/globe.svg b/res/img/globe.svg new file mode 100644 index 0000000000..cc22bc6e66 --- /dev/null +++ b/res/img/globe.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 9f8b8579c3..f03cb3ecbd 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -145,6 +145,7 @@ export default class RoomSublist2 extends React.Component { key={`room-${room.roomId}`} showMessagePreview={this.props.layout.showPreviews} isMinimized={this.props.isMinimized} + tag={this.props.layout.tagId} /> ); } diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index 10845d3840..f0d99eed99 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -44,6 +44,7 @@ interface IProps { room: Room; showMessagePreview: boolean; isMinimized: boolean; + tag: TagID; // TODO: Allow falsifying counts (for invites and stuff) // TODO: Transparency? Was this ever used? @@ -85,6 +86,12 @@ export default class RoomTile2 extends React.Component { ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate); } + private get isPublicRoom(): boolean { + const joinRules = this.props.room.currentState.getStateEvents("m.room.join_rules", ""); + const joinRule = joinRules && joinRules.getContent().join_rule; + return joinRule === 'public'; + } + public componentWillUnmount() { if (this.props.room) { ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate); @@ -287,6 +294,11 @@ export default class RoomTile2 extends React.Component { ); if (this.props.isMinimized) nameContainer = null; + let globe = null; + if (this.isPublicRoom && this.props.tag !== DefaultTagID.DM) { + globe = ; // sizing and such set by CSS + } + const avatarSize = 32; return ( @@ -304,6 +316,7 @@ export default class RoomTile2 extends React.Component { >
+ {globe}
{nameContainer}
From e4a51a7c01fe3d6f2e0aab8168c8afa7044d57fc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 14:43:48 -0600 Subject: [PATCH 2/6] Add presence icons; Convert to generic icon component For https://github.com/vector-im/riot-web/issues/14039 --- res/css/_components.scss | 1 + res/css/views/rooms/_RoomTile2.scss | 20 +-- res/css/views/rooms/_RoomTileIcon.scss | 69 +++++++++ res/themes/light/css/_light.scss | 4 + src/components/views/rooms/RoomTile2.tsx | 28 ++-- src/components/views/rooms/RoomTileIcon.tsx | 148 ++++++++++++++++++++ src/utils/presence.ts | 26 ++++ 7 files changed, 258 insertions(+), 38 deletions(-) create mode 100644 res/css/views/rooms/_RoomTileIcon.scss create mode 100644 src/components/views/rooms/RoomTileIcon.tsx create mode 100644 src/utils/presence.ts diff --git a/res/css/_components.scss b/res/css/_components.scss index 31f319e76f..66eb98ea9d 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -189,6 +189,7 @@ @import "./views/rooms/_RoomSublist2.scss"; @import "./views/rooms/_RoomTile.scss"; @import "./views/rooms/_RoomTile2.scss"; +@import "./views/rooms/_RoomTileIcon.scss"; @import "./views/rooms/_RoomUpgradeWarningBar.scss"; @import "./views/rooms/_SearchBar.scss"; @import "./views/rooms/_SendMessageComposer.scss"; diff --git a/res/css/views/rooms/_RoomTile2.scss b/res/css/views/rooms/_RoomTile2.scss index 2e9fe4a31e..001499fea5 100644 --- a/res/css/views/rooms/_RoomTile2.scss +++ b/res/css/views/rooms/_RoomTile2.scss @@ -34,28 +34,10 @@ limitations under the License. margin-right: 8px; position: relative; - .mx_RoomTile2_publicRoom { - width: 12px; - height: 12px; - border-radius: 12px; - background-color: $roomlist2-bg-color; // to match the room list itself + .mx_RoomTileIcon { position: absolute; bottom: 0; right: 0; - - &::before { - content: ''; - width: 8px; - height: 8px; - top: 2px; - left: 2px; - position: absolute; - mask-position: center; - mask-size: contain; - mask-repeat: no-repeat; - background: $primary-fg-color; - mask-image: url('$(res)/img/globe.svg'); - } } } diff --git a/res/css/views/rooms/_RoomTileIcon.scss b/res/css/views/rooms/_RoomTileIcon.scss new file mode 100644 index 0000000000..adc8ea2994 --- /dev/null +++ b/res/css/views/rooms/_RoomTileIcon.scss @@ -0,0 +1,69 @@ +/* +Copyright 2020 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. +*/ + +.mx_RoomTileIcon { + width: 12px; + height: 12px; + border-radius: 12px; + background-color: $roomlist2-bg-color; // to match the room list itself +} + +.mx_RoomTileIcon_globe::before { + content: ''; + width: 8px; + height: 8px; + top: 2px; + left: 2px; + position: absolute; + mask-position: center; + mask-size: contain; + mask-repeat: no-repeat; + background: $primary-fg-color; + mask-image: url('$(res)/img/globe.svg'); +} + +.mx_RoomTileIcon_offline::before { + content: ''; + width: 8px; + height: 8px; + top: 2px; + left: 2px; + position: absolute; + border-radius: 8px; + background-color: $presence-offline; +} + +.mx_RoomTileIcon_online::before { + content: ''; + width: 8px; + height: 8px; + top: 2px; + left: 2px; + position: absolute; + border-radius: 8px; + background-color: $presence-online; +} + +.mx_RoomTileIcon_away::before { + content: ''; + width: 8px; + height: 8px; + top: 2px; + left: 2px; + position: absolute; + border-radius: 8px; + background-color: $presence-away; +} diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 18a25b2663..355cc1301c 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -186,6 +186,10 @@ $roomtile2-preview-color: #9e9e9e; $roomtile2-default-badge-bg-color: #61708b; $roomtile2-selected-bg-color: #FFF; +$presence-online: $accent-color; +$presence-away: orange; // TODO: Get color +$presence-offline: #E3E8F0; + // ******************** $roomtile-name-color: #61708b; diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index f0d99eed99..8343851f66 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -21,7 +21,7 @@ import React, { createRef } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import classNames from "classnames"; import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; -import AccessibleButton, {ButtonEvent} from "../../views/elements/AccessibleButton"; +import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton"; import RoomAvatar from "../../views/avatars/RoomAvatar"; import dis from '../../../dispatcher/dispatcher'; import { Key } from "../../../Keyboard"; @@ -31,6 +31,7 @@ import { _t } from "../../../languageHandler"; import { ContextMenu, ContextMenuButton } from "../../structures/ContextMenu"; import { DefaultTagID, TagID } from "../../../stores/room-list/models"; import { MessagePreviewStore } from "../../../stores/MessagePreviewStore"; +import RoomTileIcon from "./RoomTileIcon"; /******************************************************************* * CAUTION * @@ -86,12 +87,6 @@ export default class RoomTile2 extends React.Component { ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate); } - private get isPublicRoom(): boolean { - const joinRules = this.props.room.currentState.getStateEvents("m.room.join_rules", ""); - const joinRule = joinRules && joinRules.getContent().join_rule; - return joinRule === 'public'; - } - public componentWillUnmount() { if (this.props.room) { ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate); @@ -187,25 +182,25 @@ export default class RoomTile2 extends React.Component {
  • this.onTagRoom(e, DefaultTagID.Favourite)}> - + {_t("Favourite")}
  • this.onTagRoom(e, DefaultTagID.LowPriority)}> - + {_t("Low Priority")}
  • this.onTagRoom(e, DefaultTagID.DM)}> - + {_t("Direct Chat")}
  • - + {_t("Settings")}
  • @@ -215,7 +210,7 @@ export default class RoomTile2 extends React.Component {
    • - + {_t("Leave Room")}
    • @@ -253,7 +248,7 @@ export default class RoomTile2 extends React.Component { 'mx_RoomTile2_minimized': this.props.isMinimized, }); - const badge = ; + const badge = ; // TODO: the original RoomTile uses state for the room name. Do we need to? let name = this.props.room.name; @@ -294,11 +289,6 @@ export default class RoomTile2 extends React.Component { ); if (this.props.isMinimized) nameContainer = null; - let globe = null; - if (this.isPublicRoom && this.props.tag !== DefaultTagID.DM) { - globe = ; // sizing and such set by CSS - } - const avatarSize = 32; return ( @@ -316,7 +306,7 @@ export default class RoomTile2 extends React.Component { >
      - {globe} +
      {nameContainer}
      diff --git a/src/components/views/rooms/RoomTileIcon.tsx b/src/components/views/rooms/RoomTileIcon.tsx new file mode 100644 index 0000000000..fb967bb811 --- /dev/null +++ b/src/components/views/rooms/RoomTileIcon.tsx @@ -0,0 +1,148 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd +Copyright 2018 Michael Telatynski <7t3chguy@gmail.com> +Copyright 2019, 2020 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 from "react"; +import { Room } from "matrix-js-sdk/src/models/room"; +import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; +import AccessibleButton from "../../views/elements/AccessibleButton"; +import RoomAvatar from "../../views/avatars/RoomAvatar"; +import ActiveRoomObserver from "../../../ActiveRoomObserver"; +import { DefaultTagID, TagID } from "../../../stores/room-list/models"; +import { User } from "matrix-js-sdk/src/models/user"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; +import DMRoomMap from "../../../utils/DMRoomMap"; +import { MatrixClientPeg } from "../../../MatrixClientPeg"; +import SdkConfig from "../../../SdkConfig"; +import { isPresenceEnabled } from "../../../utils/presence"; + +enum Icon { + // Note: the names here are used in CSS class names + None = "NONE", // ... except this one + Globe = "GLOBE", + PresenceOnline = "ONLINE", + PresenceAway = "AWAY", + PresenceOffline = "OFFLINE", +} + +interface IProps { + room: Room; + tag: TagID; +} + +interface IState { + icon: Icon; +} + +export default class RoomTileIcon extends React.Component { + private isUnmounted = false; + private dmUser: User; + private isWatchingTimeline = false; + + constructor(props: IProps) { + super(props); + + this.state = { + icon: this.getIcon(), + }; + } + + private get isPublicRoom(): boolean { + const joinRules = this.props.room.currentState.getStateEvents("m.room.join_rules", ""); + const joinRule = joinRules && joinRules.getContent().join_rule; + return joinRule === 'public'; + } + + public componentWillUnmount() { + this.isUnmounted = true; + if (this.isWatchingTimeline) this.props.room.off('Room.timeline', this.onRoomTimeline); + this.unsubscribePresence(); + } + + private unsubscribePresence() { + if (this.dmUser) { + this.dmUser.off('User.currentlyActive', this.onPresenceUpdate); + this.dmUser.off('User.presence', this.onPresenceUpdate); + } + } + + private onRoomTimeline = (ev: MatrixEvent, room: Room) => { + if (this.isUnmounted) return; + + // apparently these can happen? + if (!room) return; + if (this.props.room.roomId !== room.roomId) return; + + if (ev.getType() === 'm.room.join_rules' || ev.getType() === 'm.room.member') { + this.setState({icon: this.getIcon()}); + } + }; + + private onPresenceUpdate = () => { + if (this.isUnmounted) return; + + let newIcon = this.getPresenceIcon(); + if (newIcon !== this.state.icon) this.setState({icon: newIcon}); + }; + + private getPresenceIcon(): Icon { + let newIcon = Icon.None; + + const isOnline = this.dmUser.currentlyActive || this.dmUser.presence === 'online'; + if (isOnline) { + newIcon = Icon.PresenceOnline; + } else if (this.dmUser.presence === 'offline') { + newIcon = Icon.PresenceOffline; + } else if (this.dmUser.presence === 'unavailable') { + newIcon = Icon.PresenceAway; + } + + return newIcon; + } + + private getIcon(): Icon { + let defaultIcon = Icon.None; + this.unsubscribePresence(); + if (this.props.tag === DefaultTagID.DM && this.props.room.getJoinedMemberCount() === 2) { + // Track presence, if available + if (isPresenceEnabled()) { + const otherUserId = DMRoomMap.shared().getUserIdForRoomId(this.props.room.roomId); + if (otherUserId) { + this.dmUser = MatrixClientPeg.get().getUser(otherUserId); + if (this.dmUser) { + this.dmUser.on('User.currentlyActive', this.onPresenceUpdate); + this.dmUser.on('User.presence', this.onPresenceUpdate); + defaultIcon = this.getPresenceIcon(); + } + } + } + } else { + // Track publicity + defaultIcon = this.isPublicRoom ? Icon.Globe : Icon.None; + this.props.room.on('Room.timeline', this.onRoomTimeline); + this.isWatchingTimeline = true; + } + return defaultIcon; + } + + public render(): React.ReactElement { + if (this.state.icon === Icon.None) return null; + + return ; + } +} diff --git a/src/utils/presence.ts b/src/utils/presence.ts new file mode 100644 index 0000000000..f2c208265e --- /dev/null +++ b/src/utils/presence.ts @@ -0,0 +1,26 @@ +/* +Copyright 2020 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 { MatrixClientPeg } from "../MatrixClientPeg"; +import SdkConfig from "../SdkConfig"; + +export function isPresenceEnabled() { + const hsUrl = MatrixClientPeg.get().baseUrl; + const urls = SdkConfig.get()['enable_presence_by_hs_url']; + if (!urls) return true; + if (urls[hsUrl] || urls[hsUrl] === undefined) return true; + return false; +} From b69a5a525d3b4339d63be3ee5fdbe50e7b612897 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 17:29:36 -0600 Subject: [PATCH 3/6] Fix spaces --- src/components/views/rooms/RoomTile2.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index 8343851f66..0d13f856e9 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -182,25 +182,25 @@ export default class RoomTile2 extends React.Component {
      • this.onTagRoom(e, DefaultTagID.Favourite)}> - + {_t("Favourite")}
      • this.onTagRoom(e, DefaultTagID.LowPriority)}> - + {_t("Low Priority")}
      • this.onTagRoom(e, DefaultTagID.DM)}> - + {_t("Direct Chat")}
      • - + {_t("Settings")}
      • @@ -210,7 +210,7 @@ export default class RoomTile2 extends React.Component {
        • - + {_t("Leave Room")}
        • @@ -248,7 +248,7 @@ export default class RoomTile2 extends React.Component { 'mx_RoomTile2_minimized': this.props.isMinimized, }); - const badge = ; + const badge = ; // TODO: the original RoomTile uses state for the room name. Do we need to? let name = this.props.room.name; From daa552e25021c8d4a67912f42fa741579012b494 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 17:35:56 -0600 Subject: [PATCH 4/6] Refactor listener usage --- src/components/views/rooms/RoomTileIcon.tsx | 78 +++++++++++---------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/components/views/rooms/RoomTileIcon.tsx b/src/components/views/rooms/RoomTileIcon.tsx index fb967bb811..b0cf10e313 100644 --- a/src/components/views/rooms/RoomTileIcon.tsx +++ b/src/components/views/rooms/RoomTileIcon.tsx @@ -1,8 +1,5 @@ /* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 New Vector Ltd -Copyright 2018 Michael Telatynski <7t3chguy@gmail.com> -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. +Copyright 2020 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. @@ -19,16 +16,11 @@ limitations under the License. import React from "react"; import { Room } from "matrix-js-sdk/src/models/room"; -import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; -import AccessibleButton from "../../views/elements/AccessibleButton"; -import RoomAvatar from "../../views/avatars/RoomAvatar"; -import ActiveRoomObserver from "../../../ActiveRoomObserver"; import { DefaultTagID, TagID } from "../../../stores/room-list/models"; import { User } from "matrix-js-sdk/src/models/user"; -import {MatrixEvent} from "matrix-js-sdk/src/models/event"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import DMRoomMap from "../../../utils/DMRoomMap"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; -import SdkConfig from "../../../SdkConfig"; import { isPresenceEnabled } from "../../../utils/presence"; enum Icon { @@ -50,15 +42,15 @@ interface IState { } export default class RoomTileIcon extends React.Component { + private _dmUser: User; private isUnmounted = false; - private dmUser: User; private isWatchingTimeline = false; constructor(props: IProps) { super(props); this.state = { - icon: this.getIcon(), + icon: this.calculateIcon(), }; } @@ -68,17 +60,27 @@ export default class RoomTileIcon extends React.Component { return joinRule === 'public'; } + private get dmUser(): User { + return this._dmUser; + } + + private set dmUser(val: User) { + const oldUser = this._dmUser; + this._dmUser = val; + if (oldUser && oldUser !== this._dmUser) { + oldUser.off('User.currentlyActive', this.onPresenceUpdate); + oldUser.off('User.presence', this.onPresenceUpdate); + } + if (this._dmUser && oldUser !== this._dmUser) { + this._dmUser.on('User.currentlyActive', this.onPresenceUpdate); + this._dmUser.on('User.presence', this.onPresenceUpdate); + } + } + public componentWillUnmount() { this.isUnmounted = true; if (this.isWatchingTimeline) this.props.room.off('Room.timeline', this.onRoomTimeline); - this.unsubscribePresence(); - } - - private unsubscribePresence() { - if (this.dmUser) { - this.dmUser.off('User.currentlyActive', this.onPresenceUpdate); - this.dmUser.off('User.presence', this.onPresenceUpdate); - } + this.dmUser = null; // clear listeners, if any } private onRoomTimeline = (ev: MatrixEvent, room: Room) => { @@ -89,7 +91,7 @@ export default class RoomTileIcon extends React.Component { if (this.props.room.roomId !== room.roomId) return; if (ev.getType() === 'm.room.join_rules' || ev.getType() === 'm.room.member') { - this.setState({icon: this.getIcon()}); + this.setState({icon: this.calculateIcon()}); } }; @@ -101,43 +103,43 @@ export default class RoomTileIcon extends React.Component { }; private getPresenceIcon(): Icon { - let newIcon = Icon.None; + if (!this.dmUser) return Icon.None; + + let icon = Icon.None; const isOnline = this.dmUser.currentlyActive || this.dmUser.presence === 'online'; if (isOnline) { - newIcon = Icon.PresenceOnline; + icon = Icon.PresenceOnline; } else if (this.dmUser.presence === 'offline') { - newIcon = Icon.PresenceOffline; + icon = Icon.PresenceOffline; } else if (this.dmUser.presence === 'unavailable') { - newIcon = Icon.PresenceAway; + icon = Icon.PresenceAway; } - return newIcon; + return icon; } - private getIcon(): Icon { - let defaultIcon = Icon.None; - this.unsubscribePresence(); + private calculateIcon(): Icon { + let icon = Icon.None; + if (this.props.tag === DefaultTagID.DM && this.props.room.getJoinedMemberCount() === 2) { // Track presence, if available if (isPresenceEnabled()) { const otherUserId = DMRoomMap.shared().getUserIdForRoomId(this.props.room.roomId); if (otherUserId) { this.dmUser = MatrixClientPeg.get().getUser(otherUserId); - if (this.dmUser) { - this.dmUser.on('User.currentlyActive', this.onPresenceUpdate); - this.dmUser.on('User.presence', this.onPresenceUpdate); - defaultIcon = this.getPresenceIcon(); - } + icon = this.getPresenceIcon(); } } } else { // Track publicity - defaultIcon = this.isPublicRoom ? Icon.Globe : Icon.None; - this.props.room.on('Room.timeline', this.onRoomTimeline); - this.isWatchingTimeline = true; + icon = this.isPublicRoom ? Icon.Globe : Icon.None; + if (!this.isWatchingTimeline) { + this.props.room.on('Room.timeline', this.onRoomTimeline); + this.isWatchingTimeline = true; + } } - return defaultIcon; + return icon; } public render(): React.ReactElement { From 7a71ef9b6bba38b62c388f0cd5abf389b5856b6b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 17:40:25 -0600 Subject: [PATCH 5/6] Fix another space --- src/components/views/rooms/RoomTile2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index 0d13f856e9..edd92836df 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -306,7 +306,7 @@ export default class RoomTile2 extends React.Component { >
          - +
          {nameContainer}
          From 9878c1dc345c14338a978f3c2ebe54b6c3fb6a21 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Jun 2020 17:42:26 -0600 Subject: [PATCH 6/6] and another --- src/components/views/rooms/RoomTile2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index edd92836df..671b981ac5 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -305,7 +305,7 @@ export default class RoomTile2 extends React.Component { role="treeitem" >
          - +
          {nameContainer}