Sync breadcrumb rooms through account data
Fixes https://github.com/vector-im/riot-web/issues/9315 Other clients would need to listen for and update im.vector.riot.breadcrumb_rooms in account data.
This commit is contained in:
parent
37afa9fc0e
commit
44198ea97d
3 changed files with 94 additions and 24 deletions
|
@ -24,6 +24,7 @@ import classNames from 'classnames';
|
|||
import sdk from "../../../index";
|
||||
import * as RoomNotifs from '../../../RoomNotifs';
|
||||
import * as FormattingUtils from "../../../utils/FormattingUtils";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
|
||||
const MAX_ROOMS = 20;
|
||||
|
||||
|
@ -38,22 +39,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);
|
||||
|
@ -64,6 +65,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);
|
||||
|
@ -84,8 +87,8 @@ 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);
|
||||
SettingsStore.setValue("breadcrumb_rooms", null, SettingLevel.ACCOUNT, roomIds);
|
||||
}
|
||||
|
||||
onAction(payload) {
|
||||
|
@ -125,17 +128,48 @@ 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 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)) {
|
||||
|
@ -155,6 +189,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 a new issue