diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js index fb82ee067b44..48169e21c0d3 100644 --- a/src/components/structures/RoomSubList.js +++ b/src/components/structures/RoomSubList.js @@ -17,6 +17,8 @@ limitations under the License. 'use strict'; +import SettingsStore from "../../settings/SettingsStore"; + var React = require('react'); var ReactDOM = require('react-dom'); var classNames = require('classnames'); @@ -98,8 +100,10 @@ var RoomSubList = React.createClass({ componentWillReceiveProps: function(newProps) { // order the room list appropriately before we re-render //if (debug) console.log("received new props, list = " + newProps.list); + const filteredRooms = this.applySearchFilter(newProps.list, newProps.searchFilter); + const sortedRooms = this.applyPinnedTileRules(filteredRooms); this.setState({ - sortedList: this.applySearchFilter(newProps.list, newProps.searchFilter), + sortedList: sortedRooms, }); }, @@ -110,6 +114,21 @@ var RoomSubList = React.createClass({ }); }, + applyPinnedTileRules: function(list) { + const pinUnread = SettingsStore.getValue("pinUnreadRooms"); + const pinMentioned = SettingsStore.getValue("pinMentionedRooms"); + if (!pinUnread && !pinMentioned) { + return list; // Nothing to sort + } + + const mentioned = !pinMentioned ? [] : list.filter(room => room.getUnreadNotificationCount("highlight") > 0); + const unread = !pinUnread ? [] : list.filter(room => Unread.doesRoomHaveUnreadMessages(room)); + + return mentioned + .concat(unread.filter(room => !mentioned.find(other => other === room))) + .concat(list.filter(room => !unread.find(other => other === room))); + }, + // The header is collapsable if it is hidden or not stuck // The dataset elements are added in the RoomList _initAndPositionStickyHeaders method isCollapsableOnClick: function() { diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index c8ce79905d99..3695e0cf9fef 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -81,6 +81,8 @@ const SIMPLE_SETTINGS = [ { id: "VideoView.flipVideoHorizontally" }, { id: "TagPanel.disableTagPanel" }, { id: "enableWidgetScreenshots" }, + { id: "pinMentionedRooms" }, + { id: "pinUnreadRooms" }, ]; // These settings must be defined in SettingsStore diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bf9e395bee18..1b378c34d377 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -218,6 +218,8 @@ "Enable URL previews for this room (only affects you)": "Enable URL previews for this room (only affects you)", "Enable URL previews by default for participants in this room": "Enable URL previews by default for participants in this room", "Room Colour": "Room Colour", + "Pin unread rooms to the top of the room list": "Pin unread rooms to the top of the room list", + "Pin rooms I'm mentioned in to the top of the room list": "Pin rooms I'm mentioned in to the top of the room list", "Enable widget screenshots on supported widgets": "Enable widget screenshots on supported widgets", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index b1bc4161fdba..1665a59dfd7c 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -269,6 +269,16 @@ export const SETTINGS = { default: true, controller: new AudioNotificationsEnabledController(), }, + "pinMentionedRooms": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td("Pin rooms I'm mentioned in to the top of the room list"), + default: false, + }, + "pinUnreadRooms": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td("Pin unread rooms to the top of the room list"), + default: false, + }, "enableWidgetScreenshots": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Enable widget screenshots on supported widgets'),