Merge pull request #2875 from matrix-org/travis/breadcrumbs/mobile
Sync breadcrumb rooms through account datapull/21833/head
						commit
						4815aa6de9
					
				|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| import React from "react"; | ||||
| import dis from "../../../dispatcher"; | ||||
| import MatrixClientPeg from "../../../MatrixClientPeg"; | ||||
| import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; | ||||
| import AccessibleButton from '../elements/AccessibleButton'; | ||||
| import RoomAvatar from '../avatars/RoomAvatar'; | ||||
| import classNames from 'classnames'; | ||||
|  | @ -39,22 +40,22 @@ export default class RoomBreadcrumbs extends React.Component { | |||
|     componentWillMount() { | ||||
|         this._dispatcherRef = dis.register(this.onAction); | ||||
| 
 | ||||
|         const roomStr = localStorage.getItem("mx_breadcrumb_rooms"); | ||||
|         if (roomStr) { | ||||
|             try { | ||||
|                 const roomIds = JSON.parse(roomStr); | ||||
|                 this.setState({ | ||||
|                     rooms: roomIds.map((r) => { | ||||
|                         return { | ||||
|                             room: MatrixClientPeg.get().getRoom(r), | ||||
|                             animated: false, | ||||
|                         }; | ||||
|                     }).filter((r) => r.room), | ||||
|                 }); | ||||
|             } catch (e) { | ||||
|                 console.error("Failed to parse breadcrumbs:", e); | ||||
|         let storedRooms = SettingsStore.getValue("breadcrumb_rooms"); | ||||
|         if (!storedRooms || !storedRooms.length) { | ||||
|             // Fallback to the rooms stored in localstorage for those who would have had this.
 | ||||
|             // TODO: Remove this after a bit - the feature was only on develop, so a few weeks should be plenty time.
 | ||||
|             const roomStr = localStorage.getItem("mx_breadcrumb_rooms"); | ||||
|             if (roomStr) { | ||||
|                 try { | ||||
|                     storedRooms = JSON.parse(roomStr); | ||||
|                 } catch (e) { | ||||
|                     console.error("Failed to parse breadcrumbs:", e); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         this._loadRoomIds(storedRooms || []); | ||||
| 
 | ||||
|         this._settingWatchRef = SettingsStore.watchSetting("breadcrumb_rooms", null, this.onBreadcrumbsChanged); | ||||
| 
 | ||||
|         MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership); | ||||
|         MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt); | ||||
|  | @ -65,6 +66,8 @@ export default class RoomBreadcrumbs extends React.Component { | |||
|     componentWillUnmount() { | ||||
|         dis.unregister(this._dispatcherRef); | ||||
| 
 | ||||
|         SettingsStore.unwatchSetting(this._settingWatchRef); | ||||
| 
 | ||||
|         const client = MatrixClientPeg.get(); | ||||
|         if (client) { | ||||
|             client.removeListener("Room.myMembership", this.onMyMembership); | ||||
|  | @ -85,8 +88,10 @@ export default class RoomBreadcrumbs extends React.Component { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         const roomStr = JSON.stringify(rooms.map((r) => r.room.roomId)); | ||||
|         localStorage.setItem("mx_breadcrumb_rooms", roomStr); | ||||
|         const roomIds = rooms.map((r) => r.room.roomId); | ||||
|         if (roomIds.length > 0) { | ||||
|             SettingsStore.setValue("breadcrumb_rooms", null, SettingLevel.ACCOUNT, roomIds); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     onAction(payload) { | ||||
|  | @ -126,17 +131,50 @@ export default class RoomBreadcrumbs extends React.Component { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     _calculateRoomBadges(room) { | ||||
|         if (!room) return; | ||||
|     onBreadcrumbsChanged = (settingName, roomId, level, valueAtLevel, value) => { | ||||
|         if (!value) return; | ||||
| 
 | ||||
|         const rooms = this.state.rooms.slice(); | ||||
|         const roomModel = rooms.find((r) => r.room.roomId === room.roomId); | ||||
|         if (!roomModel) return; // No applicable room, so don't do math on it
 | ||||
|         const currentState = this.state.rooms.map((r) => r.room.roomId); | ||||
|         if (currentState.length === value.length) { | ||||
|             let changed = false; | ||||
|             for (let i = 0; i < currentState.length; i++) { | ||||
|                 if (currentState[i] !== value[i]) { | ||||
|                     changed = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if (!changed) return; | ||||
|         } | ||||
| 
 | ||||
|         this._loadRoomIds(value); | ||||
|     }; | ||||
| 
 | ||||
|     _loadRoomIds(roomIds) { | ||||
|         if (!roomIds || roomIds.length <= 0) return; // Skip updates with no rooms
 | ||||
| 
 | ||||
|         // If we're here, the list changed.
 | ||||
|         const rooms = roomIds.map((r) => MatrixClientPeg.get().getRoom(r)).filter((r) => r).map((r) => { | ||||
|             const badges = this._calculateBadgesForRoom(r) || {}; | ||||
|             return { | ||||
|                 room: r, | ||||
|                 animated: false, | ||||
|                 ...badges, | ||||
|             }; | ||||
|         }); | ||||
|         this.setState({ | ||||
|             rooms: rooms, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _calculateBadgesForRoom(room) { | ||||
|         if (!room) return null; | ||||
| 
 | ||||
|         // Reset the notification variables for simplicity
 | ||||
|         roomModel.redBadge = false; | ||||
|         roomModel.formattedCount = "0"; | ||||
|         roomModel.showCount = false; | ||||
|         const roomModel = { | ||||
|             redBadge: false, | ||||
|             formattedCount: "0", | ||||
|             showCount: false, | ||||
|         }; | ||||
| 
 | ||||
|         const notifState = RoomNotifs.getRoomNotifsState(room.roomId); | ||||
|         if (RoomNotifs.MENTION_BADGE_STATES.includes(notifState)) { | ||||
|  | @ -156,6 +194,20 @@ export default class RoomBreadcrumbs extends React.Component { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return roomModel; | ||||
|     } | ||||
| 
 | ||||
|     _calculateRoomBadges(room) { | ||||
|         if (!room) return; | ||||
| 
 | ||||
|         const rooms = this.state.rooms.slice(); | ||||
|         const roomModel = rooms.find((r) => r.room.roomId === room.roomId); | ||||
|         if (!roomModel) return; // No applicable room, so don't do math on it
 | ||||
| 
 | ||||
|         const badges = this._calculateBadgesForRoom(room); | ||||
|         if (!badges) return; // No badges for some reason
 | ||||
| 
 | ||||
|         Object.assign(roomModel, badges); | ||||
|         this.setState({rooms}); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -258,6 +258,10 @@ export const SETTINGS = { | |||
|         supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, | ||||
|         default: "en", | ||||
|     }, | ||||
|     "breadcrumb_rooms": { | ||||
|         supportedLevels: ['account'], | ||||
|         default: [], | ||||
|     }, | ||||
|     "analyticsOptIn": { | ||||
|         supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, | ||||
|         displayName: _td('Send analytics data'), | ||||
|  |  | |||
|  | @ -19,6 +19,8 @@ import MatrixClientPeg from '../../MatrixClientPeg'; | |||
| import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandler"; | ||||
| import {SettingLevel} from "../SettingsStore"; | ||||
| 
 | ||||
| const BREADCRUMBS_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms"; | ||||
| 
 | ||||
| /** | ||||
|  * Gets and sets settings at the "account" level for the current user. | ||||
|  * This handler does not make use of the roomId parameter. | ||||
|  | @ -55,6 +57,9 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa | |||
|                 const val = event.getContent()[settingName]; | ||||
|                 this._watchers.notifyUpdate(settingName, null, SettingLevel.ACCOUNT, val); | ||||
|             } | ||||
|         } else if (event.getType() === BREADCRUMBS_EVENT_TYPE) { | ||||
|             const val = event.getContent()['rooms'] || []; | ||||
|             this._watchers.notifyUpdate("breadcrumb_rooms", null, SettingLevel.ACCOUNT, val); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -68,6 +73,12 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa | |||
|             return !content['disable']; | ||||
|         } | ||||
| 
 | ||||
|         // Special case for breadcrumbs
 | ||||
|         if (settingName === "breadcrumb_rooms") { | ||||
|             const content = this._getSettings(BREADCRUMBS_EVENT_TYPE) || {}; | ||||
|             return content['rooms'] || []; | ||||
|         } | ||||
| 
 | ||||
|         const settings = this._getSettings() || {}; | ||||
|         let preferredValue = settings[settingName]; | ||||
| 
 | ||||
|  | @ -89,6 +100,13 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa | |||
|             return MatrixClientPeg.get().setAccountData("org.matrix.preview_urls", content); | ||||
|         } | ||||
| 
 | ||||
|         // Special case for breadcrumbs
 | ||||
|         if (settingName === "breadcrumb_rooms") { | ||||
|             const content = this._getSettings(BREADCRUMBS_EVENT_TYPE) || {}; | ||||
|             content['rooms'] = newValue; | ||||
|             return MatrixClientPeg.get().setAccountData(BREADCRUMBS_EVENT_TYPE, content); | ||||
|         } | ||||
| 
 | ||||
|         const content = this._getSettings() || {}; | ||||
|         content[settingName] = newValue; | ||||
|         return MatrixClientPeg.get().setAccountData("im.vector.web.settings", content); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Travis Ralston
						Travis Ralston