Merge branches 'develop' and 't3chguy/room_avatar' of github.com:matrix-org/matrix-react-sdk into t3chguy/room_avatar
This commit is contained in:
commit
4983378230
26 changed files with 193 additions and 136 deletions
|
@ -16,9 +16,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
import {MatrixClient, MemoryStore} from 'matrix-js-sdk';
|
||||
|
||||
import utils from 'matrix-js-sdk/lib/utils';
|
||||
import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline';
|
||||
|
@ -27,7 +25,6 @@ import sdk from './index';
|
|||
import createMatrixClient from './utils/createMatrixClient';
|
||||
import SettingsStore from './settings/SettingsStore';
|
||||
import MatrixActionCreators from './actions/MatrixActionCreators';
|
||||
import {phasedRollOutExpiredForUser} from "./PhasedRollOut";
|
||||
import Modal from './Modal';
|
||||
import {verificationMethods} from 'matrix-js-sdk/lib/crypto';
|
||||
import MatrixClientBackedSettingsHandler from "./settings/handlers/MatrixClientBackedSettingsHandler";
|
||||
|
@ -87,7 +84,7 @@ class MatrixClientPeg {
|
|||
MatrixActionCreators.stop();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* If we've registered a user ID we set this to the ID of the
|
||||
* user we've just registered. If they then go & log in, we
|
||||
* can send them to the welcome user (obviously this doesn't
|
||||
|
@ -99,7 +96,7 @@ class MatrixClientPeg {
|
|||
this._justRegisteredUserId = uid;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Returns true if the current user has just been registered by this
|
||||
* client as determined by setJustRegisteredUserId()
|
||||
*
|
||||
|
@ -112,7 +109,7 @@ class MatrixClientPeg {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Replace this MatrixClientPeg's client with a client instance that has
|
||||
* homeserver / identity server URLs and active credentials
|
||||
*/
|
||||
|
@ -131,7 +128,7 @@ class MatrixClientPeg {
|
|||
} catch (err) {
|
||||
if (dbType === 'indexeddb') {
|
||||
console.error('Error starting matrixclient store - falling back to memory store', err);
|
||||
this.matrixClient.store = new Matrix.MemoryStore({
|
||||
this.matrixClient.store = new MemoryStore({
|
||||
localStorage: global.localStorage,
|
||||
});
|
||||
} else {
|
||||
|
@ -195,7 +192,7 @@ class MatrixClientPeg {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return the server name of the user's homeserver
|
||||
* Throws an error if unable to deduce the homeserver name
|
||||
* (eg. if the user is not logged in)
|
||||
|
|
|
@ -112,7 +112,7 @@ const Notifier = {
|
|||
console.warn(`${roomId} has custom notification sound event, but no url key`);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (!content.url.startsWith("mxc://")) {
|
||||
console.warn(`${roomId} has custom notification sound event, but url is not a mxc url`);
|
||||
return null;
|
||||
|
@ -203,7 +203,8 @@ const Notifier = {
|
|||
// The permission request was dismissed or denied
|
||||
// TODO: Support alternative branding in messaging
|
||||
const description = result === 'denied'
|
||||
? _t('Riot does not have permission to send you notifications - please check your browser settings')
|
||||
? _t('Riot does not have permission to send you notifications - ' +
|
||||
'please check your browser settings')
|
||||
: _t('Riot was not given permission to send notifications - please try again');
|
||||
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
|
||||
Modal.createTrackedDialog('Unable to enable Notifications', result, ErrorDialog, {
|
||||
|
|
|
@ -15,8 +15,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||
const dis = require("./dispatcher");
|
||||
import MatrixClientPeg from "./MatrixClientPeg";
|
||||
import dis from "./dispatcher";
|
||||
import Timer from './utils/Timer';
|
||||
|
||||
// Time in ms after that a user is considered as unavailable/away
|
||||
|
@ -24,7 +24,6 @@ const UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
|
|||
const PRESENCE_STATES = ["online", "offline", "unavailable"];
|
||||
|
||||
class Presence {
|
||||
|
||||
constructor() {
|
||||
this._activitySignal = null;
|
||||
this._unavailableTimer = null;
|
||||
|
@ -43,7 +42,7 @@ class Presence {
|
|||
try {
|
||||
await this._unavailableTimer.finished();
|
||||
this.setState("unavailable");
|
||||
} catch(e) { /* aborted, stop got called */ }
|
||||
} catch (e) { /* aborted, stop got called */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +87,7 @@ class Presence {
|
|||
if (PRESENCE_STATES.indexOf(newState) === -1) {
|
||||
throw new Error("Bad presence state: " + newState);
|
||||
}
|
||||
const old_state = this.state;
|
||||
const oldState = this.state;
|
||||
this.state = newState;
|
||||
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
|
@ -98,9 +97,9 @@ class Presence {
|
|||
try {
|
||||
await MatrixClientPeg.get().setPresence(this.state);
|
||||
console.log("Presence: %s", newState);
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.error("Failed to set presence: %s", err);
|
||||
this.state = old_state;
|
||||
this.state = oldState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export function levelRoleMap(usersDefault) {
|
|||
}
|
||||
|
||||
export function textualPowerLevel(level, usersDefault) {
|
||||
const LEVEL_ROLE_MAP = this.levelRoleMap(usersDefault);
|
||||
const LEVEL_ROLE_MAP = levelRoleMap(usersDefault);
|
||||
if (LEVEL_ROLE_MAP[level]) {
|
||||
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${usersDefault})`);
|
||||
} else {
|
||||
|
|
|
@ -14,12 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
import Promise from 'bluebird';
|
||||
const Matrix = require("matrix-js-sdk");
|
||||
const Room = Matrix.Room;
|
||||
const CallHandler = require('./CallHandler');
|
||||
import {createNewMatrixCall, Room} from "matrix-js-sdk";
|
||||
import CallHandler from './CallHandler';
|
||||
import MatrixClientPeg from "./MatrixClientPeg";
|
||||
|
||||
// FIXME: this is Riot (Vector) specific code, but will be removed shortly when
|
||||
// we switch over to jitsi entirely for video conferencing.
|
||||
|
@ -45,7 +43,7 @@ ConferenceCall.prototype.setup = function() {
|
|||
// return a call for *this* room to be placed. We also tack on
|
||||
// confUserId to speed up lookups (else we'd need to loop every room
|
||||
// looking for a 1:1 room with this conf user ID!)
|
||||
const call = Matrix.createNewMatrixCall(self.client, room.roomId);
|
||||
const call = createNewMatrixCall(self.client, room.roomId);
|
||||
call.confUserId = self.confUserId;
|
||||
call.groupRoomId = self.groupRoomId;
|
||||
return call;
|
||||
|
@ -84,7 +82,7 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
|
|||
preset: "private_chat",
|
||||
invite: [this.confUserId],
|
||||
}).then(function(res) {
|
||||
return new Room(res.room_id, null, client.getUserId());
|
||||
return new Room(res.room_id, null, MatrixClientPeg.get().getUserId());
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||
import MatrixClientPeg from "./MatrixClientPeg";
|
||||
import { _t } from './languageHandler';
|
||||
|
||||
module.exports = {
|
||||
|
@ -33,6 +33,9 @@ module.exports = {
|
|||
/**
|
||||
* Given a Room object and, optionally, a list of userID strings
|
||||
* to exclude, return a list of user objects who are typing.
|
||||
* @param {Room} room: room object to get users from.
|
||||
* @param {string[]} exclude: list of user mxids to exclude.
|
||||
* @returns {string[]} list of user objects who are typing.
|
||||
*/
|
||||
usersTyping: function(room, exclude) {
|
||||
const whoIsTyping = [];
|
||||
|
@ -46,7 +49,7 @@ module.exports = {
|
|||
const userId = memberKeys[i];
|
||||
|
||||
if (room.currentState.members[userId].typing) {
|
||||
if (exclude.indexOf(userId) == -1) {
|
||||
if (exclude.indexOf(userId) === -1) {
|
||||
whoIsTyping.push(room.currentState.members[userId]);
|
||||
}
|
||||
}
|
||||
|
@ -60,16 +63,19 @@ module.exports = {
|
|||
if (whoIsTyping.length > limit) {
|
||||
othersCount = whoIsTyping.length - limit + 1;
|
||||
}
|
||||
if (whoIsTyping.length == 0) {
|
||||
if (whoIsTyping.length === 0) {
|
||||
return '';
|
||||
} else if (whoIsTyping.length == 1) {
|
||||
} else if (whoIsTyping.length === 1) {
|
||||
return _t('%(displayName)s is typing …', {displayName: whoIsTyping[0].name});
|
||||
}
|
||||
const names = whoIsTyping.map(function(m) {
|
||||
return m.name;
|
||||
});
|
||||
if (othersCount>=1) {
|
||||
return _t('%(names)s and %(count)s others are typing …', {names: names.slice(0, limit - 1).join(', '), count: othersCount});
|
||||
return _t('%(names)s and %(count)s others are typing …', {
|
||||
names: names.slice(0, limit - 1).join(', '),
|
||||
count: othersCount,
|
||||
});
|
||||
} else {
|
||||
const lastPerson = names.pop();
|
||||
return _t('%(names)s and %(lastPerson)s are typing …', {names: names.join(', '), lastPerson: lastPerson});
|
||||
|
|
|
@ -20,6 +20,7 @@ import React from 'react';
|
|||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import {focusCapturedRef} from "../../utils/Accessibility";
|
||||
|
||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||
|
@ -83,6 +84,9 @@ export default class ContextualMenu extends React.Component {
|
|||
// We don't need to clean up when unmounting, so ignore
|
||||
if (!element) return;
|
||||
|
||||
// For screen readers to find the thing
|
||||
focusCapturedRef(element);
|
||||
|
||||
this.setState({
|
||||
contextMenuRect: element.getBoundingClientRect(),
|
||||
});
|
||||
|
@ -206,7 +210,7 @@ export default class ContextualMenu extends React.Component {
|
|||
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||
// property set here so you can't close the menu from a button click!
|
||||
return <div className={className} style={{...position, ...wrapperStyle}}>
|
||||
<div className={menuClasses} style={menuStyle} ref={this.collectContextMenuRect}>
|
||||
<div className={menuClasses} style={menuStyle} ref={this.collectContextMenuRect} tabIndex={0}>
|
||||
{ chevron }
|
||||
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
||||
</div>
|
||||
|
|
|
@ -286,7 +286,10 @@ export default createReactClass({
|
|||
// the first thing to do is to try the token params in the query-string
|
||||
// if the session isn't soft logged out (ie: is a clean session being logged in)
|
||||
if (!Lifecycle.isSoftLogout()) {
|
||||
Lifecycle.attemptTokenLogin(this.props.realQueryParams).then((loggedIn) => {
|
||||
Lifecycle.attemptTokenLogin(
|
||||
this.props.realQueryParams,
|
||||
this.props.defaultDeviceDisplayName,
|
||||
).then((loggedIn) => {
|
||||
if (loggedIn) {
|
||||
this.props.onTokenLoginCompleted();
|
||||
|
||||
|
|
|
@ -389,13 +389,7 @@ module.exports = createReactClass({
|
|||
},
|
||||
|
||||
onJoinClick: function(ev, room) {
|
||||
this.props.onFinished();
|
||||
MatrixClientPeg.get().joinRoom(room.room_id);
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.room_id,
|
||||
joining: true,
|
||||
});
|
||||
this.showRoom(room, null, true);
|
||||
ev.stopPropagation();
|
||||
},
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ import EditorStateTransfer from '../../utils/EditorStateTransfer';
|
|||
|
||||
const PAGINATE_SIZE = 20;
|
||||
const INITIAL_SIZE = 20;
|
||||
const READ_MARKER_INVIEW_THRESHOLD_MS = 1 * 1000;
|
||||
const READ_MARKER_OUTOFVIEW_THRESHOLD_MS = 30 * 1000;
|
||||
const READ_RECEIPT_INTERVAL_MS = 500;
|
||||
|
||||
const DEBUG = false;
|
||||
|
@ -191,6 +189,12 @@ const TimelinePanel = createReactClass({
|
|||
|
||||
// always show timestamps on event tiles?
|
||||
alwaysShowTimestamps: SettingsStore.getValue("alwaysShowTimestamps"),
|
||||
|
||||
// how long to show the RM for when it's visible in the window
|
||||
readMarkerInViewThresholdMs: SettingsStore.getValue("readMarkerInViewThresholdMs"),
|
||||
|
||||
// how long to show the RM for when it's scrolled off-screen
|
||||
readMarkerOutOfViewThresholdMs: SettingsStore.getValue("readMarkerOutOfViewThresholdMs"),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -593,8 +597,8 @@ const TimelinePanel = createReactClass({
|
|||
|
||||
_readMarkerTimeout(readMarkerPosition) {
|
||||
return readMarkerPosition === 0 ?
|
||||
READ_MARKER_INVIEW_THRESHOLD_MS :
|
||||
READ_MARKER_OUTOFVIEW_THRESHOLD_MS;
|
||||
this.state.readMarkerInViewThresholdMs :
|
||||
this.state.readMarkerOutOfViewThresholdMs;
|
||||
},
|
||||
|
||||
updateReadMarkerOnUserActivity: async function() {
|
||||
|
|
|
@ -80,7 +80,7 @@ module.exports = createReactClass({
|
|||
let validAddressTypes = this.props.validAddressTypes;
|
||||
// Remove email from validAddressTypes if no IS is configured. It may be added at a later stage by the user
|
||||
if (!MatrixClientPeg.get().getIdentityServerUrl() && validAddressTypes.includes("email")) {
|
||||
validAddressTypes = validAddressTypes.splice(validAddressTypes.indexOf("email"), 1);
|
||||
validAddressTypes = validAddressTypes.filter(type => type !== "email");
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -179,6 +179,7 @@ export default class BasicMessageEditor extends React.Component {
|
|||
const {partCreator} = model;
|
||||
const text = event.clipboardData.getData("text/plain");
|
||||
if (text) {
|
||||
this._modifiedFlag = true;
|
||||
const range = getRangeForSelection(this._editorRef, model, document.getSelection());
|
||||
const parts = parsePlainTextMessage(text, partCreator);
|
||||
replaceRangeAndMoveCaret(range, parts);
|
||||
|
|
|
@ -643,7 +643,11 @@ module.exports = createReactClass({
|
|||
_calculateOpsPermissions: async function(member) {
|
||||
let canDeactivate = false;
|
||||
if (this.context.matrixClient) {
|
||||
canDeactivate = await this.context.matrixClient.isSynapseAdministrator();
|
||||
try {
|
||||
canDeactivate = await this.context.matrixClient.isSynapseAdministrator();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
const defaultPerms = {
|
||||
|
|
|
@ -176,6 +176,7 @@ export default class PhoneNumbers extends React.Component {
|
|||
|
||||
this.setState({continueDisabled: true});
|
||||
const token = this.state.newPhoneNumberCode;
|
||||
const address = this.state.verifyMsisdn;
|
||||
this.state.addTask.haveMsisdnToken(token).then(() => {
|
||||
this.setState({
|
||||
addTask: null,
|
||||
|
@ -188,7 +189,7 @@ export default class PhoneNumbers extends React.Component {
|
|||
});
|
||||
const msisdns = [
|
||||
...this.props.msisdns,
|
||||
{ address: this.state.verifyMsisdn, medium: "msisdn" },
|
||||
{ address, medium: "msisdn" },
|
||||
];
|
||||
this.props.onMsisdnsChange(msisdns);
|
||||
}).catch((err) => {
|
||||
|
@ -272,8 +273,8 @@ export default class PhoneNumbers extends React.Component {
|
|||
onChange={this._onChangeNewPhoneNumber}
|
||||
/>
|
||||
</div>
|
||||
{addVerifySection}
|
||||
</form>
|
||||
{addVerifySection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,12 @@ export default class PreferencesUserSettingsTab extends React.Component {
|
|||
alwaysShowMenuBarSupported: false,
|
||||
minimizeToTray: true,
|
||||
minimizeToTraySupported: false,
|
||||
autocompleteDelay: SettingsStore.getValueAt(SettingLevel.DEVICE, 'autocompleteDelay').toString(10),
|
||||
autocompleteDelay:
|
||||
SettingsStore.getValueAt(SettingLevel.DEVICE, 'autocompleteDelay').toString(10),
|
||||
readMarkerInViewThresholdMs:
|
||||
SettingsStore.getValueAt(SettingLevel.DEVICE, 'readMarkerInViewThresholdMs').toString(10),
|
||||
readMarkerOutOfViewThresholdMs:
|
||||
SettingsStore.getValueAt(SettingLevel.DEVICE, 'readMarkerOutOfViewThresholdMs').toString(10),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -124,6 +129,16 @@ export default class PreferencesUserSettingsTab extends React.Component {
|
|||
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
_onReadMarkerInViewThresholdMs = (e) => {
|
||||
this.setState({readMarkerInViewThresholdMs: e.target.value});
|
||||
SettingsStore.setValue("readMarkerInViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
_onReadMarkerOutOfViewThresholdMs = (e) => {
|
||||
this.setState({readMarkerOutOfViewThresholdMs: e.target.value});
|
||||
SettingsStore.setValue("readMarkerOutOfViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
_renderGroup(settingIds) {
|
||||
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
|
||||
return settingIds.map(i => <SettingsFlag key={i} name={i} level={SettingLevel.ACCOUNT} />);
|
||||
|
@ -178,6 +193,18 @@ export default class PreferencesUserSettingsTab extends React.Component {
|
|||
type='number'
|
||||
value={this.state.autocompleteDelay}
|
||||
onChange={this._onAutocompleteDelayChange} />
|
||||
<Field
|
||||
id={"readMarkerInViewThresholdMs"}
|
||||
label={_t('Read Marker lifetime (ms)')}
|
||||
type='number'
|
||||
value={this.state.readMarkerInViewThresholdMs}
|
||||
onChange={this._onReadMarkerInViewThresholdMs} />
|
||||
<Field
|
||||
id={"readMarkerOutOfViewThresholdMs"}
|
||||
label={_t('Read Marker off-screen lifetime (ms)')}
|
||||
type='number'
|
||||
value={this.state.readMarkerOutOfViewThresholdMs}
|
||||
onChange={this._onReadMarkerOutOfViewThresholdMs} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -637,6 +637,8 @@
|
|||
"Timeline": "Timeline",
|
||||
"Room list": "Room list",
|
||||
"Autocomplete delay (ms)": "Autocomplete delay (ms)",
|
||||
"Read Marker lifetime (ms)": "Read Marker lifetime (ms)",
|
||||
"Read Marker off-screen lifetime (ms)": "Read Marker off-screen lifetime (ms)",
|
||||
"Unignore": "Unignore",
|
||||
"<not supported>": "<not supported>",
|
||||
"Import E2E room keys": "Import E2E room keys",
|
||||
|
|
|
@ -44,7 +44,7 @@ function matrixLinkify(linkify) {
|
|||
const S_ROOMALIAS_COLON = new linkify.parser.State();
|
||||
const S_ROOMALIAS_COLON_NUM = new linkify.parser.State(ROOMALIAS);
|
||||
|
||||
const roomname_tokens = [
|
||||
const roomnameTokens = [
|
||||
TT.DOT,
|
||||
TT.PLUS,
|
||||
TT.NUM,
|
||||
|
@ -58,8 +58,8 @@ function matrixLinkify(linkify) {
|
|||
TT.LOCALHOST,
|
||||
];
|
||||
|
||||
S_HASH.on(roomname_tokens, S_HASH_NAME);
|
||||
S_HASH_NAME.on(roomname_tokens, S_HASH_NAME);
|
||||
S_HASH.on(roomnameTokens, S_HASH_NAME);
|
||||
S_HASH_NAME.on(roomnameTokens, S_HASH_NAME);
|
||||
S_HASH_NAME.on(TT.DOMAIN, S_HASH_NAME);
|
||||
|
||||
S_HASH_NAME.on(TT.COLON, S_HASH_NAME_COLON);
|
||||
|
@ -92,7 +92,7 @@ function matrixLinkify(linkify) {
|
|||
const S_USERID_COLON = new linkify.parser.State();
|
||||
const S_USERID_COLON_NUM = new linkify.parser.State(USERID);
|
||||
|
||||
const username_tokens = [
|
||||
const usernameTokens = [
|
||||
TT.DOT,
|
||||
TT.UNDERSCORE,
|
||||
TT.PLUS,
|
||||
|
@ -100,12 +100,12 @@ function matrixLinkify(linkify) {
|
|||
TT.DOMAIN,
|
||||
TT.TLD,
|
||||
|
||||
// as in roomname_tokens
|
||||
// as in roomnameTokens
|
||||
TT.LOCALHOST,
|
||||
];
|
||||
|
||||
S_AT.on(username_tokens, S_AT_NAME);
|
||||
S_AT_NAME.on(username_tokens, S_AT_NAME);
|
||||
S_AT.on(usernameTokens, S_AT_NAME);
|
||||
S_AT_NAME.on(usernameTokens, S_AT_NAME);
|
||||
S_AT_NAME.on(TT.DOMAIN, S_AT_NAME);
|
||||
|
||||
S_AT_NAME.on(TT.COLON, S_AT_NAME_COLON);
|
||||
|
@ -138,7 +138,7 @@ function matrixLinkify(linkify) {
|
|||
const S_GROUPID_COLON = new linkify.parser.State();
|
||||
const S_GROUPID_COLON_NUM = new linkify.parser.State(GROUPID);
|
||||
|
||||
const groupid_tokens = [
|
||||
const groupIdTokens = [
|
||||
TT.DOT,
|
||||
TT.UNDERSCORE,
|
||||
TT.PLUS,
|
||||
|
@ -146,12 +146,12 @@ function matrixLinkify(linkify) {
|
|||
TT.DOMAIN,
|
||||
TT.TLD,
|
||||
|
||||
// as in roomname_tokens
|
||||
// as in roomnameTokens
|
||||
TT.LOCALHOST,
|
||||
];
|
||||
|
||||
S_PLUS.on(groupid_tokens, S_PLUS_NAME);
|
||||
S_PLUS_NAME.on(groupid_tokens, S_PLUS_NAME);
|
||||
S_PLUS.on(groupIdTokens, S_PLUS_NAME);
|
||||
S_PLUS_NAME.on(groupIdTokens, S_PLUS_NAME);
|
||||
S_PLUS_NAME.on(TT.DOMAIN, S_PLUS_NAME);
|
||||
|
||||
S_PLUS_NAME.on(TT.COLON, S_PLUS_NAME_COLON);
|
||||
|
@ -179,14 +179,14 @@ const escapeRegExp = function(string) {
|
|||
|
||||
// Recognise URLs from both our local vector and official vector as vector.
|
||||
// anyone else really should be using matrix.to.
|
||||
matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?:\/\/)?(?:"
|
||||
matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?://)?(?:"
|
||||
+ escapeRegExp(window.location.host + window.location.pathname) + "|"
|
||||
+ "(?:www\\.)?(?:riot|vector)\\.im/(?:app|beta|staging|develop)/"
|
||||
+ ")(#.*)";
|
||||
|
||||
matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/(([#@!+]).*)";
|
||||
matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?://)?(?:www\\.)?matrix\\.to/#/(([#@!+]).*)";
|
||||
matrixLinkify.MATRIXTO_MD_LINK_PATTERN =
|
||||
'\\[([^\\]]*)\\]\\((?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/([#@!+][^\\)]*)\\)';
|
||||
'\\[([^\\]]*)\\]\\((?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!+][^\\)]*)\\)';
|
||||
matrixLinkify.MATRIXTO_BASE_URL= baseUrl;
|
||||
|
||||
const matrixToEntityMap = {
|
||||
|
|
|
@ -284,6 +284,14 @@ export const SETTINGS = {
|
|||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||
default: 200,
|
||||
},
|
||||
"readMarkerInViewThresholdMs": {
|
||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||
default: 3000,
|
||||
},
|
||||
"readMarkerOutOfViewThresholdMs": {
|
||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||
default: 30000,
|
||||
},
|
||||
"blacklistUnverifiedDevices": {
|
||||
// We specifically want to have room-device > device so that users may set a device default
|
||||
// with a per-room override.
|
||||
|
|
|
@ -327,7 +327,7 @@ class RoomListStore extends Store {
|
|||
} else if (tags.length === 0) {
|
||||
tags.push("im.vector.fake.recent");
|
||||
}
|
||||
} else {
|
||||
} else if (myMembership) { // null-guard as null means it was peeked
|
||||
tags.push("im.vector.fake.archived");
|
||||
}
|
||||
|
||||
|
|
|
@ -100,11 +100,14 @@ export default class WidgetUtils {
|
|||
}
|
||||
|
||||
const testUrl = url.parse(testUrlString);
|
||||
|
||||
let scalarUrls = SdkConfig.get().integrations_widgets_urls;
|
||||
if (!scalarUrls || scalarUrls.length === 0) {
|
||||
const defaultManager = IntegrationManagers.sharedInstance().getPrimaryManager();
|
||||
if (defaultManager) scalarUrls = [defaultManager.apiUrl];
|
||||
if (defaultManager) {
|
||||
scalarUrls = [defaultManager.apiUrl];
|
||||
} else {
|
||||
scalarUrls = [];
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < scalarUrls.length; i++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue