mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-17 14:05:04 +08:00
Merge branches 'develop' and 't3chguy/alpha_room_list' of github.com:matrix-org/matrix-react-sdk into t3chguy/alpha_room_list
This commit is contained in:
commit
e6d8c4a576
34
CHANGELOG.md
34
CHANGELOG.md
@ -1,3 +1,37 @@
|
||||
Changes in [2.1.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.1.1) (2020-02-19)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.1.0...v2.1.1)
|
||||
|
||||
* show spinner while loading local aliases
|
||||
[\#4090](https://github.com/matrix-org/matrix-react-sdk/pull/4090)
|
||||
* Don't index key verification events.
|
||||
[\#4083](https://github.com/matrix-org/matrix-react-sdk/pull/4083)
|
||||
* Get rid of dependence on usercontent.riot.im
|
||||
[\#4046](https://github.com/matrix-org/matrix-react-sdk/pull/4046)
|
||||
* also detect aliases using new /aliases endpoint for room access settings
|
||||
[\#4089](https://github.com/matrix-org/matrix-react-sdk/pull/4089)
|
||||
* get local aliases from /aliases in room settings
|
||||
[\#4086](https://github.com/matrix-org/matrix-react-sdk/pull/4086)
|
||||
* Start verification sessions in an E2E DM where possible
|
||||
[\#4080](https://github.com/matrix-org/matrix-react-sdk/pull/4080)
|
||||
* Only show supported verification methods
|
||||
[\#4077](https://github.com/matrix-org/matrix-react-sdk/pull/4077)
|
||||
* Use local echo in VerificationRequest for accepting/declining a verification
|
||||
request
|
||||
[\#4072](https://github.com/matrix-org/matrix-react-sdk/pull/4072)
|
||||
* Report installed PWA, touch input status in rageshakes, analytics
|
||||
[\#4078](https://github.com/matrix-org/matrix-react-sdk/pull/4078)
|
||||
* refactor event grouping into separate helper classes
|
||||
[\#4059](https://github.com/matrix-org/matrix-react-sdk/pull/4059)
|
||||
* Find existing requests when starting a new verification request
|
||||
[\#4070](https://github.com/matrix-org/matrix-react-sdk/pull/4070)
|
||||
* Always speak the full text of the typing indicator when it updates.
|
||||
[\#4074](https://github.com/matrix-org/matrix-react-sdk/pull/4074)
|
||||
* Fix escaped markdown passing backslashes through
|
||||
[\#4008](https://github.com/matrix-org/matrix-react-sdk/pull/4008)
|
||||
* Move the sidebar to below the sidebar tab buttons for screen readers.
|
||||
[\#4071](https://github.com/matrix-org/matrix-react-sdk/pull/4071)
|
||||
|
||||
Changes in [2.1.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.1.0) (2020-02-17)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.1.0-rc.2...v2.1.0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "matrix-react-sdk",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"description": "SDK for matrix.org using React",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
|
@ -35,7 +35,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
|
||||
./node_modules/matrix-js-sdk/release.sh -z "$@"
|
||||
|
||||
release="${1#v}"
|
||||
prerelease=0
|
||||
|
@ -32,7 +32,7 @@ import MatrixClientBackedSettingsHandler from "./settings/handlers/MatrixClientB
|
||||
import * as StorageManager from './utils/StorageManager';
|
||||
import IdentityAuthClient from './IdentityAuthClient';
|
||||
import { crossSigningCallbacks } from './CrossSigningManager';
|
||||
import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
|
||||
import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
|
||||
|
||||
interface MatrixClientCreds {
|
||||
homeserverUrl: string,
|
||||
@ -221,7 +221,6 @@ class _MatrixClientPeg {
|
||||
verificationMethods: [
|
||||
verificationMethods.SAS,
|
||||
SHOW_QR_CODE_METHOD,
|
||||
SCAN_QR_CODE_METHOD, // XXX: We don't actually support scanning yet!
|
||||
verificationMethods.RECIPROCATE_QR_CODE,
|
||||
],
|
||||
unstableClientRelationAggregation: true,
|
||||
|
@ -153,10 +153,12 @@ const Notifier = {
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this.boundOnEvent = this.onEvent.bind(this);
|
||||
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
|
||||
this.boundOnRoomReceipt = this.onRoomReceipt.bind(this);
|
||||
this.boundOnEventDecrypted = this.onEventDecrypted.bind(this);
|
||||
// do not re-bind in the case of repeated call
|
||||
this.boundOnEvent = this.boundOnEvent || this.onEvent.bind(this);
|
||||
this.boundOnSyncStateChange = this.boundOnSyncStateChange || this.onSyncStateChange.bind(this);
|
||||
this.boundOnRoomReceipt = this.boundOnRoomReceipt || this.onRoomReceipt.bind(this);
|
||||
this.boundOnEventDecrypted = this.boundOnEventDecrypted || this.onEventDecrypted.bind(this);
|
||||
|
||||
MatrixClientPeg.get().on('event', this.boundOnEvent);
|
||||
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
|
||||
MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted);
|
||||
@ -166,7 +168,7 @@ const Notifier = {
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) {
|
||||
if (MatrixClientPeg.get()) {
|
||||
MatrixClientPeg.get().removeListener('Event', this.boundOnEvent);
|
||||
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
|
||||
MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted);
|
||||
|
@ -46,9 +46,18 @@ export default class ManageEventIndexDialog extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
async updateCurrentRoom(room) {
|
||||
updateCurrentRoom = async (room) => {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
const stats = await eventIndex.getStats();
|
||||
let stats;
|
||||
|
||||
try {
|
||||
stats = await eventIndex.getStats();
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we will
|
||||
// try later again and probably succeed.
|
||||
return;
|
||||
}
|
||||
|
||||
let currentRoom = null;
|
||||
|
||||
if (room) currentRoom = room.name;
|
||||
@ -63,13 +72,13 @@ export default class ManageEventIndexDialog extends React.Component {
|
||||
roomCount: roomCount,
|
||||
currentRoom: currentRoom,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount(): void {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
|
||||
if (eventIndex !== null) {
|
||||
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this));
|
||||
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,14 +92,21 @@ export default class ManageEventIndexDialog extends React.Component {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
|
||||
if (eventIndex !== null) {
|
||||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this));
|
||||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom);
|
||||
|
||||
try {
|
||||
const stats = await eventIndex.getStats();
|
||||
eventIndexSize = stats.size;
|
||||
eventCount = stats.eventCount;
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we
|
||||
// will try later again in the updateCurrentRoom call and
|
||||
// probably succeed.
|
||||
}
|
||||
|
||||
const stats = await eventIndex.getStats();
|
||||
const roomStats = eventIndex.crawlingRooms();
|
||||
eventIndexSize = stats.size;
|
||||
crawlingRoomsCount = roomStats.crawlingRooms.size;
|
||||
roomCount = roomStats.totalRooms.size;
|
||||
eventCount = stats.eventCount;
|
||||
|
||||
const room = eventIndex.currentRoom();
|
||||
if (room) currentRoom = room.name;
|
||||
|
@ -95,8 +95,8 @@ const FilePanel = createReactClass({
|
||||
// this could be made more general in the future or the filter logic
|
||||
// could be fixed.
|
||||
if (EventIndexPeg.get() !== null) {
|
||||
client.on('Room.timeline', this.onRoomTimeline.bind(this));
|
||||
client.on('Event.decrypted', this.onEventDecrypted.bind(this));
|
||||
client.on('Room.timeline', this.onRoomTimeline);
|
||||
client.on('Event.decrypted', this.onEventDecrypted);
|
||||
}
|
||||
},
|
||||
|
||||
@ -107,8 +107,8 @@ const FilePanel = createReactClass({
|
||||
if (!MatrixClientPeg.get().isRoomEncrypted(this.props.roomId)) return;
|
||||
|
||||
if (EventIndexPeg.get() !== null) {
|
||||
client.removeListener('Room.timeline', this.onRoomTimeline.bind(this));
|
||||
client.removeListener('Event.decrypted', this.onEventDecrypted.bind(this));
|
||||
client.removeListener('Room.timeline', this.onRoomTimeline);
|
||||
client.removeListener('Event.decrypted', this.onEventDecrypted);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -65,6 +65,7 @@ import { ThemeWatcher } from "../../theme";
|
||||
import { storeRoomAliasInCache } from '../../RoomAliasCache';
|
||||
import { defer } from "../../utils/promise";
|
||||
import ToastStore from "../../stores/ToastStore";
|
||||
import * as StorageManager from "../../utils/StorageManager";
|
||||
|
||||
/** constants for MatrixChat.state.view */
|
||||
export const VIEWS = {
|
||||
@ -1193,6 +1194,8 @@ export default createReactClass({
|
||||
} else {
|
||||
this._showScreenAfterLogin();
|
||||
}
|
||||
|
||||
StorageManager.tryPersistStorage();
|
||||
},
|
||||
|
||||
_showScreenAfterLogin: function() {
|
||||
|
@ -92,6 +92,7 @@ export default class RightPanel extends React.Component {
|
||||
// not mounted in time to get the dispatch.
|
||||
// Until then, let this code serve as a warning from history.
|
||||
if (
|
||||
rps.roomPanelPhaseParams.member &&
|
||||
userForPanel.userId === rps.roomPanelPhaseParams.member.userId &&
|
||||
rps.roomPanelPhaseParams.verificationRequest
|
||||
) {
|
||||
|
@ -414,11 +414,16 @@ export default createReactClass({
|
||||
}
|
||||
// XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID)
|
||||
const permalinkButton = (
|
||||
<MenuItem className="mx_MessageContextMenu_field">
|
||||
<a href={permalink} target="_blank" rel="noopener" onClick={this.onPermalinkClick} tabIndex={-1}>
|
||||
{ mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message'
|
||||
? _t('Share Permalink') : _t('Share Message') }
|
||||
</a>
|
||||
<MenuItem
|
||||
element="a"
|
||||
className="mx_MessageContextMenu_field"
|
||||
onClick={this.onPermalinkClick}
|
||||
href={permalink}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{ mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message'
|
||||
? _t('Share Permalink') : _t('Share Message') }
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@ -436,16 +441,15 @@ export default createReactClass({
|
||||
isUrlPermitted(mxEvent.event.content.external_url)
|
||||
) {
|
||||
externalURLButton = (
|
||||
<MenuItem className="mx_MessageContextMenu_field">
|
||||
<a
|
||||
href={mxEvent.event.content.external_url}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
onClick={this.closeMenu}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{ _t('Source URL') }
|
||||
</a>
|
||||
<MenuItem
|
||||
element="a"
|
||||
className="mx_MessageContextMenu_field"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
onClick={this.closeMenu}
|
||||
href={mxEvent.event.content.external_url}
|
||||
>
|
||||
{ _t('Source URL') }
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import {verificationMethods} from 'matrix-js-sdk/src/crypto';
|
||||
import {ensureDMExists} from "../../../createRoom";
|
||||
import dis from "../../../dispatcher";
|
||||
import SettingsStore from '../../../settings/SettingsStore';
|
||||
import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
|
||||
import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
|
||||
import VerificationQREmojiOptions from "../verification/VerificationQREmojiOptions";
|
||||
|
||||
const MODE_LEGACY = 'legacy';
|
||||
@ -135,7 +135,6 @@ export default class DeviceVerifyDialog extends React.Component {
|
||||
this._request = await client.requestVerification(this.props.userId, [
|
||||
verificationMethods.SAS,
|
||||
SHOW_QR_CODE_METHOD,
|
||||
SCAN_QR_CODE_METHOD,
|
||||
verificationMethods.RECIPROCATE_QR_CODE,
|
||||
]);
|
||||
|
||||
|
@ -26,10 +26,15 @@ export default class VerificationRequestDialog extends React.Component {
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.onFinished = this.onFinished.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
const BaseDialog = sdk.getComponent("views.dialogs.BaseDialog");
|
||||
const EncryptionPanel = sdk.getComponent("views.right_panel.EncryptionPanel");
|
||||
return <BaseDialog className="mx_InfoDialog" onFinished={this.props.onFinished}
|
||||
return <BaseDialog className="mx_InfoDialog" onFinished={this.onFinished}
|
||||
contentId="mx_Dialog_content"
|
||||
title={_t("Verification Request")}
|
||||
hasCancel={true}
|
||||
@ -42,4 +47,9 @@ export default class VerificationRequestDialog extends React.Component {
|
||||
/>
|
||||
</BaseDialog>;
|
||||
}
|
||||
|
||||
onFinished() {
|
||||
this.props.verificationRequest.cancel();
|
||||
this.props.onFinished();
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,8 @@ const Pill = createReactClass({
|
||||
case Pill.TYPE_ROOM_MENTION: {
|
||||
const localRoom = resourceId[0] === '#' ?
|
||||
MatrixClientPeg.get().getRooms().find((r) => {
|
||||
return r.getAliases().includes(resourceId);
|
||||
return r.getCanonicalAlias() === resourceId ||
|
||||
r.getAliases().includes(resourceId);
|
||||
}) : MatrixClientPeg.get().getRoom(resourceId);
|
||||
room = localRoom;
|
||||
if (!localRoom) {
|
||||
|
@ -91,6 +91,7 @@ export default class AliasSettings extends React.Component {
|
||||
remoteDomains: [], // [ domain.com, foobar.com ]
|
||||
canonicalAlias: null, // #canonical:domain.com
|
||||
updatingCanonicalAlias: false,
|
||||
localAliasesLoading: true,
|
||||
};
|
||||
|
||||
if (props.canonicalAliasEvent) {
|
||||
@ -102,28 +103,32 @@ export default class AliasSettings extends React.Component {
|
||||
|
||||
async componentWillMount() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (await cli.doesServerSupportUnstableFeature("org.matrix.msc2432")) {
|
||||
const response = await cli.unstableGetLocalAliases(this.props.roomId);
|
||||
const localAliases = response.aliases;
|
||||
const localDomain = cli.getDomain();
|
||||
const domainToAliases = Object.assign(
|
||||
{},
|
||||
// FIXME, any localhost alt_aliases will be ignored as they are overwritten by localAliases
|
||||
this.aliasesToDictionary(this._getAltAliases()),
|
||||
{[localDomain]: localAliases || []},
|
||||
);
|
||||
const remoteDomains = Object.keys(domainToAliases).filter((domain) => {
|
||||
return domain !== localDomain && domainToAliases[domain].length > 0;
|
||||
});
|
||||
this.setState({ domainToAliases, remoteDomains });
|
||||
} else {
|
||||
const state = {};
|
||||
const localDomain = cli.getDomain();
|
||||
state.domainToAliases = this.aliasEventsToDictionary(this.props.aliasEvents || []);
|
||||
state.remoteDomains = Object.keys(state.domainToAliases).filter((domain) => {
|
||||
return domain !== localDomain && state.domainToAliases[domain].length > 0;
|
||||
});
|
||||
this.setState(state);
|
||||
try {
|
||||
if (await cli.doesServerSupportUnstableFeature("org.matrix.msc2432")) {
|
||||
const response = await cli.unstableGetLocalAliases(this.props.roomId);
|
||||
const localAliases = response.aliases;
|
||||
const localDomain = cli.getDomain();
|
||||
const domainToAliases = Object.assign(
|
||||
{},
|
||||
// FIXME, any localhost alt_aliases will be ignored as they are overwritten by localAliases
|
||||
this.aliasesToDictionary(this._getAltAliases()),
|
||||
{[localDomain]: localAliases || []},
|
||||
);
|
||||
const remoteDomains = Object.keys(domainToAliases).filter((domain) => {
|
||||
return domain !== localDomain && domainToAliases[domain].length > 0;
|
||||
});
|
||||
this.setState({ domainToAliases, remoteDomains });
|
||||
} else {
|
||||
const state = {};
|
||||
const localDomain = cli.getDomain();
|
||||
state.domainToAliases = this.aliasEventsToDictionary(this.props.aliasEvents || []);
|
||||
state.remoteDomains = Object.keys(state.domainToAliases).filter((domain) => {
|
||||
return domain !== localDomain && state.domainToAliases[domain].length > 0;
|
||||
});
|
||||
this.setState(state);
|
||||
}
|
||||
} finally {
|
||||
this.setState({localAliasesLoading: false});
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,26 +307,34 @@ export default class AliasSettings extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let localAliasesList;
|
||||
if (this.state.localAliasesLoading) {
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
localAliasesList = <Spinner />;
|
||||
} else {
|
||||
localAliasesList = <EditableAliasesList
|
||||
id="roomAliases"
|
||||
className={"mx_RoomSettings_localAliases"}
|
||||
items={this.state.domainToAliases[localDomain] || []}
|
||||
newItem={this.state.newAlias}
|
||||
onNewItemChanged={this.onNewAliasChanged}
|
||||
canRemove={this.props.canSetAliases}
|
||||
canEdit={this.props.canSetAliases}
|
||||
onItemAdded={this.onLocalAliasAdded}
|
||||
onItemRemoved={this.onLocalAliasDeleted}
|
||||
itemsLabel={_t('Local addresses for this room:')}
|
||||
noItemsLabel={_t('This room has no local addresses')}
|
||||
placeholder={_t(
|
||||
'New address (e.g. #foo:%(localDomain)s)', {localDomain: localDomain},
|
||||
)}
|
||||
domain={localDomain}
|
||||
/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mx_AliasSettings'>
|
||||
{canonicalAliasSection}
|
||||
<EditableAliasesList
|
||||
id="roomAliases"
|
||||
className={"mx_RoomSettings_localAliases"}
|
||||
items={this.state.domainToAliases[localDomain] || []}
|
||||
newItem={this.state.newAlias}
|
||||
onNewItemChanged={this.onNewAliasChanged}
|
||||
canRemove={this.props.canSetAliases}
|
||||
canEdit={this.props.canSetAliases}
|
||||
onItemAdded={this.onLocalAliasAdded}
|
||||
onItemRemoved={this.onLocalAliasDeleted}
|
||||
itemsLabel={_t('Local addresses for this room:')}
|
||||
noItemsLabel={_t('This room has no local addresses')}
|
||||
placeholder={_t(
|
||||
'New address (e.g. #foo:%(localDomain)s)', {localDomain: localDomain},
|
||||
)}
|
||||
domain={localDomain}
|
||||
/>
|
||||
{localAliasesList}
|
||||
{remoteAliasesSection}
|
||||
</div>
|
||||
);
|
||||
|
@ -37,21 +37,29 @@ export default class EventIndexPanel extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
async updateCurrentRoom(room) {
|
||||
updateCurrentRoom = async (room) => {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
const stats = await eventIndex.getStats();
|
||||
let stats;
|
||||
|
||||
try {
|
||||
stats = await eventIndex.getStats();
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we will
|
||||
// try later again and probably succeed.
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
eventIndexSize: stats.size,
|
||||
roomCount: stats.roomCount,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount(): void {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
|
||||
if (eventIndex !== null) {
|
||||
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this));
|
||||
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,11 +76,17 @@ export default class EventIndexPanel extends React.Component {
|
||||
let roomCount = 0;
|
||||
|
||||
if (eventIndex !== null) {
|
||||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this));
|
||||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom);
|
||||
|
||||
const stats = await eventIndex.getStats();
|
||||
eventIndexSize = stats.size;
|
||||
roomCount = stats.roomCount;
|
||||
try {
|
||||
const stats = await eventIndex.getStats();
|
||||
eventIndexSize = stats.size;
|
||||
roomCount = stats.roomCount;
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we
|
||||
// will try later again in the updateCurrentRoom call and
|
||||
// probably succeed.
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -107,20 +107,20 @@ export default class RolesRoomSettingsTab extends React.Component {
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership.bind(this));
|
||||
MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership);
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
const client = MatrixClientPeg.get();
|
||||
if (client) {
|
||||
client.removeListener("RoomState.members", this._onRoomMembership.bind(this));
|
||||
client.removeListener("RoomState.members", this._onRoomMembership);
|
||||
}
|
||||
}
|
||||
|
||||
_onRoomMembership(event, state, member) {
|
||||
_onRoomMembership = (event, state, member) => {
|
||||
if (state.roomId !== this.props.roomId) return;
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
_populateDefaultPlEvents(eventsSection, stateLevel, eventsLevel) {
|
||||
for (const desiredEvent of Object.keys(plEventsToShow)) {
|
||||
|
@ -240,6 +240,33 @@ export default class EventIndex extends EventEmitter {
|
||||
this.crawlerCheckpoints.push(backwardsCheckpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an event should be added to the event index.
|
||||
*
|
||||
* Most notably we filter events for which decryption failed, are redacted
|
||||
* or aren't of a type that we know how to index.
|
||||
*
|
||||
* @param {MatrixEvent} ev The event that should checked.
|
||||
* @returns {bool} Returns true if the event can be indexed, false
|
||||
* otherwise.
|
||||
*/
|
||||
isValidEvent(ev) {
|
||||
const isUsefulType = ["m.room.message", "m.room.name", "m.room.topic"].includes(ev.getType());
|
||||
const validEventType = isUsefulType && !ev.isRedacted() && !ev.isDecryptionFailure();
|
||||
|
||||
let validMsgType = true;
|
||||
|
||||
if (ev.getType() === "m.room.message" && !ev.isRedacted()) {
|
||||
// Expand this if there are more invalid msgtypes.
|
||||
const msgtype = ev.getContent().msgtype;
|
||||
|
||||
if (!msgtype) validMsgType = false;
|
||||
else validMsgType = !msgtype.startsWith("m.key.verification");
|
||||
}
|
||||
|
||||
return validEventType && validMsgType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue up live events to be added to the event index.
|
||||
*
|
||||
@ -248,10 +275,7 @@ export default class EventIndex extends EventEmitter {
|
||||
async addLiveEventToIndex(ev) {
|
||||
const indexManager = PlatformPeg.get().getEventIndexingManager();
|
||||
|
||||
if (["m.room.message", "m.room.name", "m.room.topic"]
|
||||
.indexOf(ev.getType()) == -1) {
|
||||
return;
|
||||
}
|
||||
if (!this.isValidEvent(ev)) return;
|
||||
|
||||
const jsonEvent = ev.toJSON();
|
||||
const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent;
|
||||
@ -407,22 +431,11 @@ export default class EventIndex extends EventEmitter {
|
||||
// Let us wait for all the events to get decrypted.
|
||||
await Promise.all(decryptionPromises);
|
||||
|
||||
// We filter out events for which decryption failed, are redacted
|
||||
// or aren't of a type that we know how to index.
|
||||
const isValidEvent = (value) => {
|
||||
return ([
|
||||
"m.room.message",
|
||||
"m.room.name",
|
||||
"m.room.topic",
|
||||
].indexOf(value.getType()) >= 0
|
||||
&& !value.isRedacted() && !value.isDecryptionFailure()
|
||||
);
|
||||
};
|
||||
|
||||
// TODO if there are no events at this point we're missing a lot
|
||||
// decryption keys, do we want to retry this checkpoint at a later
|
||||
// stage?
|
||||
const filteredEvents = matrixEvents.filter(isValidEvent);
|
||||
const filteredEvents = matrixEvents.filter(this.isValidEvent);
|
||||
|
||||
// Let us convert the events back into a format that EventIndex can
|
||||
// consume.
|
||||
|
@ -54,14 +54,14 @@ export class IntegrationManagers {
|
||||
startWatching(): void {
|
||||
this.stopWatching();
|
||||
this._client = MatrixClientPeg.get();
|
||||
this._client.on("accountData", this._onAccountData.bind(this));
|
||||
this._client.on("accountData", this._onAccountData);
|
||||
this._compileManagers();
|
||||
setInterval(() => this._setupHomeserverManagers(), HS_MANAGERS_REFRESH_INTERVAL);
|
||||
}
|
||||
|
||||
stopWatching(): void {
|
||||
if (!this._client) return;
|
||||
this._client.removeListener("accountData", this._onAccountData.bind(this));
|
||||
this._client.removeListener("accountData", this._onAccountData);
|
||||
if (this._wellknownRefreshTimerId !== null) clearInterval(this._wellknownRefreshTimerId);
|
||||
}
|
||||
|
||||
@ -136,11 +136,11 @@ export class IntegrationManagers {
|
||||
this._primaryManager = null; // reset primary
|
||||
}
|
||||
|
||||
_onAccountData(ev: MatrixEvent): void {
|
||||
_onAccountData = (ev: MatrixEvent): void => {
|
||||
if (ev.getType() === 'm.widgets') {
|
||||
this._compileManagers();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hasManager(): boolean {
|
||||
return this._managers.length > 0;
|
||||
|
@ -61,7 +61,7 @@ export class Mjolnir {
|
||||
setup() {
|
||||
if (!MatrixClientPeg.get()) return;
|
||||
this._updateLists(SettingsStore.getValue("mjolnirRooms"));
|
||||
MatrixClientPeg.get().on("RoomState.events", this._onEvent.bind(this));
|
||||
MatrixClientPeg.get().on("RoomState.events", this._onEvent);
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -76,7 +76,7 @@ export class Mjolnir {
|
||||
}
|
||||
|
||||
if (!MatrixClientPeg.get()) return;
|
||||
MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent.bind(this));
|
||||
MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent);
|
||||
}
|
||||
|
||||
async getOrCreatePersonalList(): Promise<BanList> {
|
||||
@ -130,13 +130,13 @@ export class Mjolnir {
|
||||
this._lists = this._lists.filter(b => b.roomId !== roomId);
|
||||
}
|
||||
|
||||
_onEvent(event) {
|
||||
_onEvent = (event) => {
|
||||
if (!MatrixClientPeg.get()) return;
|
||||
if (!this._roomIds.includes(event.getRoomId())) return;
|
||||
if (!ALL_RULE_TYPES.includes(event.getType())) return;
|
||||
|
||||
this._updateLists(this._roomIds);
|
||||
}
|
||||
};
|
||||
|
||||
_onListsChanged(settingName, roomId, atLevel, newValue) {
|
||||
// We know that ban lists are only recorded at one level so we don't need to re-eval them
|
||||
|
@ -106,6 +106,25 @@ export default async function sendBugReport(bugReportEndpoint, opts) {
|
||||
body.append('enabled_labs', enabledLabs.join(', '));
|
||||
}
|
||||
|
||||
// add storage persistence/quota information
|
||||
if (navigator.storage && navigator.storage.persisted) {
|
||||
try {
|
||||
body.append("storageManager_persisted", await navigator.storage.persisted());
|
||||
} catch (e) {}
|
||||
}
|
||||
if (navigator.storage && navigator.storage.estimate) {
|
||||
try {
|
||||
const estimate = await navigator.storage.estimate();
|
||||
body.append("storageManager_quota", estimate.quota);
|
||||
body.append("storageManager_usage", estimate.usage);
|
||||
if (estimate.usageDetails) {
|
||||
Object.keys(estimate.usageDetails).forEach(k => {
|
||||
body.append(`storageManager_usage_${k}`, estimate.usageDetails[k]);
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (opts.sendLogs) {
|
||||
progressCallback(_t("Collecting logs"));
|
||||
const logs = await rageshake.getLogsForReport();
|
||||
|
@ -43,6 +43,16 @@ function track(action) {
|
||||
Analytics.trackEvent("StorageManager", action);
|
||||
}
|
||||
|
||||
export function tryPersistStorage() {
|
||||
if (navigator.storage && navigator.storage.persist) {
|
||||
navigator.storage.persist().then(persistent => {
|
||||
console.log("StorageManager: Persistent?", persistent);
|
||||
});
|
||||
} else {
|
||||
console.log("StorageManager: Persistence unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkConsistency() {
|
||||
log("Checking storage consistency");
|
||||
log(`Local storage supported? ${!!localStorage}`);
|
||||
|
@ -5760,10 +5760,9 @@ mathml-tag-names@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc"
|
||||
integrity sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw==
|
||||
|
||||
matrix-js-sdk@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-5.0.0.tgz#dcbab35f1afdb35ef0364eb232e78e0fb7dc2a5b"
|
||||
integrity sha512-A/aeE2Zn2OHq1n/9wIHCszrQZ7oXfThUHWi5Kz7illVCPUJ3JrZ31XVvx02k6vBasDcUtjAfZblHdTVN62cWLw==
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
|
||||
version "5.0.1"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/a998006842ae558f02819ca84fbaad43685cc10b"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.3"
|
||||
another-json "^0.2.0"
|
||||
|
Loading…
Reference in New Issue
Block a user