Merge pull request #2875 from matrix-org/travis/breadcrumbs/mobile

Sync breadcrumb rooms through account data
This commit is contained in:
Travis Ralston 2019-04-05 08:21:57 -06:00 committed by GitHub
commit 4815aa6de9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 24 deletions

View file

@ -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);
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 {
const roomIds = JSON.parse(roomStr);
this.setState({
rooms: roomIds.map((r) => {
return {
room: MatrixClientPeg.get().getRoom(r),
animated: false,
};
}).filter((r) => r.room),
});
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});
}

View file

@ -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'),

View file

@ -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);