Merge branch 'develop' into expand-codeblock
This commit is contained in:
commit
8a4af2f348
23 changed files with 382 additions and 172 deletions
60
CHANGELOG.md
60
CHANGELOG.md
|
@ -1,3 +1,63 @@
|
||||||
|
Changes in [3.12.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.12.0) (2021-01-18)
|
||||||
|
=====================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.12.0-rc.1...v3.12.0)
|
||||||
|
|
||||||
|
* Upgrade to JS SDK 9.5.0
|
||||||
|
* Fix incoming call box on dark theme
|
||||||
|
[\#5543](https://github.com/matrix-org/matrix-react-sdk/pull/5543)
|
||||||
|
|
||||||
|
Changes in [3.12.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.12.0-rc.1) (2021-01-13)
|
||||||
|
===============================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.11.1...v3.12.0-rc.1)
|
||||||
|
|
||||||
|
* Upgrade to JS SDK 9.5.0-rc.1
|
||||||
|
* Fix soft crash on soft logout page
|
||||||
|
[\#5539](https://github.com/matrix-org/matrix-react-sdk/pull/5539)
|
||||||
|
* Translations update from Weblate
|
||||||
|
[\#5538](https://github.com/matrix-org/matrix-react-sdk/pull/5538)
|
||||||
|
* Run TypeScript tests
|
||||||
|
[\#5537](https://github.com/matrix-org/matrix-react-sdk/pull/5537)
|
||||||
|
* Add a basic widget explorer to devtools (per-room)
|
||||||
|
[\#5528](https://github.com/matrix-org/matrix-react-sdk/pull/5528)
|
||||||
|
* Add <input type="password"> to security key field
|
||||||
|
[\#5534](https://github.com/matrix-org/matrix-react-sdk/pull/5534)
|
||||||
|
* Fix avatar upload prompt/tooltip floating wrong and permissions
|
||||||
|
[\#5526](https://github.com/matrix-org/matrix-react-sdk/pull/5526)
|
||||||
|
* Add a dialpad UI for PSTN lookup
|
||||||
|
[\#5523](https://github.com/matrix-org/matrix-react-sdk/pull/5523)
|
||||||
|
* Basic call transfer initiation support
|
||||||
|
[\#5494](https://github.com/matrix-org/matrix-react-sdk/pull/5494)
|
||||||
|
* Fix #15988
|
||||||
|
[\#5524](https://github.com/matrix-org/matrix-react-sdk/pull/5524)
|
||||||
|
* Bump node-notifier from 8.0.0 to 8.0.1
|
||||||
|
[\#5520](https://github.com/matrix-org/matrix-react-sdk/pull/5520)
|
||||||
|
* Use TypeScript source for development, swap to build during release
|
||||||
|
[\#5503](https://github.com/matrix-org/matrix-react-sdk/pull/5503)
|
||||||
|
* Look for emoji in the body that will be displayed
|
||||||
|
[\#5517](https://github.com/matrix-org/matrix-react-sdk/pull/5517)
|
||||||
|
* Bump ini from 1.3.5 to 1.3.7
|
||||||
|
[\#5486](https://github.com/matrix-org/matrix-react-sdk/pull/5486)
|
||||||
|
* Recognise `*.element.io` links as Element permalinks
|
||||||
|
[\#5514](https://github.com/matrix-org/matrix-react-sdk/pull/5514)
|
||||||
|
* Fixes for call UI
|
||||||
|
[\#5509](https://github.com/matrix-org/matrix-react-sdk/pull/5509)
|
||||||
|
* Add a snowfall chat effect (with /snowfall command)
|
||||||
|
[\#5511](https://github.com/matrix-org/matrix-react-sdk/pull/5511)
|
||||||
|
* fireworks effect
|
||||||
|
[\#5507](https://github.com/matrix-org/matrix-react-sdk/pull/5507)
|
||||||
|
* Don't play call end sound for calls that never started
|
||||||
|
[\#5506](https://github.com/matrix-org/matrix-react-sdk/pull/5506)
|
||||||
|
* Add /tableflip slash command
|
||||||
|
[\#5485](https://github.com/matrix-org/matrix-react-sdk/pull/5485)
|
||||||
|
* Import from src in IncomingCallBox.tsx
|
||||||
|
[\#5504](https://github.com/matrix-org/matrix-react-sdk/pull/5504)
|
||||||
|
* Social Login support both https and mxc icons
|
||||||
|
[\#5499](https://github.com/matrix-org/matrix-react-sdk/pull/5499)
|
||||||
|
* Fix padding in confirmation email registration prompt
|
||||||
|
[\#5501](https://github.com/matrix-org/matrix-react-sdk/pull/5501)
|
||||||
|
* Fix room list help prompt alignment
|
||||||
|
[\#5500](https://github.com/matrix-org/matrix-react-sdk/pull/5500)
|
||||||
|
|
||||||
Changes in [3.11.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.11.1) (2020-12-21)
|
Changes in [3.11.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.11.1) (2020-12-21)
|
||||||
=====================================================================================================
|
=====================================================================================================
|
||||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.11.0...v3.11.1)
|
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.11.0...v3.11.1)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "matrix-react-sdk",
|
"name": "matrix-react-sdk",
|
||||||
"version": "3.11.1",
|
"version": "3.12.0",
|
||||||
"description": "SDK for matrix.org using React",
|
"description": "SDK for matrix.org using React",
|
||||||
"author": "matrix.org",
|
"author": "matrix.org",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
"linkifyjs": "^2.1.9",
|
"linkifyjs": "^2.1.9",
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||||
"matrix-widget-api": "^0.1.0-beta.10",
|
"matrix-widget-api": "0.1.0-beta.11",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"pako": "^1.0.11",
|
"pako": "^1.0.11",
|
||||||
"parse5": "^5.1.1",
|
"parse5": "^5.1.1",
|
||||||
|
|
|
@ -89,24 +89,18 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_showMore {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata {
|
.metadata {
|
||||||
color: $muted-fg-color;
|
color: $muted-fg-color;
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.metadata.visible {
|
|
||||||
overflow-y: visible;
|
overflow-y: visible;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
protected readonly _matrixClient: MatrixClient;
|
protected readonly _matrixClient: MatrixClient;
|
||||||
protected readonly _roomView: React.RefObject<any>;
|
protected readonly _roomView: React.RefObject<any>;
|
||||||
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
|
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
|
||||||
protected readonly _compactLayoutWatcherRef: string;
|
protected compactLayoutWatcherRef: string;
|
||||||
protected resizer: Resizer;
|
protected resizer: Resizer;
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
|
@ -157,18 +157,6 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
CallMediaHandler.loadDevices();
|
CallMediaHandler.loadDevices();
|
||||||
|
|
||||||
document.addEventListener('keydown', this._onNativeKeyDown, false);
|
|
||||||
|
|
||||||
this._updateServerNoticeEvents();
|
|
||||||
|
|
||||||
this._matrixClient.on("accountData", this.onAccountData);
|
|
||||||
this._matrixClient.on("sync", this.onSync);
|
|
||||||
this._matrixClient.on("RoomState.events", this.onRoomStateEvents);
|
|
||||||
|
|
||||||
this._compactLayoutWatcherRef = SettingsStore.watchSetting(
|
|
||||||
"useCompactLayout", null, this.onCompactLayoutChanged,
|
|
||||||
);
|
|
||||||
|
|
||||||
fixupColorFonts();
|
fixupColorFonts();
|
||||||
|
|
||||||
this._roomView = React.createRef();
|
this._roomView = React.createRef();
|
||||||
|
@ -176,6 +164,24 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
document.addEventListener('keydown', this._onNativeKeyDown, false);
|
||||||
|
|
||||||
|
this._updateServerNoticeEvents();
|
||||||
|
|
||||||
|
this._matrixClient.on("accountData", this.onAccountData);
|
||||||
|
this._matrixClient.on("sync", this.onSync);
|
||||||
|
// Call `onSync` with the current state as well
|
||||||
|
this.onSync(
|
||||||
|
this._matrixClient.getSyncState(),
|
||||||
|
null,
|
||||||
|
this._matrixClient.getSyncStateData(),
|
||||||
|
);
|
||||||
|
this._matrixClient.on("RoomState.events", this.onRoomStateEvents);
|
||||||
|
|
||||||
|
this.compactLayoutWatcherRef = SettingsStore.watchSetting(
|
||||||
|
"useCompactLayout", null, this.onCompactLayoutChanged,
|
||||||
|
);
|
||||||
|
|
||||||
this.resizer = this._createResizer();
|
this.resizer = this._createResizer();
|
||||||
this.resizer.attach();
|
this.resizer.attach();
|
||||||
this._loadResizerPreferences();
|
this._loadResizerPreferences();
|
||||||
|
@ -186,7 +192,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
this._matrixClient.removeListener("accountData", this.onAccountData);
|
this._matrixClient.removeListener("accountData", this.onAccountData);
|
||||||
this._matrixClient.removeListener("sync", this.onSync);
|
this._matrixClient.removeListener("sync", this.onSync);
|
||||||
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
|
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
|
||||||
SettingsStore.unwatchSetting(this._compactLayoutWatcherRef);
|
SettingsStore.unwatchSetting(this.compactLayoutWatcherRef);
|
||||||
this.resizer.detach();
|
this.resizer.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import {WidgetMessagingStore} from "../../../stores/widgets/WidgetMessagingStore
|
||||||
import RoomContext from "../../../contexts/RoomContext";
|
import RoomContext from "../../../contexts/RoomContext";
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import QuestionDialog from "../dialogs/QuestionDialog";
|
import QuestionDialog from "../dialogs/QuestionDialog";
|
||||||
import {WidgetType} from "../../../widgets/WidgetType";
|
import {WidgetType} from "../../../widgets/WidgetType";
|
||||||
|
@ -127,7 +126,8 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
||||||
console.info("Revoking permission for widget to load: " + app.eventId);
|
console.info("Revoking permission for widget to load: " + app.eventId);
|
||||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||||
current[app.eventId] = false;
|
current[app.eventId] = false;
|
||||||
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).catch(err => {
|
const level = SettingsStore.firstSupportedLevel("allowedWidgets");
|
||||||
|
SettingsStore.setValue("allowedWidgets", roomId, level, current).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
// We don't really need to do anything about this - the user will just hit the button again.
|
// We don't really need to do anything about this - the user will just hit the button again.
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,7 +33,6 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import {aboveLeftOf, ContextMenuButton} from "../../structures/ContextMenu";
|
import {aboveLeftOf, ContextMenuButton} from "../../structures/ContextMenu";
|
||||||
import PersistedElement, {getPersistKey} from "./PersistedElement";
|
import PersistedElement, {getPersistKey} from "./PersistedElement";
|
||||||
import {WidgetType} from "../../../widgets/WidgetType";
|
import {WidgetType} from "../../../widgets/WidgetType";
|
||||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
|
||||||
import {StopGapWidget} from "../../../stores/widgets/StopGapWidget";
|
import {StopGapWidget} from "../../../stores/widgets/StopGapWidget";
|
||||||
import {ElementWidgetActions} from "../../../stores/widgets/ElementWidgetActions";
|
import {ElementWidgetActions} from "../../../stores/widgets/ElementWidgetActions";
|
||||||
import {MatrixCapabilities} from "matrix-widget-api";
|
import {MatrixCapabilities} from "matrix-widget-api";
|
||||||
|
@ -240,7 +239,8 @@ export default class AppTile extends React.Component {
|
||||||
console.info("Granting permission for widget to load: " + this.props.app.eventId);
|
console.info("Granting permission for widget to load: " + this.props.app.eventId);
|
||||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||||
current[this.props.app.eventId] = true;
|
current[this.props.app.eventId] = true;
|
||||||
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).then(() => {
|
const level = SettingsStore.firstSupportedLevel("allowedWidgets");
|
||||||
|
SettingsStore.setValue("allowedWidgets", roomId, level, current).then(() => {
|
||||||
this.setState({hasPermissionToLoad: true});
|
this.setState({hasPermissionToLoad: true});
|
||||||
|
|
||||||
// Fetch a token for the integration manager, now that we're allowed to
|
// Fetch a token for the integration manager, now that we're allowed to
|
||||||
|
|
|
@ -412,7 +412,10 @@ export default class TextualBody extends React.Component {
|
||||||
ref: this._content,
|
ref: this._content,
|
||||||
});
|
});
|
||||||
if (this.props.replacingEventId) {
|
if (this.props.replacingEventId) {
|
||||||
body = [body, this._renderEditedMarker()];
|
body = <>
|
||||||
|
{body}
|
||||||
|
{this._renderEditedMarker()}
|
||||||
|
</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.highlightLink) {
|
if (this.props.highlightLink) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import ActiveRoomObserver from "../../../ActiveRoomObserver";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { ChevronFace, ContextMenuTooltipButton } from "../../structures/ContextMenu";
|
import { ChevronFace, ContextMenuTooltipButton } from "../../structures/ContextMenu";
|
||||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||||
import { MessagePreviewStore, ROOM_PREVIEW_CHANGED } from "../../../stores/room-list/MessagePreviewStore";
|
import { MessagePreviewStore } from "../../../stores/room-list/MessagePreviewStore";
|
||||||
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
|
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
|
||||||
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE } from "../../../RoomNotifs";
|
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE } from "../../../RoomNotifs";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
|
@ -51,7 +51,6 @@ import IconizedContextMenu, {
|
||||||
IconizedContextMenuRadio,
|
IconizedContextMenuRadio,
|
||||||
} from "../context_menus/IconizedContextMenu";
|
} from "../context_menus/IconizedContextMenu";
|
||||||
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
||||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -99,12 +98,18 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate);
|
ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate);
|
||||||
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
||||||
MessagePreviewStore.instance.on(ROOM_PREVIEW_CHANGED, this.onRoomPreviewChanged);
|
MessagePreviewStore.instance.on(
|
||||||
|
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
|
||||||
|
this.onRoomPreviewChanged,
|
||||||
|
);
|
||||||
this.notificationState = RoomNotificationStateStore.instance.getRoomState(this.props.room);
|
this.notificationState = RoomNotificationStateStore.instance.getRoomState(this.props.room);
|
||||||
this.notificationState.on(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
|
this.notificationState.on(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
|
||||||
this.roomProps = EchoChamber.forRoom(this.props.room);
|
this.roomProps = EchoChamber.forRoom(this.props.room);
|
||||||
this.roomProps.on(PROPERTY_UPDATED, this.onRoomPropertyUpdate);
|
this.roomProps.on(PROPERTY_UPDATED, this.onRoomPropertyUpdate);
|
||||||
CommunityPrototypeStore.instance.on(UPDATE_EVENT, this.onCommunityUpdate);
|
CommunityPrototypeStore.instance.on(
|
||||||
|
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
||||||
|
this.onCommunityUpdate,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onNotificationUpdate = () => {
|
private onNotificationUpdate = () => {
|
||||||
|
@ -128,6 +133,24 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
if (prevProps.showMessagePreview !== this.props.showMessagePreview && this.showMessagePreview) {
|
if (prevProps.showMessagePreview !== this.props.showMessagePreview && this.showMessagePreview) {
|
||||||
this.setState({messagePreview: this.generatePreview()});
|
this.setState({messagePreview: this.generatePreview()});
|
||||||
}
|
}
|
||||||
|
if (prevProps.room?.roomId !== this.props.room?.roomId) {
|
||||||
|
MessagePreviewStore.instance.off(
|
||||||
|
MessagePreviewStore.getPreviewChangedEventName(prevProps.room),
|
||||||
|
this.onRoomPreviewChanged,
|
||||||
|
);
|
||||||
|
MessagePreviewStore.instance.on(
|
||||||
|
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
|
||||||
|
this.onRoomPreviewChanged,
|
||||||
|
);
|
||||||
|
CommunityPrototypeStore.instance.off(
|
||||||
|
CommunityPrototypeStore.getUpdateEventName(prevProps.room?.roomId),
|
||||||
|
this.onCommunityUpdate,
|
||||||
|
);
|
||||||
|
CommunityPrototypeStore.instance.on(
|
||||||
|
CommunityPrototypeStore.getUpdateEventName(this.props.room?.roomId),
|
||||||
|
this.onCommunityUpdate,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
|
@ -140,11 +163,17 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
if (this.props.room) {
|
if (this.props.room) {
|
||||||
ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate);
|
ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate);
|
||||||
|
MessagePreviewStore.instance.off(
|
||||||
|
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
|
||||||
|
this.onRoomPreviewChanged,
|
||||||
|
);
|
||||||
|
CommunityPrototypeStore.instance.off(
|
||||||
|
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
||||||
|
this.onCommunityUpdate,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
defaultDispatcher.unregister(this.dispatcherRef);
|
defaultDispatcher.unregister(this.dispatcherRef);
|
||||||
MessagePreviewStore.instance.off(ROOM_PREVIEW_CHANGED, this.onRoomPreviewChanged);
|
|
||||||
this.notificationState.off(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
|
this.notificationState.off(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
|
||||||
CommunityPrototypeStore.instance.off(UPDATE_EVENT, this.onCommunityUpdate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
|
||||||
import {_t} from "../../../languageHandler";
|
|
||||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
|
||||||
import Pill from "../elements/Pill";
|
|
||||||
import {makeUserPermalink} from "../../../utils/permalinks/Permalinks";
|
|
||||||
import BaseAvatar from "../avatars/BaseAvatar";
|
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
|
|
||||||
@replaceableComponent("views.settings.BridgeTile")
|
|
||||||
export default class BridgeTile extends React.PureComponent {
|
|
||||||
static propTypes = {
|
|
||||||
ev: PropTypes.object.isRequired,
|
|
||||||
room: PropTypes.object.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
state = {
|
|
||||||
visible: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleVisible() {
|
|
||||||
this.setState({
|
|
||||||
visible: !this.state.visible,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const content = this.props.ev.getContent();
|
|
||||||
const { channel, network, protocol } = content;
|
|
||||||
const protocolName = protocol.displayname || protocol.id;
|
|
||||||
const channelName = channel.displayname || channel.id;
|
|
||||||
const networkName = network ? network.displayname || network.id : protocolName;
|
|
||||||
|
|
||||||
let creator = null;
|
|
||||||
if (content.creator) {
|
|
||||||
creator = _t("This bridge was provisioned by <user />.", {}, {
|
|
||||||
user: <Pill
|
|
||||||
type={Pill.TYPE_USER_MENTION}
|
|
||||||
room={this.props.room}
|
|
||||||
url={makeUserPermalink(content.creator)}
|
|
||||||
shouldShowPillAvatar={SettingsStore.getValue("Pill.shouldShowPillAvatar")}
|
|
||||||
/>,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const bot = _t("This bridge is managed by <user />.", {}, {
|
|
||||||
user: <Pill
|
|
||||||
type={Pill.TYPE_USER_MENTION}
|
|
||||||
room={this.props.room}
|
|
||||||
url={makeUserPermalink(this.props.ev.getSender())}
|
|
||||||
shouldShowPillAvatar={SettingsStore.getValue("Pill.shouldShowPillAvatar")}
|
|
||||||
/>,
|
|
||||||
});
|
|
||||||
|
|
||||||
let networkIcon;
|
|
||||||
|
|
||||||
if (protocol.avatar) {
|
|
||||||
const avatarUrl = getHttpUriForMxc(
|
|
||||||
MatrixClientPeg.get().getHomeserverUrl(),
|
|
||||||
protocol.avatar, 64, 64, "crop",
|
|
||||||
);
|
|
||||||
|
|
||||||
networkIcon = <BaseAvatar className="protocol-icon"
|
|
||||||
width={48}
|
|
||||||
height={48}
|
|
||||||
resizeMethod='crop'
|
|
||||||
name={ protocolName }
|
|
||||||
idName={ protocolName }
|
|
||||||
url={ avatarUrl }
|
|
||||||
/>;
|
|
||||||
} else {
|
|
||||||
networkIcon = <div class="noProtocolIcon"></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = this.props.ev.getId();
|
|
||||||
const metadataClassname = "metadata" + (this.state.visible ? " visible" : "");
|
|
||||||
return (<li key={id}>
|
|
||||||
<div className="column-icon">
|
|
||||||
{networkIcon}
|
|
||||||
</div>
|
|
||||||
<div className="column-data">
|
|
||||||
<h3>{protocolName}</h3>
|
|
||||||
<p className="workspace-channel-details">
|
|
||||||
<span>{_t("Workspace: %(networkName)s", {networkName})}</span>
|
|
||||||
<span className="channel">{_t("Channel: %(channelName)s", {channelName})}</span>
|
|
||||||
</p>
|
|
||||||
<p className={metadataClassname}>
|
|
||||||
{creator} {bot}
|
|
||||||
</p>
|
|
||||||
<AccessibleButton className="mx_showMore" kind="secondary" onClick={this._toggleVisible.bind(this)}>
|
|
||||||
{ this.state.visible ? _t("Show less") : _t("Show more") }
|
|
||||||
</AccessibleButton>
|
|
||||||
</div>
|
|
||||||
</li>);
|
|
||||||
}
|
|
||||||
}
|
|
167
src/components/views/settings/BridgeTile.tsx
Normal file
167
src/components/views/settings/BridgeTile.tsx
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
||||||
|
import {_t} from "../../../languageHandler";
|
||||||
|
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
|
import Pill from "../elements/Pill";
|
||||||
|
import {makeUserPermalink} from "../../../utils/permalinks/Permalinks";
|
||||||
|
import BaseAvatar from "../avatars/BaseAvatar";
|
||||||
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||||
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { isUrlPermitted } from '../../../HtmlUtils';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
ev: MatrixEvent;
|
||||||
|
room: Room;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should match https://github.com/matrix-org/matrix-doc/blob/hs/msc-bridge-inf/proposals/2346-bridge-info-state-event.md#mbridge
|
||||||
|
*/
|
||||||
|
interface IBridgeStateEvent {
|
||||||
|
bridgebot: string;
|
||||||
|
creator?: string;
|
||||||
|
protocol: {
|
||||||
|
id: string;
|
||||||
|
displayname?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
avatar_url?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
external_url?: string;
|
||||||
|
};
|
||||||
|
network?: {
|
||||||
|
id: string;
|
||||||
|
displayname?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
avatar_url?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
external_url?: string;
|
||||||
|
};
|
||||||
|
channel: {
|
||||||
|
id: string;
|
||||||
|
displayname?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
avatar_url?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
external_url?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class BridgeTile extends React.PureComponent<IProps> {
|
||||||
|
static propTypes = {
|
||||||
|
ev: PropTypes.object.isRequired,
|
||||||
|
room: PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const content: IBridgeStateEvent = this.props.ev.getContent();
|
||||||
|
// Validate
|
||||||
|
if (!content.channel?.id || !content.protocol?.id) {
|
||||||
|
console.warn(`Bridge info event ${this.props.ev.getId()} has missing content. Tile will not render`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!content.bridgebot) {
|
||||||
|
// Bridgebot was not required previously, so in order to not break rooms we are allowing
|
||||||
|
// the sender to be used in place. When the proposal is merged, this should be removed.
|
||||||
|
console.warn(`Bridge info event ${this.props.ev.getId()} does not provide a 'bridgebot' key which`
|
||||||
|
+ "is deprecated behaviour. Using sender for now.");
|
||||||
|
content.bridgebot = this.props.ev.getSender();
|
||||||
|
}
|
||||||
|
const { channel, network, protocol } = content;
|
||||||
|
const protocolName = protocol.displayname || protocol.id;
|
||||||
|
const channelName = channel.displayname || channel.id;
|
||||||
|
|
||||||
|
let creator = null;
|
||||||
|
if (content.creator) {
|
||||||
|
creator = <li>{_t("This bridge was provisioned by <user />.", {}, {
|
||||||
|
user: () => <Pill
|
||||||
|
type={Pill.TYPE_USER_MENTION}
|
||||||
|
room={this.props.room}
|
||||||
|
url={makeUserPermalink(content.creator)}
|
||||||
|
shouldShowPillAvatar={SettingsStore.getValue("Pill.shouldShowPillAvatar")}
|
||||||
|
/>,
|
||||||
|
})}</li>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bot = <li>{_t("This bridge is managed by <user />.", {}, {
|
||||||
|
user: () => <Pill
|
||||||
|
type={Pill.TYPE_USER_MENTION}
|
||||||
|
room={this.props.room}
|
||||||
|
url={makeUserPermalink(content.bridgebot)}
|
||||||
|
shouldShowPillAvatar={SettingsStore.getValue("Pill.shouldShowPillAvatar")}
|
||||||
|
/>,
|
||||||
|
})}</li>;
|
||||||
|
|
||||||
|
let networkIcon;
|
||||||
|
|
||||||
|
if (protocol.avatar_url) {
|
||||||
|
const avatarUrl = getHttpUriForMxc(
|
||||||
|
MatrixClientPeg.get().getHomeserverUrl(),
|
||||||
|
protocol.avatar_url, 64, 64, "crop",
|
||||||
|
);
|
||||||
|
|
||||||
|
networkIcon = <BaseAvatar className="protocol-icon"
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
resizeMethod='crop'
|
||||||
|
name={ protocolName }
|
||||||
|
idName={ protocolName }
|
||||||
|
url={ avatarUrl }
|
||||||
|
/>;
|
||||||
|
} else {
|
||||||
|
networkIcon = <div className="noProtocolIcon"></div>;
|
||||||
|
}
|
||||||
|
let networkItem = null;
|
||||||
|
if (network) {
|
||||||
|
const networkName = network.displayname || network.id;
|
||||||
|
let networkLink = <span>{networkName}</span>;
|
||||||
|
if (typeof network.external_url === "string" && isUrlPermitted(network.external_url)) {
|
||||||
|
networkLink = <a href={network.external_url} target="_blank" rel="noreferrer noopener">{networkName}</a>
|
||||||
|
}
|
||||||
|
networkItem = _t("Workspace: <networkLink/>", {}, {
|
||||||
|
networkLink: () => networkLink,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let channelLink = <span>{channelName}</span>;
|
||||||
|
if (typeof channel.external_url === "string" && isUrlPermitted(channel.external_url)) {
|
||||||
|
channelLink = <a href={channel.external_url} target="_blank" rel="noreferrer noopener">{channelName}</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = this.props.ev.getId();
|
||||||
|
return (<li key={id}>
|
||||||
|
<div className="column-icon">
|
||||||
|
{networkIcon}
|
||||||
|
</div>
|
||||||
|
<div className="column-data">
|
||||||
|
<h3>{protocolName}</h3>
|
||||||
|
<p className="workspace-channel-details">
|
||||||
|
{networkItem}
|
||||||
|
<span className="channel">{_t("Channel: <channelLink/>", {}, {
|
||||||
|
channelLink: () => channelLink,
|
||||||
|
})}</span>
|
||||||
|
</p>
|
||||||
|
<ul className="metadata">
|
||||||
|
{creator} {bot}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>);
|
||||||
|
}
|
||||||
|
}
|
|
@ -584,6 +584,7 @@
|
||||||
"Send stickers into this room": "Send stickers into this room",
|
"Send stickers into this room": "Send stickers into this room",
|
||||||
"Send stickers into your active room": "Send stickers into your active room",
|
"Send stickers into your active room": "Send stickers into your active room",
|
||||||
"Change which room you're viewing": "Change which room you're viewing",
|
"Change which room you're viewing": "Change which room you're viewing",
|
||||||
|
"Change which room, message, or user you're viewing": "Change which room, message, or user you're viewing",
|
||||||
"Change the topic of this room": "Change the topic of this room",
|
"Change the topic of this room": "Change the topic of this room",
|
||||||
"See when the topic changes in this room": "See when the topic changes in this room",
|
"See when the topic changes in this room": "See when the topic changes in this room",
|
||||||
"Change the topic of your active room": "Change the topic of your active room",
|
"Change the topic of your active room": "Change the topic of your active room",
|
||||||
|
@ -965,10 +966,8 @@
|
||||||
"Upload": "Upload",
|
"Upload": "Upload",
|
||||||
"This bridge was provisioned by <user />.": "This bridge was provisioned by <user />.",
|
"This bridge was provisioned by <user />.": "This bridge was provisioned by <user />.",
|
||||||
"This bridge is managed by <user />.": "This bridge is managed by <user />.",
|
"This bridge is managed by <user />.": "This bridge is managed by <user />.",
|
||||||
"Workspace: %(networkName)s": "Workspace: %(networkName)s",
|
"Workspace: <networkLink/>": "Workspace: <networkLink/>",
|
||||||
"Channel: %(channelName)s": "Channel: %(channelName)s",
|
"Channel: <channelLink/>": "Channel: <channelLink/>",
|
||||||
"Show less": "Show less",
|
|
||||||
"Show more": "Show more",
|
|
||||||
"Failed to upload profile picture!": "Failed to upload profile picture!",
|
"Failed to upload profile picture!": "Failed to upload profile picture!",
|
||||||
"Upload new:": "Upload new:",
|
"Upload new:": "Upload new:",
|
||||||
"No display name": "No display name",
|
"No display name": "No display name",
|
||||||
|
@ -1532,6 +1531,7 @@
|
||||||
"Jump to first invite.": "Jump to first invite.",
|
"Jump to first invite.": "Jump to first invite.",
|
||||||
"Show %(count)s more|other": "Show %(count)s more",
|
"Show %(count)s more|other": "Show %(count)s more",
|
||||||
"Show %(count)s more|one": "Show %(count)s more",
|
"Show %(count)s more|one": "Show %(count)s more",
|
||||||
|
"Show less": "Show less",
|
||||||
"Use default": "Use default",
|
"Use default": "Use default",
|
||||||
"All messages": "All messages",
|
"All messages": "All messages",
|
||||||
"Mentions & Keywords": "Mentions & Keywords",
|
"Mentions & Keywords": "Mentions & Keywords",
|
||||||
|
@ -1594,6 +1594,7 @@
|
||||||
"New published address (e.g. #alias:server)": "New published address (e.g. #alias:server)",
|
"New published address (e.g. #alias:server)": "New published address (e.g. #alias:server)",
|
||||||
"Local Addresses": "Local Addresses",
|
"Local Addresses": "Local Addresses",
|
||||||
"Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)",
|
"Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)",
|
||||||
|
"Show more": "Show more",
|
||||||
"Error updating flair": "Error updating flair",
|
"Error updating flair": "Error updating flair",
|
||||||
"There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.",
|
"There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.",
|
||||||
"Invalid community ID": "Invalid community ID",
|
"Invalid community ID": "Invalid community ID",
|
||||||
|
|
|
@ -426,7 +426,8 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
"allowedWidgets": {
|
"allowedWidgets": {
|
||||||
supportedLevels: [SettingLevel.ROOM_ACCOUNT],
|
supportedLevels: [SettingLevel.ROOM_ACCOUNT, SettingLevel.ROOM_DEVICE],
|
||||||
|
supportedLevelsAreOrdered: true,
|
||||||
default: {}, // none allowed
|
default: {}, // none allowed
|
||||||
},
|
},
|
||||||
"analyticsOptIn": {
|
"analyticsOptIn": {
|
||||||
|
|
|
@ -467,6 +467,32 @@ export default class SettingsStore {
|
||||||
return LEVEL_HANDLERS[level].isSupported();
|
return LEVEL_HANDLERS[level].isSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the first supported level out of all the levels that can be used for a
|
||||||
|
* specific setting.
|
||||||
|
* @param {string} settingName The setting name.
|
||||||
|
* @return {SettingLevel}
|
||||||
|
*/
|
||||||
|
public static firstSupportedLevel(settingName: string): SettingLevel {
|
||||||
|
// Verify that the setting is actually a setting
|
||||||
|
const setting = SETTINGS[settingName];
|
||||||
|
if (!setting) {
|
||||||
|
throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const levelOrder = (setting.supportedLevelsAreOrdered ? setting.supportedLevels : LEVEL_ORDER);
|
||||||
|
if (!levelOrder.includes(SettingLevel.DEFAULT)) levelOrder.push(SettingLevel.DEFAULT); // always include default
|
||||||
|
|
||||||
|
const handlers = SettingsStore.getHandlers(settingName);
|
||||||
|
|
||||||
|
for (const level of levelOrder) {
|
||||||
|
const handler = handlers[level];
|
||||||
|
if (!handler) continue;
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debugging function for reading explicit setting values without going through the
|
* Debugging function for reading explicit setting values without going through the
|
||||||
* complicated/biased functions in the SettingsStore. This will print information to
|
* complicated/biased functions in the SettingsStore. This will print information to
|
||||||
|
|
|
@ -169,7 +169,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa
|
||||||
|
|
||||||
public isSupported(): boolean {
|
public isSupported(): boolean {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
return cli !== undefined && cli !== null;
|
return cli !== undefined && cli !== null && !cli.isGuest();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSettings(eventType = "im.vector.web.settings"): any { // TODO: [TS] Types on return
|
private getSettings(eventType = "im.vector.web.settings"): any { // TODO: [TS] Types on return
|
||||||
|
|
|
@ -129,7 +129,7 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin
|
||||||
|
|
||||||
public isSupported(): boolean {
|
public isSupported(): boolean {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
return cli !== undefined && cli !== null;
|
return cli !== undefined && cli !== null && !cli.isGuest();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSettings(roomId: string, eventType = "im.vector.web.settings"): any { // TODO: [TS] Type return
|
private getSettings(roomId: string, eventType = "im.vector.web.settings"): any { // TODO: [TS] Type return
|
||||||
|
|
|
@ -48,6 +48,10 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient<IState> {
|
||||||
return CommunityPrototypeStore.internalInstance;
|
return CommunityPrototypeStore.internalInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getUpdateEventName(roomId: string): string {
|
||||||
|
return `${UPDATE_EVENT}:${roomId}`;
|
||||||
|
}
|
||||||
|
|
||||||
public getSelectedCommunityId(): string {
|
public getSelectedCommunityId(): string {
|
||||||
if (SettingsStore.getValue("feature_communities_v2_prototypes")) {
|
if (SettingsStore.getValue("feature_communities_v2_prototypes")) {
|
||||||
return GroupFilterOrderStore.getSelectedTags()[0];
|
return GroupFilterOrderStore.getSelectedTags()[0];
|
||||||
|
@ -134,7 +138,8 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
} else if (payload.action === "MatrixActions.accountData") {
|
} else if (payload.action === "MatrixActions.accountData") {
|
||||||
if (payload.event_type.startsWith("im.vector.group_info.")) {
|
if (payload.event_type.startsWith("im.vector.group_info.")) {
|
||||||
this.emit(UPDATE_EVENT, payload.event_type.substring("im.vector.group_info.".length));
|
const roomId = payload.event_type.substring("im.vector.group_info.".length);
|
||||||
|
this.emit(CommunityPrototypeStore.getUpdateEventName(roomId), roomId);
|
||||||
}
|
}
|
||||||
} else if (payload.action === "select_tag") {
|
} else if (payload.action === "select_tag") {
|
||||||
// Automatically select the general chat when switching communities
|
// Automatically select the general chat when switching communities
|
||||||
|
@ -167,7 +172,7 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient<IState> {
|
||||||
if (getEffectiveMembership(myMember.membership) === EffectiveMembership.Invite) {
|
if (getEffectiveMembership(myMember.membership) === EffectiveMembership.Invite) {
|
||||||
// Fake an update for anything that might have started listening before the invite
|
// Fake an update for anything that might have started listening before the invite
|
||||||
// data was available (eg: RoomPreviewBar after a refresh)
|
// data was available (eg: RoomPreviewBar after a refresh)
|
||||||
this.emit(UPDATE_EVENT, room.roomId);
|
this.emit(CommunityPrototypeStore.getUpdateEventName(room.roomId), room.roomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { UPDATE_EVENT } from "../AsyncStore";
|
||||||
|
|
||||||
// Emitted event for when a room's preview has changed. First argument will the room for which
|
// Emitted event for when a room's preview has changed. First argument will the room for which
|
||||||
// the change happened.
|
// the change happened.
|
||||||
export const ROOM_PREVIEW_CHANGED = "room_preview_changed";
|
const ROOM_PREVIEW_CHANGED = "room_preview_changed";
|
||||||
|
|
||||||
const PREVIEWS = {
|
const PREVIEWS = {
|
||||||
'm.room.message': {
|
'm.room.message': {
|
||||||
|
@ -84,6 +84,10 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
|
||||||
return MessagePreviewStore.internalInstance;
|
return MessagePreviewStore.internalInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getPreviewChangedEventName(room: Room): string {
|
||||||
|
return `${ROOM_PREVIEW_CHANGED}:${room?.roomId}`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pre-translated preview for a given room
|
* Gets the pre-translated preview for a given room
|
||||||
* @param room The room to get the preview for.
|
* @param room The room to get the preview for.
|
||||||
|
@ -150,7 +154,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
|
||||||
// We've muted the underlying Map, so just emit that we've changed.
|
// We've muted the underlying Map, so just emit that we've changed.
|
||||||
this.previews.set(room.roomId, map);
|
this.previews.set(room.roomId, map);
|
||||||
this.emit(UPDATE_EVENT, this);
|
this.emit(UPDATE_EVENT, this);
|
||||||
this.emit(ROOM_PREVIEW_CHANGED, room);
|
this.emit(MessagePreviewStore.getPreviewChangedEventName(room), room);
|
||||||
}
|
}
|
||||||
return; // we're done
|
return; // we're done
|
||||||
}
|
}
|
||||||
|
@ -158,7 +162,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
|
||||||
// At this point, we didn't generate a preview so clear it
|
// At this point, we didn't generate a preview so clear it
|
||||||
this.previews.set(room.roomId, new Map<TagID|TAG_ANY, string|null>());
|
this.previews.set(room.roomId, new Map<TagID|TAG_ANY, string|null>());
|
||||||
this.emit(UPDATE_EVENT, this);
|
this.emit(UPDATE_EVENT, this);
|
||||||
this.emit(ROOM_PREVIEW_CHANGED, room);
|
this.emit(MessagePreviewStore.getPreviewChangedEventName(room), room);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async onAction(payload: ActionPayload) {
|
protected async onAction(payload: ActionPayload) {
|
||||||
|
|
|
@ -20,9 +20,16 @@ export enum ElementWidgetActions {
|
||||||
ClientReady = "im.vector.ready",
|
ClientReady = "im.vector.ready",
|
||||||
HangupCall = "im.vector.hangup",
|
HangupCall = "im.vector.hangup",
|
||||||
OpenIntegrationManager = "integration_manager_open",
|
OpenIntegrationManager = "integration_manager_open",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use MSC2931 instead
|
||||||
|
*/
|
||||||
ViewRoom = "io.element.view_room",
|
ViewRoom = "io.element.view_room",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use MSC2931 instead
|
||||||
|
*/
|
||||||
export interface IViewRoomApiRequest extends IWidgetApiRequest {
|
export interface IViewRoomApiRequest extends IWidgetApiRequest {
|
||||||
data: {
|
data: {
|
||||||
room_id: string; // eslint-disable-line camelcase
|
room_id: string; // eslint-disable-line camelcase
|
||||||
|
|
|
@ -15,5 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export enum ElementWidgetCapabilities {
|
export enum ElementWidgetCapabilities {
|
||||||
|
/**
|
||||||
|
* @deprecated Use MSC2931 instead.
|
||||||
|
*/
|
||||||
CanChangeViewedRoom = "io.element.view_room",
|
CanChangeViewedRoom = "io.element.view_room",
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { CHAT_EFFECTS } from "../../effects";
|
import { CHAT_EFFECTS } from "../../effects";
|
||||||
import { containsEmoji } from "../../effects/utils";
|
import { containsEmoji } from "../../effects/utils";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
|
import {tryTransformPermalinkToLocalHref} from "../../utils/permalinks/Permalinks";
|
||||||
|
|
||||||
// TODO: Purge this from the universe
|
// TODO: Purge this from the universe
|
||||||
|
|
||||||
|
@ -171,4 +172,12 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async navigate(uri: string): Promise<void> {
|
||||||
|
const localUri = tryTransformPermalinkToLocalHref(uri);
|
||||||
|
if (!localUri || localUri === uri) { // parse failure can lead to an unmodified URL
|
||||||
|
throw new Error("Failed to transform URI");
|
||||||
|
}
|
||||||
|
window.location.hash = localUri; // it'll just be a fragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ export class CapabilityText {
|
||||||
[ElementWidgetCapabilities.CanChangeViewedRoom]: {
|
[ElementWidgetCapabilities.CanChangeViewedRoom]: {
|
||||||
[GENERIC_WIDGET_KIND]: _td("Change which room you're viewing"),
|
[GENERIC_WIDGET_KIND]: _td("Change which room you're viewing"),
|
||||||
},
|
},
|
||||||
|
[MatrixCapabilities.MSC2931Navigate]: {
|
||||||
|
[GENERIC_WIDGET_KIND]: _td("Change which room, message, or user you're viewing"),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
private static stateSendRecvCaps: ISendRecvStaticCapText = {
|
private static stateSendRecvCaps: ISendRecvStaticCapText = {
|
||||||
|
|
|
@ -222,6 +222,7 @@ describe("<TextualBody />", () => {
|
||||||
getRoom: () => mkStubRoom("room_id"),
|
getRoom: () => mkStubRoom("room_id"),
|
||||||
getAccountData: () => undefined,
|
getAccountData: () => undefined,
|
||||||
getUrlPreview: (url) => new Promise(() => {}),
|
getUrlPreview: (url) => new Promise(() => {}),
|
||||||
|
isGuest: () => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ev = mkEvent({
|
const ev = mkEvent({
|
||||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -1809,6 +1809,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||||
|
|
||||||
|
"@types/events@^3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||||
|
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||||
|
|
||||||
"@types/fbemitter@*":
|
"@types/fbemitter@*":
|
||||||
version "2.0.32"
|
version "2.0.32"
|
||||||
resolved "https://registry.yarnpkg.com/@types/fbemitter/-/fbemitter-2.0.32.tgz#8ed204da0f54e9c8eaec31b1eec91e25132d082c"
|
resolved "https://registry.yarnpkg.com/@types/fbemitter/-/fbemitter-2.0.32.tgz#8ed204da0f54e9c8eaec31b1eec91e25132d082c"
|
||||||
|
@ -6554,8 +6559,8 @@ mathml-tag-names@^2.0.1:
|
||||||
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
|
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
|
||||||
version "9.4.1"
|
version "9.5.0"
|
||||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/1717fcf499b943517213f2a81c41ffec0b50748e"
|
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/214a9df3823e602400b24d9a81cfc7b7df0a863b"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
another-json "^0.2.0"
|
another-json "^0.2.0"
|
||||||
|
@ -6580,11 +6585,12 @@ matrix-react-test-utils@^0.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/matrix-react-test-utils/-/matrix-react-test-utils-0.2.2.tgz#c87144d3b910c7edc544a6699d13c7c2bf02f853"
|
resolved "https://registry.yarnpkg.com/matrix-react-test-utils/-/matrix-react-test-utils-0.2.2.tgz#c87144d3b910c7edc544a6699d13c7c2bf02f853"
|
||||||
integrity sha512-49+7gfV6smvBIVbeloql+37IeWMTD+fiywalwCqk8Dnz53zAFjKSltB3rmWHso1uecLtQEcPtCijfhzcLXAxTQ==
|
integrity sha512-49+7gfV6smvBIVbeloql+37IeWMTD+fiywalwCqk8Dnz53zAFjKSltB3rmWHso1uecLtQEcPtCijfhzcLXAxTQ==
|
||||||
|
|
||||||
matrix-widget-api@^0.1.0-beta.10:
|
matrix-widget-api@0.1.0-beta.11:
|
||||||
version "0.1.0-beta.10"
|
version "0.1.0-beta.11"
|
||||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.10.tgz#2e4d658d90ff3152c5567089b4ddd21fb44ec1dd"
|
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.11.tgz#3658e244bf82eebea36e64475ebfce86b778b476"
|
||||||
integrity sha512-yX2UURjM1zVp7snPiOFcH9+FDBdHfAdt5HEAyDUHGJ7w/F2zOtcK/y0dMlZ1+XhxY7Wv0IBZH0US8X/ioJRX1A==
|
integrity sha512-RxIghopRKTQdmYMJzZg/QR+wcPcKe9S1pZZ31zN/M1LKsvTLThBYdMcP1idKh7MkhpO9eCdCVjJOMJTrqxNzbQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@types/events" "^3.0.0"
|
||||||
events "^3.2.0"
|
events "^3.2.0"
|
||||||
|
|
||||||
mdast-util-compact@^1.0.0:
|
mdast-util-compact@^1.0.0:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue