Fix merge conflict
This commit is contained in:
commit
a96169e80e
74 changed files with 506 additions and 438 deletions
13
.eslintrc.js
13
.eslintrc.js
|
@ -40,6 +40,19 @@ module.exports = {
|
||||||
}],
|
}],
|
||||||
"react/jsx-key": ["error"],
|
"react/jsx-key": ["error"],
|
||||||
|
|
||||||
|
// Assert no spacing in JSX curly brackets
|
||||||
|
// <Element prop={ consideredError} prop={notConsideredError} />
|
||||||
|
//
|
||||||
|
// https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md
|
||||||
|
"react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}],
|
||||||
|
|
||||||
|
// Assert spacing before self-closing JSX tags, and no spacing before or
|
||||||
|
// after the closing slash, and no spacing after the opening bracket of
|
||||||
|
// the opening tag or closing tag.
|
||||||
|
//
|
||||||
|
// https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-tag-spacing.md
|
||||||
|
"react/jsx-tag-spacing": ["error"],
|
||||||
|
|
||||||
/** flowtype **/
|
/** flowtype **/
|
||||||
"flowtype/require-parameter-type": ["warn", {
|
"flowtype/require-parameter-type": ["warn", {
|
||||||
"excludeArrowFunctions": true,
|
"excludeArrowFunctions": true,
|
||||||
|
|
|
@ -21,9 +21,7 @@ npm run test -- --no-colors
|
||||||
npm run lintall -- -f checkstyle -o eslint.xml || true
|
npm run lintall -- -f checkstyle -o eslint.xml || true
|
||||||
|
|
||||||
# re-run the linter, excluding any files known to have errors or warnings.
|
# re-run the linter, excluding any files known to have errors or warnings.
|
||||||
./node_modules/.bin/eslint --max-warnings 0 \
|
npm run lintwithexclusions
|
||||||
--ignore-path .eslintignore.errorfiles \
|
|
||||||
src test
|
|
||||||
|
|
||||||
# delete the old tarball, if it exists
|
# delete the old tarball, if it exists
|
||||||
rm -f matrix-react-sdk-*.tgz
|
rm -f matrix-react-sdk-*.tgz
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
"start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"",
|
"start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"",
|
||||||
"lint": "eslint src/",
|
"lint": "eslint src/",
|
||||||
"lintall": "eslint src/ test/",
|
"lintall": "eslint src/ test/",
|
||||||
|
"lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test",
|
||||||
"clean": "rimraf lib",
|
"clean": "rimraf lib",
|
||||||
"prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt",
|
"prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt",
|
||||||
"test": "karma start --single-run=true --browsers ChromeHeadless",
|
"test": "karma start --single-run=true --browsers ChromeHeadless",
|
||||||
|
@ -99,7 +100,7 @@
|
||||||
"eslint-config-google": "^0.7.1",
|
"eslint-config-google": "^0.7.1",
|
||||||
"eslint-plugin-babel": "^4.0.1",
|
"eslint-plugin-babel": "^4.0.1",
|
||||||
"eslint-plugin-flowtype": "^2.30.0",
|
"eslint-plugin-flowtype": "^2.30.0",
|
||||||
"eslint-plugin-react": "^6.9.0",
|
"eslint-plugin-react": "^7.4.0",
|
||||||
"expect": "^1.16.0",
|
"expect": "^1.16.0",
|
||||||
"json-loader": "^0.5.3",
|
"json-loader": "^0.5.3",
|
||||||
"karma": "^1.7.0",
|
"karma": "^1.7.0",
|
||||||
|
|
|
@ -6,6 +6,4 @@ npm run test
|
||||||
./.travis-test-riot.sh
|
./.travis-test-riot.sh
|
||||||
|
|
||||||
# run the linter, but exclude any files known to have errors or warnings.
|
# run the linter, but exclude any files known to have errors or warnings.
|
||||||
./node_modules/.bin/eslint --max-warnings 0 \
|
npm run lintwithexclusions
|
||||||
--ignore-path .eslintignore.errorfiles \
|
|
||||||
src test
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ export function showGroupInviteDialog(groupId) {
|
||||||
description: _t("Who would you like to add to this group?"),
|
description: _t("Who would you like to add to this group?"),
|
||||||
placeholder: _t("Name or matrix ID"),
|
placeholder: _t("Name or matrix ID"),
|
||||||
button: _t("Invite to Group"),
|
button: _t("Invite to Group"),
|
||||||
validAddressTypes: ['mx'],
|
validAddressTypes: ['mx-user-id'],
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export function showGroupAddRoomDialog(groupId) {
|
||||||
placeholder: _t("Room name or alias"),
|
placeholder: _t("Room name or alias"),
|
||||||
button: _t("Add to group"),
|
button: _t("Add to group"),
|
||||||
pickerType: 'room',
|
pickerType: 'room',
|
||||||
validAddressTypes: ['mx'],
|
validAddressTypes: ['mx-room-id'],
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ export function inviteToRoom(roomId, addr) {
|
||||||
|
|
||||||
if (addrType == 'email') {
|
if (addrType == 'email') {
|
||||||
return MatrixClientPeg.get().inviteByEmail(roomId, addr);
|
return MatrixClientPeg.get().inviteByEmail(roomId, addr);
|
||||||
} else if (addrType == 'mx') {
|
} else if (addrType == 'mx-user-id') {
|
||||||
return MatrixClientPeg.get().invite(roomId, addr);
|
return MatrixClientPeg.get().invite(roomId, addr);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unsupported address');
|
throw new Error('Unsupported address');
|
||||||
|
|
|
@ -254,7 +254,7 @@ const commands = {
|
||||||
title: _t("Ignored user"),
|
title: _t("Ignored user"),
|
||||||
description: (
|
description: (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t("You are now ignoring %(userId)s", {userId: userId})}</p>
|
<p>{ _t("You are now ignoring %(userId)s", {userId: userId}) }</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
hasCancelButton: false,
|
hasCancelButton: false,
|
||||||
|
@ -281,7 +281,7 @@ const commands = {
|
||||||
title: _t("Unignored user"),
|
title: _t("Unignored user"),
|
||||||
description: (
|
description: (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t("You are no longer ignoring %(userId)s", {userId: userId})}</p>
|
<p>{ _t("You are no longer ignoring %(userId)s", {userId: userId}) }</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
hasCancelButton: false,
|
hasCancelButton: false,
|
||||||
|
|
|
@ -16,11 +16,12 @@ limitations under the License.
|
||||||
|
|
||||||
const emailRegex = /^\S+@\S+\.\S+$/;
|
const emailRegex = /^\S+@\S+\.\S+$/;
|
||||||
|
|
||||||
const mxidRegex = /^@\S+:\S+$/;
|
const mxUserIdRegex = /^@\S+:\S+$/;
|
||||||
|
const mxRoomIdRegex = /^!\S+:\S+$/;
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
export const addressTypes = [
|
export const addressTypes = [
|
||||||
'mx', 'email',
|
'mx-user-id', 'mx-room-id', 'email',
|
||||||
];
|
];
|
||||||
|
|
||||||
// PropType definition for an object describing
|
// PropType definition for an object describing
|
||||||
|
@ -41,13 +42,16 @@ export const UserAddressType = PropTypes.shape({
|
||||||
|
|
||||||
export function getAddressType(inputText) {
|
export function getAddressType(inputText) {
|
||||||
const isEmailAddress = emailRegex.test(inputText);
|
const isEmailAddress = emailRegex.test(inputText);
|
||||||
const isMatrixId = mxidRegex.test(inputText);
|
const isUserId = mxUserIdRegex.test(inputText);
|
||||||
|
const isRoomId = mxRoomIdRegex.test(inputText);
|
||||||
|
|
||||||
// sanity check the input for user IDs
|
// sanity check the input for user IDs
|
||||||
if (isEmailAddress) {
|
if (isEmailAddress) {
|
||||||
return 'email';
|
return 'email';
|
||||||
} else if (isMatrixId) {
|
} else if (isUserId) {
|
||||||
return 'mx';
|
return 'mx-user-id';
|
||||||
|
} else if (isRoomId) {
|
||||||
|
return 'mx-room-id';
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "-",
|
name: "-",
|
||||||
id: 'feature_flair',
|
id: 'feature_groups',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -43,7 +43,7 @@ export default {
|
||||||
// horrible but it works. The locality makes this somewhat more palatable.
|
// horrible but it works. The locality makes this somewhat more palatable.
|
||||||
doTranslations: function() {
|
doTranslations: function() {
|
||||||
this.LABS_FEATURES[0].name = _t("Matrix Apps");
|
this.LABS_FEATURES[0].name = _t("Matrix Apps");
|
||||||
this.LABS_FEATURES[1].name = _t("Flair");
|
this.LABS_FEATURES[1].name = _t("Groups");
|
||||||
},
|
},
|
||||||
|
|
||||||
loadProfileInfo: function() {
|
loadProfileInfo: function() {
|
||||||
|
|
|
@ -136,13 +136,13 @@ export default React.createClass({
|
||||||
) }
|
) }
|
||||||
</p>
|
</p>
|
||||||
<div className='error'>
|
<div className='error'>
|
||||||
{this.state.errStr}
|
{ this.state.errStr }
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputTable'>
|
<div className='mx_E2eKeysDialog_inputTable'>
|
||||||
<div className='mx_E2eKeysDialog_inputRow'>
|
<div className='mx_E2eKeysDialog_inputRow'>
|
||||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||||
<label htmlFor='passphrase1'>
|
<label htmlFor='passphrase1'>
|
||||||
{_t("Enter passphrase")}
|
{ _t("Enter passphrase") }
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputCell'>
|
<div className='mx_E2eKeysDialog_inputCell'>
|
||||||
|
@ -155,7 +155,7 @@ export default React.createClass({
|
||||||
<div className='mx_E2eKeysDialog_inputRow'>
|
<div className='mx_E2eKeysDialog_inputRow'>
|
||||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||||
<label htmlFor='passphrase2'>
|
<label htmlFor='passphrase2'>
|
||||||
{_t("Confirm passphrase")}
|
{ _t("Confirm passphrase") }
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputCell'>
|
<div className='mx_E2eKeysDialog_inputCell'>
|
||||||
|
@ -172,7 +172,7 @@ export default React.createClass({
|
||||||
disabled={disableForm}
|
disabled={disableForm}
|
||||||
/>
|
/>
|
||||||
<button onClick={this._onCancelClick} disabled={disableForm}>
|
<button onClick={this._onCancelClick} disabled={disableForm}>
|
||||||
{_t("Cancel")}
|
{ _t("Cancel") }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -134,13 +134,13 @@ export default React.createClass({
|
||||||
) }
|
) }
|
||||||
</p>
|
</p>
|
||||||
<div className='error'>
|
<div className='error'>
|
||||||
{this.state.errStr}
|
{ this.state.errStr }
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputTable'>
|
<div className='mx_E2eKeysDialog_inputTable'>
|
||||||
<div className='mx_E2eKeysDialog_inputRow'>
|
<div className='mx_E2eKeysDialog_inputRow'>
|
||||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||||
<label htmlFor='importFile'>
|
<label htmlFor='importFile'>
|
||||||
{_t("File to import")}
|
{ _t("File to import") }
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputCell'>
|
<div className='mx_E2eKeysDialog_inputCell'>
|
||||||
|
@ -153,14 +153,14 @@ export default React.createClass({
|
||||||
<div className='mx_E2eKeysDialog_inputRow'>
|
<div className='mx_E2eKeysDialog_inputRow'>
|
||||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||||
<label htmlFor='passphrase'>
|
<label htmlFor='passphrase'>
|
||||||
{_t("Enter passphrase")}
|
{ _t("Enter passphrase") }
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_E2eKeysDialog_inputCell'>
|
<div className='mx_E2eKeysDialog_inputCell'>
|
||||||
<input ref='passphrase' id='passphrase'
|
<input ref='passphrase' id='passphrase'
|
||||||
size='64' type='password'
|
size='64' type='password'
|
||||||
onChange={this._onFormChange}
|
onChange={this._onFormChange}
|
||||||
disabled={disableForm}/>
|
disabled={disableForm} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -170,7 +170,7 @@ export default React.createClass({
|
||||||
disabled={!this.state.enableSubmit || disableForm}
|
disabled={!this.state.enableSubmit || disableForm}
|
||||||
/>
|
/>
|
||||||
<button onClick={this._onCancelClick} disabled={disableForm}>
|
<button onClick={this._onCancelClick} disabled={disableForm}>
|
||||||
{_t("Cancel")}
|
{ _t("Cancel") }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -129,7 +129,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
||||||
component: (<TextualCompletion
|
component: (<TextualCompletion
|
||||||
title={result.command}
|
title={result.command}
|
||||||
subtitle={result.args}
|
subtitle={result.args}
|
||||||
description={ _t(result.description) }
|
description={_t(result.description)}
|
||||||
/>),
|
/>),
|
||||||
range,
|
range,
|
||||||
};
|
};
|
||||||
|
@ -150,7 +150,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||||
return <div className="mx_Autocomplete_Completion_container_block">
|
return <div className="mx_Autocomplete_Completion_container_block">
|
||||||
{completions}
|
{ completions }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||||
return <div className="mx_Autocomplete_Completion_container_pill mx_Autocomplete_Completion_container_truncate">
|
return <div className="mx_Autocomplete_Completion_container_pill mx_Autocomplete_Completion_container_truncate">
|
||||||
{completions}
|
{ completions }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ const CategoryRoomList = React.createClass({
|
||||||
placeholder: _t("Room name or alias"),
|
placeholder: _t("Room name or alias"),
|
||||||
button: _t("Add to summary"),
|
button: _t("Add to summary"),
|
||||||
pickerType: 'room',
|
pickerType: 'room',
|
||||||
validAddressTypes: ['mx'],
|
validAddressTypes: ['mx-room-id'],
|
||||||
groupId: this.props.groupId,
|
groupId: this.props.groupId,
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
|
@ -106,9 +106,9 @@ const CategoryRoomList = React.createClass({
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
const addButton = this.props.editing ?
|
const addButton = this.props.editing ?
|
||||||
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddRoomsClicked}>
|
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddRoomsClicked}>
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="64" height="64"/>
|
<TintableSvg src="img/icons-create-room.svg" width="64" height="64" />
|
||||||
<div className="mx_GroupView_featuredThings_addButton_label">
|
<div className="mx_GroupView_featuredThings_addButton_label">
|
||||||
{_t('Add a Room')}
|
{ _t('Add a Room') }
|
||||||
</div>
|
</div>
|
||||||
</AccessibleButton>) : <div />;
|
</AccessibleButton>) : <div />;
|
||||||
|
|
||||||
|
@ -117,17 +117,19 @@ const CategoryRoomList = React.createClass({
|
||||||
key={r.room_id}
|
key={r.room_id}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
editing={this.props.editing}
|
editing={this.props.editing}
|
||||||
summaryInfo={r}/>;
|
summaryInfo={r} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
let catHeader = <div />;
|
let catHeader = <div />;
|
||||||
if (this.props.category && this.props.category.profile) {
|
if (this.props.category && this.props.category.profile) {
|
||||||
catHeader = <div className="mx_GroupView_featuredThings_category">{this.props.category.profile.name}</div>;
|
catHeader = <div className="mx_GroupView_featuredThings_category">
|
||||||
|
{ this.props.category.profile.name }
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
return <div className="mx_GroupView_featuredThings_container">
|
return <div className="mx_GroupView_featuredThings_container">
|
||||||
{catHeader}
|
{ catHeader }
|
||||||
{roomNodes}
|
{ roomNodes }
|
||||||
{addButton}
|
{ addButton }
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -179,20 +181,26 @@ const FeaturedRoom = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
||||||
|
|
||||||
|
const roomName = this.props.summaryInfo.profile.name ||
|
||||||
|
this.props.summaryInfo.profile.canonical_alias ||
|
||||||
|
_t("Unnamed Room");
|
||||||
|
|
||||||
const oobData = {
|
const oobData = {
|
||||||
roomId: this.props.summaryInfo.room_id,
|
roomId: this.props.summaryInfo.room_id,
|
||||||
avatarUrl: this.props.summaryInfo.profile.avatar_url,
|
avatarUrl: this.props.summaryInfo.profile.avatar_url,
|
||||||
name: this.props.summaryInfo.profile.name,
|
name: roomName,
|
||||||
};
|
};
|
||||||
|
|
||||||
let permalink = null;
|
let permalink = null;
|
||||||
if (this.props.summaryInfo.profile && this.props.summaryInfo.profile.canonical_alias) {
|
if (this.props.summaryInfo.profile && this.props.summaryInfo.profile.canonical_alias) {
|
||||||
permalink = 'https://matrix.to/#/' + this.props.summaryInfo.profile.canonical_alias;
|
permalink = 'https://matrix.to/#/' + this.props.summaryInfo.profile.canonical_alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
let roomNameNode = null;
|
let roomNameNode = null;
|
||||||
if (permalink) {
|
if (permalink) {
|
||||||
roomNameNode = <a href={permalink} onClick={this.onClick} >{this.props.summaryInfo.profile.name}</a>;
|
roomNameNode = <a href={permalink} onClick={this.onClick} >{ roomName }</a>;
|
||||||
} else {
|
} else {
|
||||||
roomNameNode = <span>{this.props.summaryInfo.profile.name}</span>;
|
roomNameNode = <span>{ roomName }</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteButton = this.props.editing ?
|
const deleteButton = this.props.editing ?
|
||||||
|
@ -202,13 +210,13 @@ const FeaturedRoom = React.createClass({
|
||||||
width="14"
|
width="14"
|
||||||
height="14"
|
height="14"
|
||||||
alt="Delete"
|
alt="Delete"
|
||||||
onClick={this.onDeleteClicked}/>
|
onClick={this.onDeleteClicked} />
|
||||||
: <div />;
|
: <div />;
|
||||||
|
|
||||||
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
||||||
<RoomAvatar oobData={oobData} width={64} height={64} />
|
<RoomAvatar oobData={oobData} width={64} height={64} />
|
||||||
<div className="mx_GroupView_featuredThing_name">{roomNameNode}</div>
|
<div className="mx_GroupView_featuredThing_name">{ roomNameNode }</div>
|
||||||
{deleteButton}
|
{ deleteButton }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -237,8 +245,9 @@ const RoleUserList = React.createClass({
|
||||||
description: _t("Who would you like to add to this summary?"),
|
description: _t("Who would you like to add to this summary?"),
|
||||||
placeholder: _t("Name or matrix ID"),
|
placeholder: _t("Name or matrix ID"),
|
||||||
button: _t("Add to summary"),
|
button: _t("Add to summary"),
|
||||||
validAddressTypes: ['mx'],
|
validAddressTypes: ['mx-user-id'],
|
||||||
groupId: this.props.groupId,
|
groupId: this.props.groupId,
|
||||||
|
shouldOmitSelf: false,
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
|
@ -271,9 +280,9 @@ const RoleUserList = React.createClass({
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
const addButton = this.props.editing ?
|
const addButton = this.props.editing ?
|
||||||
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddUsersClicked}>
|
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddUsersClicked}>
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="64" height="64"/>
|
<TintableSvg src="img/icons-create-room.svg" width="64" height="64" />
|
||||||
<div className="mx_GroupView_featuredThings_addButton_label">
|
<div className="mx_GroupView_featuredThings_addButton_label">
|
||||||
{_t('Add a User')}
|
{ _t('Add a User') }
|
||||||
</div>
|
</div>
|
||||||
</AccessibleButton>) : <div />;
|
</AccessibleButton>) : <div />;
|
||||||
const userNodes = this.props.users.map((u) => {
|
const userNodes = this.props.users.map((u) => {
|
||||||
|
@ -281,16 +290,16 @@ const RoleUserList = React.createClass({
|
||||||
key={u.user_id}
|
key={u.user_id}
|
||||||
summaryInfo={u}
|
summaryInfo={u}
|
||||||
editing={this.props.editing}
|
editing={this.props.editing}
|
||||||
groupId={this.props.groupId}/>;
|
groupId={this.props.groupId} />;
|
||||||
});
|
});
|
||||||
let roleHeader = <div />;
|
let roleHeader = <div />;
|
||||||
if (this.props.role && this.props.role.profile) {
|
if (this.props.role && this.props.role.profile) {
|
||||||
roleHeader = <div className="mx_GroupView_featuredThings_category">{this.props.role.profile.name}</div>;
|
roleHeader = <div className="mx_GroupView_featuredThings_category">{ this.props.role.profile.name }</div>;
|
||||||
}
|
}
|
||||||
return <div className="mx_GroupView_featuredThings_container">
|
return <div className="mx_GroupView_featuredThings_container">
|
||||||
{roleHeader}
|
{ roleHeader }
|
||||||
{userNodes}
|
{ userNodes }
|
||||||
{addButton}
|
{ addButton }
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -342,7 +351,7 @@ const FeaturedUser = React.createClass({
|
||||||
const name = this.props.summaryInfo.displayname || this.props.summaryInfo.user_id;
|
const name = this.props.summaryInfo.displayname || this.props.summaryInfo.user_id;
|
||||||
|
|
||||||
const permalink = 'https://matrix.to/#/' + this.props.summaryInfo.user_id;
|
const permalink = 'https://matrix.to/#/' + this.props.summaryInfo.user_id;
|
||||||
const userNameNode = <a href={permalink} onClick={this.onClick}>{name}</a>;
|
const userNameNode = <a href={permalink} onClick={this.onClick}>{ name }</a>;
|
||||||
const httpUrl = MatrixClientPeg.get()
|
const httpUrl = MatrixClientPeg.get()
|
||||||
.mxcUrlToHttp(this.props.summaryInfo.avatar_url, 64, 64);
|
.mxcUrlToHttp(this.props.summaryInfo.avatar_url, 64, 64);
|
||||||
|
|
||||||
|
@ -353,13 +362,13 @@ const FeaturedUser = React.createClass({
|
||||||
width="14"
|
width="14"
|
||||||
height="14"
|
height="14"
|
||||||
alt="Delete"
|
alt="Delete"
|
||||||
onClick={this.onDeleteClicked}/>
|
onClick={this.onDeleteClicked} />
|
||||||
: <div />;
|
: <div />;
|
||||||
|
|
||||||
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
||||||
<BaseAvatar name={name} url={httpUrl} width={64} height={64} />
|
<BaseAvatar name={name} url={httpUrl} width={64} height={64} />
|
||||||
<div className="mx_GroupView_featuredThing_name">{userNameNode}</div>
|
<div className="mx_GroupView_featuredThing_name">{ userNameNode }</div>
|
||||||
{deleteButton}
|
{ deleteButton }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -625,7 +634,7 @@ export default React.createClass({
|
||||||
const defaultCategoryNode = <CategoryRoomList
|
const defaultCategoryNode = <CategoryRoomList
|
||||||
rooms={defaultCategoryRooms}
|
rooms={defaultCategoryRooms}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
editing={this.state.editing}/>;
|
editing={this.state.editing} />;
|
||||||
const categoryRoomNodes = Object.keys(categoryRooms).map((catId) => {
|
const categoryRoomNodes = Object.keys(categoryRooms).map((catId) => {
|
||||||
const cat = summary.rooms_section.categories[catId];
|
const cat = summary.rooms_section.categories[catId];
|
||||||
return <CategoryRoomList
|
return <CategoryRoomList
|
||||||
|
@ -633,15 +642,15 @@ export default React.createClass({
|
||||||
rooms={categoryRooms[catId]}
|
rooms={categoryRooms[catId]}
|
||||||
category={cat}
|
category={cat}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
editing={this.state.editing}/>;
|
editing={this.state.editing} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
return <div className="mx_GroupView_featuredThings">
|
return <div className="mx_GroupView_featuredThings">
|
||||||
<div className="mx_GroupView_featuredThings_header">
|
<div className="mx_GroupView_featuredThings_header">
|
||||||
{_t('Featured Rooms:')}
|
{ _t('Featured Rooms:') }
|
||||||
</div>
|
</div>
|
||||||
{defaultCategoryNode}
|
{ defaultCategoryNode }
|
||||||
{categoryRoomNodes}
|
{ categoryRoomNodes }
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -666,7 +675,7 @@ export default React.createClass({
|
||||||
const noRoleNode = <RoleUserList
|
const noRoleNode = <RoleUserList
|
||||||
users={noRoleUsers}
|
users={noRoleUsers}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
editing={this.state.editing}/>;
|
editing={this.state.editing} />;
|
||||||
const roleUserNodes = Object.keys(roleUsers).map((roleId) => {
|
const roleUserNodes = Object.keys(roleUsers).map((roleId) => {
|
||||||
const role = summary.users_section.roles[roleId];
|
const role = summary.users_section.roles[roleId];
|
||||||
return <RoleUserList
|
return <RoleUserList
|
||||||
|
@ -674,15 +683,15 @@ export default React.createClass({
|
||||||
users={roleUsers[roleId]}
|
users={roleUsers[roleId]}
|
||||||
role={role}
|
role={role}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
editing={this.state.editing}/>;
|
editing={this.state.editing} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
return <div className="mx_GroupView_featuredThings">
|
return <div className="mx_GroupView_featuredThings">
|
||||||
<div className="mx_GroupView_featuredThings_header">
|
<div className="mx_GroupView_featuredThings_header">
|
||||||
{_t('Featured Users:')}
|
{ _t('Featured Users:') }
|
||||||
</div>
|
</div>
|
||||||
{noRoleNode}
|
{ noRoleNode }
|
||||||
{roleUserNodes}
|
{ roleUserNodes }
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -701,18 +710,18 @@ export default React.createClass({
|
||||||
|
|
||||||
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_invited">
|
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_invited">
|
||||||
<div className="mx_GroupView_membershipSection_description">
|
<div className="mx_GroupView_membershipSection_description">
|
||||||
{_t("%(inviter)s has invited you to join this group", {inviter: group.inviter.userId})}
|
{ _t("%(inviter)s has invited you to join this group", {inviter: group.inviter.userId}) }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_membership_buttonContainer">
|
<div className="mx_GroupView_membership_buttonContainer">
|
||||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onAcceptInviteClick}
|
onClick={this._onAcceptInviteClick}
|
||||||
>
|
>
|
||||||
{_t("Accept")}
|
{ _t("Accept") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onRejectInviteClick}
|
onClick={this._onRejectInviteClick}
|
||||||
>
|
>
|
||||||
{_t("Decline")}
|
{ _t("Decline") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -733,13 +742,13 @@ export default React.createClass({
|
||||||
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onPubliciseOffClick}
|
onClick={this._onPubliciseOffClick}
|
||||||
>
|
>
|
||||||
{_t("Unpublish")}
|
{ _t("Unpublish") }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
publicisedSection = <div className="mx_GroupView_membershipSubSection">
|
publicisedSection = <div className="mx_GroupView_membershipSubSection">
|
||||||
{_t("This group is published on your profile")}
|
{ _t("This group is published on your profile") }
|
||||||
<div className="mx_GroupView_membership_buttonContainer">
|
<div className="mx_GroupView_membership_buttonContainer">
|
||||||
{publicisedButton}
|
{ publicisedButton }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
|
@ -747,13 +756,13 @@ export default React.createClass({
|
||||||
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onPubliciseOnClick}
|
onClick={this._onPubliciseOnClick}
|
||||||
>
|
>
|
||||||
{_t("Publish")}
|
{ _t("Publish") }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
publicisedSection = <div className="mx_GroupView_membershipSubSection">
|
publicisedSection = <div className="mx_GroupView_membershipSubSection">
|
||||||
{_t("This group is not published on your profile")}
|
{ _t("This group is not published on your profile") }
|
||||||
<div className="mx_GroupView_membership_buttonContainer">
|
<div className="mx_GroupView_membership_buttonContainer">
|
||||||
{publicisedButton}
|
{ publicisedButton }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
@ -761,17 +770,17 @@ export default React.createClass({
|
||||||
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_joined">
|
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_joined">
|
||||||
<div className="mx_GroupView_membershipSubSection">
|
<div className="mx_GroupView_membershipSubSection">
|
||||||
<div className="mx_GroupView_membershipSection_description">
|
<div className="mx_GroupView_membershipSection_description">
|
||||||
{youAreAMemberText}
|
{ youAreAMemberText }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_membership_buttonContainer">
|
<div className="mx_GroupView_membership_buttonContainer">
|
||||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onLeaveClick}
|
onClick={this._onLeaveClick}
|
||||||
>
|
>
|
||||||
{_t("Leave")}
|
{ _t("Leave") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{publicisedSection}
|
{ publicisedSection }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,15 +820,15 @@ export default React.createClass({
|
||||||
avatarNode = (
|
avatarNode = (
|
||||||
<div className="mx_GroupView_avatarPicker">
|
<div className="mx_GroupView_avatarPicker">
|
||||||
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
||||||
{avatarImage}
|
{ avatarImage }
|
||||||
</label>
|
</label>
|
||||||
<div className="mx_GroupView_avatarPicker_edit">
|
<div className="mx_GroupView_avatarPicker_edit">
|
||||||
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
||||||
<img src="img/camera.svg"
|
<img src="img/camera.svg"
|
||||||
alt={ _t("Upload avatar") } title={ _t("Upload avatar") }
|
alt={_t("Upload avatar")} title={_t("Upload avatar")}
|
||||||
width="17" height="15" />
|
width="17" height="15" />
|
||||||
</label>
|
</label>
|
||||||
<input id="avatarInput" className="mx_GroupView_uploadInput" type="file" onChange={this._onAvatarSelected}/>
|
<input id="avatarInput" className="mx_GroupView_uploadInput" type="file" onChange={this._onAvatarSelected} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -839,13 +848,13 @@ export default React.createClass({
|
||||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
onClick={this._onSaveClick} key="_saveButton"
|
onClick={this._onSaveClick} key="_saveButton"
|
||||||
>
|
>
|
||||||
{_t('Save')}
|
{ _t('Save') }
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
);
|
);
|
||||||
rightButtons.push(
|
rightButtons.push(
|
||||||
<AccessibleButton className='mx_GroupView_textButton' onClick={this._onCancelClick} key="_cancelButton">
|
<AccessibleButton className="mx_RoomHeader_cancelButton" onClick={this._onCancelClick} key="_cancelButton">
|
||||||
<img src="img/cancel.svg" className='mx_filterFlipColor'
|
<img src="img/cancel.svg" className="mx_filterFlipColor"
|
||||||
width="18" height="18" alt={_t("Cancel")}/>
|
width="18" height="18" alt={_t("Cancel")} />
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
);
|
);
|
||||||
roomBody = <div>
|
roomBody = <div>
|
||||||
|
@ -853,8 +862,8 @@ export default React.createClass({
|
||||||
onChange={this._onLongDescChange}
|
onChange={this._onLongDescChange}
|
||||||
tabIndex="3"
|
tabIndex="3"
|
||||||
/>
|
/>
|
||||||
{this._getFeaturedRoomsNode()}
|
{ this._getFeaturedRoomsNode() }
|
||||||
{this._getFeaturedUsersNode()}
|
{ this._getFeaturedUsersNode() }
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
const groupAvatarUrl = summary.profile ? summary.profile.avatar_url : null;
|
const groupAvatarUrl = summary.profile ? summary.profile.avatar_url : null;
|
||||||
|
@ -865,41 +874,41 @@ export default React.createClass({
|
||||||
/>;
|
/>;
|
||||||
if (summary.profile && summary.profile.name) {
|
if (summary.profile && summary.profile.name) {
|
||||||
nameNode = <div>
|
nameNode = <div>
|
||||||
<span>{summary.profile.name}</span>
|
<span>{ summary.profile.name }</span>
|
||||||
<span className="mx_GroupView_header_groupid">
|
<span className="mx_GroupView_header_groupid">
|
||||||
({this.props.groupId})
|
({ this.props.groupId })
|
||||||
</span>
|
</span>
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
nameNode = <span>{this.props.groupId}</span>;
|
nameNode = <span>{ this.props.groupId }</span>;
|
||||||
}
|
}
|
||||||
shortDescNode = <span>{summary.profile.short_description}</span>;
|
shortDescNode = <span>{ summary.profile.short_description }</span>;
|
||||||
|
|
||||||
let description = null;
|
let description = null;
|
||||||
if (summary.profile && summary.profile.long_description) {
|
if (summary.profile && summary.profile.long_description) {
|
||||||
description = sanitizedHtmlNode(summary.profile.long_description);
|
description = sanitizedHtmlNode(summary.profile.long_description);
|
||||||
}
|
}
|
||||||
roomBody = <div>
|
roomBody = <div>
|
||||||
{this._getMembershipSection()}
|
{ this._getMembershipSection() }
|
||||||
<div className="mx_GroupView_groupDesc">{description}</div>
|
<div className="mx_GroupView_groupDesc">{ description }</div>
|
||||||
{this._getFeaturedRoomsNode()}
|
{ this._getFeaturedRoomsNode() }
|
||||||
{this._getFeaturedUsersNode()}
|
{ this._getFeaturedUsersNode() }
|
||||||
</div>;
|
</div>;
|
||||||
if (summary.user && summary.user.is_privileged) {
|
if (summary.user && summary.user.is_privileged) {
|
||||||
rightButtons.push(
|
rightButtons.push(
|
||||||
<AccessibleButton className="mx_GroupHeader_button"
|
<AccessibleButton className="mx_GroupHeader_button"
|
||||||
onClick={this._onEditClick} title={_t("Edit Group")} key="_editButton"
|
onClick={this._onEditClick} title={_t("Edit Group")} key="_editButton"
|
||||||
>
|
>
|
||||||
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
|
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16" />
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.props.collapsedRhs) {
|
if (this.props.collapsedRhs) {
|
||||||
rightButtons.push(
|
rightButtons.push(
|
||||||
<AccessibleButton className="mx_GroupHeader_button"
|
<AccessibleButton className="mx_GroupHeader_button"
|
||||||
onClick={this._onShowRhsClick} title={ _t('Show panel') } key="_maximiseButton"
|
onClick={this._onShowRhsClick} title={_t('Show panel')} key="_maximiseButton"
|
||||||
>
|
>
|
||||||
<TintableSvg src="img/maximise.svg" width="10" height="16"/>
|
<TintableSvg src="img/maximise.svg" width="10" height="16" />
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -912,40 +921,40 @@ export default React.createClass({
|
||||||
<div className={classnames(headerClasses)}>
|
<div className={classnames(headerClasses)}>
|
||||||
<div className="mx_GroupView_header_leftCol">
|
<div className="mx_GroupView_header_leftCol">
|
||||||
<div className="mx_GroupView_header_avatar">
|
<div className="mx_GroupView_header_avatar">
|
||||||
{avatarNode}
|
{ avatarNode }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_header_info">
|
<div className="mx_GroupView_header_info">
|
||||||
<div className="mx_GroupView_header_name">
|
<div className="mx_GroupView_header_name">
|
||||||
{nameNode}
|
{ nameNode }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_header_shortDesc">
|
<div className="mx_GroupView_header_shortDesc">
|
||||||
{shortDescNode}
|
{ shortDescNode }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_header_rightCol">
|
<div className="mx_GroupView_header_rightCol">
|
||||||
{rightButtons}
|
{ rightButtons }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{roomBody}
|
{ roomBody }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (this.state.error) {
|
} else if (this.state.error) {
|
||||||
if (this.state.error.httpStatus === 404) {
|
if (this.state.error.httpStatus === 404) {
|
||||||
return (
|
return (
|
||||||
<div className="mx_GroupView_error">
|
<div className="mx_GroupView_error">
|
||||||
Group {this.props.groupId} not found
|
Group { this.props.groupId } not found
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let extraText;
|
let extraText;
|
||||||
if (this.state.error.errcode === 'M_UNRECOGNIZED') {
|
if (this.state.error.errcode === 'M_UNRECOGNIZED') {
|
||||||
extraText = <div>{_t('This Home server does not support groups')}</div>;
|
extraText = <div>{ _t('This Home server does not support groups') }</div>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="mx_GroupView_error">
|
<div className="mx_GroupView_error">
|
||||||
Failed to load {this.props.groupId}
|
Failed to load { this.props.groupId }
|
||||||
{extraText}
|
{ extraText }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -853,7 +853,7 @@ module.exports = React.createClass({
|
||||||
title: _t("Leave room"),
|
title: _t("Leave room"),
|
||||||
description: (
|
description: (
|
||||||
<span>
|
<span>
|
||||||
{_t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name})}
|
{ _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) }
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
onFinished: (shouldLeave) => {
|
onFinished: (shouldLeave) => {
|
||||||
|
@ -1450,7 +1450,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixChat_splash">
|
<div className="mx_MatrixChat_splash">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
<a href="#" className="mx_MatrixChat_splashButtons" onClick={ this.onLogoutClick }>
|
<a href="#" className="mx_MatrixChat_splashButtons" onClick={this.onLogoutClick}>
|
||||||
{ _t('Logout') }
|
{ _t('Logout') }
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,7 +39,7 @@ const GroupTile = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return <a onClick={this.onClick} href="#">{this.props.groupId}</a>;
|
return <a onClick={this.onClick} href="#">{ this.props.groupId }</a>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,51 +90,51 @@ export default withMatrixClient(React.createClass({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
content = <div>
|
content = <div>
|
||||||
<div>{_t('You are a member of these groups:')}</div>
|
<div>{ _t('You are a member of these groups:') }</div>
|
||||||
{groupNodes}
|
{ groupNodes }
|
||||||
</div>;
|
</div>;
|
||||||
} else if (this.state.error) {
|
} else if (this.state.error) {
|
||||||
content = <div className="mx_MyGroups_error">
|
content = <div className="mx_MyGroups_error">
|
||||||
{_t('Error whilst fetching joined groups')}
|
{ _t('Error whilst fetching joined groups') }
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
content = <Loader />;
|
content = <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="mx_MyGroups">
|
return <div className="mx_MyGroups">
|
||||||
<SimpleRoomHeader title={ _t("Groups") } />
|
<SimpleRoomHeader title={_t("Groups")} icon="img/icons-groups.svg" />
|
||||||
<div className='mx_MyGroups_joinCreateBox'>
|
<div className='mx_MyGroups_joinCreateBox'>
|
||||||
<div className="mx_MyGroups_createBox">
|
<div className="mx_MyGroups_createBox">
|
||||||
<div className="mx_MyGroups_joinCreateHeader">
|
<div className="mx_MyGroups_joinCreateHeader">
|
||||||
{_t('Create a new group')}
|
{ _t('Create a new group') }
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onCreateGroupClick}>
|
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onCreateGroupClick}>
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
{_t(
|
{ _t(
|
||||||
'Create a group to represent your community! '+
|
'Create a group to represent your community! '+
|
||||||
'Define a set of rooms and your own custom homepage '+
|
'Define a set of rooms and your own custom homepage '+
|
||||||
'to mark out your space in the Matrix universe.',
|
'to mark out your space in the Matrix universe.',
|
||||||
)}
|
) }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MyGroups_joinBox">
|
<div className="mx_MyGroups_joinBox">
|
||||||
<div className="mx_MyGroups_joinCreateHeader">
|
<div className="mx_MyGroups_joinCreateHeader">
|
||||||
{_t('Join an existing group')}
|
{ _t('Join an existing group') }
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onJoinGroupClick}>
|
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onJoinGroupClick}>
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
{_tJsx(
|
{ _tJsx(
|
||||||
'To join an existing group you\'ll have to '+
|
'To join an existing group you\'ll have to '+
|
||||||
'know its group identifier; this will look '+
|
'know its group identifier; this will look '+
|
||||||
'something like <i>+example:matrix.org</i>.',
|
'something like <i>+example:matrix.org</i>.',
|
||||||
/<i>(.*)<\/i>/,
|
/<i>(.*)<\/i>/,
|
||||||
(sub) => <i>{sub}</i>,
|
(sub) => <i>{ sub }</i>,
|
||||||
)}
|
) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MyGroups_content">
|
<div className="mx_MyGroups_content">
|
||||||
{content}
|
{ content }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,7 +52,7 @@ const gHVersionLabel = function(repo, token='') {
|
||||||
} else {
|
} else {
|
||||||
url = `https://github.com/${repo}/commit/${token.split('-')[0]}`;
|
url = `https://github.com/${repo}/commit/${token.split('-')[0]}`;
|
||||||
}
|
}
|
||||||
return <a target="_blank" rel="noopener" href={url}>{token}</a>;
|
return <a target="_blank" rel="noopener" href={url}>{ token }</a>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enumerate some simple 'flip a bit' UI settings (if any).
|
// Enumerate some simple 'flip a bit' UI settings (if any).
|
||||||
|
@ -674,7 +674,7 @@ module.exports = React.createClass({
|
||||||
<div>
|
<div>
|
||||||
<h3>Referral</h3>
|
<h3>Referral</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
{_t("Refer a friend to Riot:")} <a href={href}>{href}</a>
|
{ _t("Refer a friend to Riot:") } <a href={href}>{ href }</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -693,7 +693,7 @@ module.exports = React.createClass({
|
||||||
_renderLanguageSetting: function() {
|
_renderLanguageSetting: function() {
|
||||||
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown');
|
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown');
|
||||||
return <div>
|
return <div>
|
||||||
<label htmlFor="languageSelector">{_t('Interface Language')}</label>
|
<label htmlFor="languageSelector">{ _t('Interface Language') }</label>
|
||||||
<LanguageDropdown ref="language" onOptionChange={this.onLanguageChange}
|
<LanguageDropdown ref="language" onOptionChange={this.onLanguageChange}
|
||||||
className="mx_UserSettings_language"
|
className="mx_UserSettings_language"
|
||||||
value={this.state.language}
|
value={this.state.language}
|
||||||
|
@ -716,7 +716,7 @@ module.exports = React.createClass({
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{_t('Autocomplete Delay (ms):')}</strong></td>
|
<td><strong>{ _t('Autocomplete Delay (ms):') }</strong></td>
|
||||||
<td>
|
<td>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -737,8 +737,8 @@ module.exports = React.createClass({
|
||||||
return <div className="mx_UserSettings_toggle">
|
return <div className="mx_UserSettings_toggle">
|
||||||
<input id="urlPreviewsDisabled"
|
<input id="urlPreviewsDisabled"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
defaultChecked={ UserSettingsStore.getUrlPreviewsDisabled() }
|
defaultChecked={UserSettingsStore.getUrlPreviewsDisabled()}
|
||||||
onChange={ this._onPreviewsDisabledChanged }
|
onChange={this._onPreviewsDisabledChanged}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="urlPreviewsDisabled">
|
<label htmlFor="urlPreviewsDisabled">
|
||||||
{ _t("Disable inline URL previews by default") }
|
{ _t("Disable inline URL previews by default") }
|
||||||
|
@ -759,13 +759,13 @@ module.exports = React.createClass({
|
||||||
if (setting.fn) setting.fn(e.target.checked);
|
if (setting.fn) setting.fn(e.target.checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
return <div className="mx_UserSettings_toggle" key={ setting.id }>
|
return <div className="mx_UserSettings_toggle" key={setting.id}>
|
||||||
<input id={ setting.id }
|
<input id={setting.id}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
defaultChecked={ this._syncedSettings[setting.id] }
|
defaultChecked={this._syncedSettings[setting.id]}
|
||||||
onChange={ onChange }
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<label htmlFor={ setting.id }>
|
<label htmlFor={setting.id}>
|
||||||
{ _t(setting.label) }
|
{ _t(setting.label) }
|
||||||
</label>
|
</label>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -784,15 +784,15 @@ module.exports = React.createClass({
|
||||||
value: setting.value,
|
value: setting.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return <div className="mx_UserSettings_toggle" key={ setting.id + "_" + setting.value }>
|
return <div className="mx_UserSettings_toggle" key={setting.id + "_" + setting.value}>
|
||||||
<input id={ setting.id + "_" + setting.value }
|
<input id={setting.id + "_" + setting.value}
|
||||||
type="radio"
|
type="radio"
|
||||||
name={ setting.id }
|
name={setting.id}
|
||||||
value={ setting.value }
|
value={setting.value}
|
||||||
checked={ this._syncedSettings[setting.id] === setting.value }
|
checked={this._syncedSettings[setting.id] === setting.value}
|
||||||
onChange={ onChange }
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<label htmlFor={ setting.id + "_" + setting.value }>
|
<label htmlFor={setting.id + "_" + setting.value}>
|
||||||
{ _t(setting.label) }
|
{ _t(setting.label) }
|
||||||
</label>
|
</label>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -829,10 +829,10 @@ module.exports = React.createClass({
|
||||||
<h3>{ _t("Cryptography") }</h3>
|
<h3>{ _t("Cryptography") }</h3>
|
||||||
<div className="mx_UserSettings_section mx_UserSettings_cryptoSection">
|
<div className="mx_UserSettings_section mx_UserSettings_cryptoSection">
|
||||||
<ul>
|
<ul>
|
||||||
<li><label>{_t("Device ID:")}</label>
|
<li><label>{ _t("Device ID:") }</label>
|
||||||
<span><code>{deviceId}</code></span></li>
|
<span><code>{ deviceId }</code></span></li>
|
||||||
<li><label>{_t("Device key:")}</label>
|
<li><label>{ _t("Device key:") }</label>
|
||||||
<span><code><b>{identityKey}</b></code></span></li>
|
<span><code><b>{ identityKey }</b></code></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
{ importExportButtons }
|
{ importExportButtons }
|
||||||
</div>
|
</div>
|
||||||
|
@ -851,11 +851,11 @@ module.exports = React.createClass({
|
||||||
<h3>{ _t("Ignored Users") }</h3>
|
<h3>{ _t("Ignored Users") }</h3>
|
||||||
<div className="mx_UserSettings_section mx_UserSettings_ignoredUsersSection">
|
<div className="mx_UserSettings_section mx_UserSettings_ignoredUsersSection">
|
||||||
<ul>
|
<ul>
|
||||||
{this.state.ignoredUsers.map(function(userId) {
|
{ this.state.ignoredUsers.map(function(userId) {
|
||||||
return (<IgnoredUser key={userId}
|
return (<IgnoredUser key={userId}
|
||||||
userId={userId}
|
userId={userId}
|
||||||
onUnignored={updateHandler}></IgnoredUser>);
|
onUnignored={updateHandler}></IgnoredUser>);
|
||||||
})}
|
}) }
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -871,13 +871,13 @@ module.exports = React.createClass({
|
||||||
if (setting.fn) setting.fn(e.target.checked);
|
if (setting.fn) setting.fn(e.target.checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
return <div className="mx_UserSettings_toggle" key={ setting.id }>
|
return <div className="mx_UserSettings_toggle" key={setting.id}>
|
||||||
<input id={ setting.id }
|
<input id={setting.id}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
defaultChecked={ this._localSettings[setting.id] }
|
defaultChecked={this._localSettings[setting.id]}
|
||||||
onChange={ onChange }
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<label htmlFor={ setting.id }>
|
<label htmlFor={setting.id}>
|
||||||
{ _t(setting.label) }
|
{ _t(setting.label) }
|
||||||
</label>
|
</label>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -887,8 +887,8 @@ module.exports = React.createClass({
|
||||||
const DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
const DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>{_t("Devices")}</h3>
|
<h3>{ _t("Devices") }</h3>
|
||||||
<DevicesPanel className="mx_UserSettings_section"/>
|
<DevicesPanel className="mx_UserSettings_section" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -903,7 +903,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<p>{ _t("Found a bug?") }</p>
|
<p>{ _t("Found a bug?") }</p>
|
||||||
<button className="mx_UserSettings_button danger"
|
<button className="mx_UserSettings_button danger"
|
||||||
onClick={this._onBugReportClicked}>{_t('Report it')}
|
onClick={this._onBugReportClicked}>{ _t('Report it') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -911,13 +911,13 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderAnalyticsControl: function() {
|
_renderAnalyticsControl: function() {
|
||||||
if (!SdkConfig.get().piwik) return <div/>;
|
if (!SdkConfig.get().piwik) return <div />;
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<h3>{ _t('Analytics') }</h3>
|
<h3>{ _t('Analytics') }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
{_t('Riot collects anonymous analytics to allow us to improve the application.')}
|
{ _t('Riot collects anonymous analytics to allow us to improve the application.') }
|
||||||
{ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting )}
|
{ ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting ) }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
@ -947,10 +947,10 @@ module.exports = React.createClass({
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={feature.id}
|
id={feature.id}
|
||||||
name={feature.id}
|
name={feature.id}
|
||||||
defaultChecked={ UserSettingsStore.isFeatureEnabled(feature.id) }
|
defaultChecked={UserSettingsStore.isFeatureEnabled(feature.id)}
|
||||||
onChange={ onChange }
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<label htmlFor={feature.id}>{feature.name}</label>
|
<label htmlFor={feature.id}>{ feature.name }</label>
|
||||||
</div>);
|
</div>);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ module.exports = React.createClass({
|
||||||
<h3>{ _t("Labs") }</h3>
|
<h3>{ _t("Labs") }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<p>{ _t("These are experimental features that may break in unexpected ways") }. { _t("Use with caution") }.</p>
|
<p>{ _t("These are experimental features that may break in unexpected ways") }. { _t("Use with caution") }.</p>
|
||||||
{features}
|
{ features }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -997,10 +997,10 @@ module.exports = React.createClass({
|
||||||
const platform = PlatformPeg.get();
|
const platform = PlatformPeg.get();
|
||||||
if ('canSelfUpdate' in platform && platform.canSelfUpdate() && 'startUpdateCheck' in platform) {
|
if ('canSelfUpdate' in platform && platform.canSelfUpdate() && 'startUpdateCheck' in platform) {
|
||||||
return <div>
|
return <div>
|
||||||
<h3>{_t('Updates')}</h3>
|
<h3>{ _t('Updates') }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<AccessibleButton className="mx_UserSettings_button" onClick={platform.startUpdateCheck}>
|
<AccessibleButton className="mx_UserSettings_button" onClick={platform.startUpdateCheck}>
|
||||||
{_t('Check for update')}
|
{ _t('Check for update') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -1026,7 +1026,7 @@ module.exports = React.createClass({
|
||||||
reject = (
|
reject = (
|
||||||
<AccessibleButton className="mx_UserSettings_button danger"
|
<AccessibleButton className="mx_UserSettings_button danger"
|
||||||
onClick={onClick}>
|
onClick={onClick}>
|
||||||
{_t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length})}
|
{ _t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length}) }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1034,7 @@ module.exports = React.createClass({
|
||||||
return <div>
|
return <div>
|
||||||
<h3>{ _t("Bulk Options") }</h3>
|
<h3>{ _t("Bulk Options") }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
{reject}
|
{ reject }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
@ -1052,7 +1052,7 @@ module.exports = React.createClass({
|
||||||
defaultChecked={settings['auto-launch']}
|
defaultChecked={settings['auto-launch']}
|
||||||
onChange={this._onAutoLaunchChanged}
|
onChange={this._onAutoLaunchChanged}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="auto-launch">{_t('Start automatically after system login')}</label>
|
<label htmlFor="auto-launch">{ _t('Start automatically after system login') }</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -1064,7 +1064,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_mapWebRtcDevicesToSpans: function(devices) {
|
_mapWebRtcDevicesToSpans: function(devices) {
|
||||||
return devices.map((device) => <span key={device.deviceId}>{device.label}</span>);
|
return devices.map((device) => <span key={device.deviceId}>{ device.label }</span>);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setAudioInput: function(deviceId) {
|
_setAudioInput: function(deviceId) {
|
||||||
|
@ -1100,15 +1100,15 @@ module.exports = React.createClass({
|
||||||
if (this.state.mediaDevices === false) {
|
if (this.state.mediaDevices === false) {
|
||||||
return (
|
return (
|
||||||
<p className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
<p className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
||||||
{_t('Missing Media Permissions, click here to request.')}
|
{ _t('Missing Media Permissions, click here to request.') }
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
} else if (!this.state.mediaDevices) return;
|
} else if (!this.state.mediaDevices) return;
|
||||||
|
|
||||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||||
|
|
||||||
let microphoneDropdown = <p>{_t('No Microphones detected')}</p>;
|
let microphoneDropdown = <p>{ _t('No Microphones detected') }</p>;
|
||||||
let webcamDropdown = <p>{_t('No Webcams detected')}</p>;
|
let webcamDropdown = <p>{ _t('No Webcams detected') }</p>;
|
||||||
|
|
||||||
const defaultOption = {
|
const defaultOption = {
|
||||||
deviceId: '',
|
deviceId: '',
|
||||||
|
@ -1125,12 +1125,12 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
microphoneDropdown = <div>
|
microphoneDropdown = <div>
|
||||||
<h4>{_t('Microphone')}</h4>
|
<h4>{ _t('Microphone') }</h4>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||||
value={this.state.activeAudioInput || defaultInput}
|
value={this.state.activeAudioInput || defaultInput}
|
||||||
onOptionChange={this._setAudioInput}>
|
onOptionChange={this._setAudioInput}>
|
||||||
{this._mapWebRtcDevicesToSpans(audioInputs)}
|
{ this._mapWebRtcDevicesToSpans(audioInputs) }
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
@ -1145,25 +1145,25 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
webcamDropdown = <div>
|
webcamDropdown = <div>
|
||||||
<h4>{_t('Camera')}</h4>
|
<h4>{ _t('Camera') }</h4>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||||
value={this.state.activeVideoInput || defaultInput}
|
value={this.state.activeVideoInput || defaultInput}
|
||||||
onOptionChange={this._setVideoInput}>
|
onOptionChange={this._setVideoInput}>
|
||||||
{this._mapWebRtcDevicesToSpans(videoInputs)}
|
{ this._mapWebRtcDevicesToSpans(videoInputs) }
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{microphoneDropdown}
|
{ microphoneDropdown }
|
||||||
{webcamDropdown}
|
{ webcamDropdown }
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderWebRtcSettings: function() {
|
_renderWebRtcSettings: function() {
|
||||||
return <div>
|
return <div>
|
||||||
<h3>{_t('VoIP')}</h3>
|
<h3>{ _t('VoIP') }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
{ WEBRTC_SETTINGS_LABELS.map(this._renderLocalSetting) }
|
{ WEBRTC_SETTINGS_LABELS.map(this._renderLocalSetting) }
|
||||||
{ this._renderWebRtcDeviceSettings() }
|
{ this._renderWebRtcDeviceSettings() }
|
||||||
|
@ -1229,7 +1229,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_UserSettings_profileTableRow" key={pidIndex}>
|
<div className="mx_UserSettings_profileTableRow" key={pidIndex}>
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
<label htmlFor={id}>{this.nameForMedium(val.medium)}</label>
|
<label htmlFor={id}>{ this.nameForMedium(val.medium) }</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
<input type="text" key={val.address} id={id}
|
<input type="text" key={val.address} id={id}
|
||||||
|
@ -1237,7 +1237,7 @@ module.exports = React.createClass({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||||
<img src="img/cancel-small.svg" width="14" height="14" alt={ _t("Remove") }
|
<img src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")}
|
||||||
onClick={onRemoveClick} />
|
onClick={onRemoveClick} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1250,16 +1250,16 @@ module.exports = React.createClass({
|
||||||
addEmailSection = (
|
addEmailSection = (
|
||||||
<div className="mx_UserSettings_profileTableRow" key="_newEmail">
|
<div className="mx_UserSettings_profileTableRow" key="_newEmail">
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
<label>{_t('Email')}</label>
|
<label>{ _t('Email') }</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
<EditableText
|
<EditableText
|
||||||
ref="add_email_input"
|
ref="add_email_input"
|
||||||
className="mx_UserSettings_editable"
|
className="mx_UserSettings_editable"
|
||||||
placeholderClassName="mx_UserSettings_threepidPlaceholder"
|
placeholderClassName="mx_UserSettings_threepidPlaceholder"
|
||||||
placeholder={ _t("Add email address") }
|
placeholder={_t("Add email address")}
|
||||||
blurToCancel={ false }
|
blurToCancel={false}
|
||||||
onValueChanged={ this._onAddEmailEditFinished } />
|
onValueChanged={this._onAddEmailEditFinished} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||||
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||||
|
@ -1307,8 +1307,8 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_UserSettings">
|
<div className="mx_UserSettings">
|
||||||
<SimpleRoomHeader
|
<SimpleRoomHeader
|
||||||
title={ _t("Settings") }
|
title={_t("Settings")}
|
||||||
onCancelClick={ this.props.onClose }
|
onCancelClick={this.props.onClose}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<GeminiScrollbar className="mx_UserSettings_body"
|
<GeminiScrollbar className="mx_UserSettings_body"
|
||||||
|
@ -1326,21 +1326,21 @@ module.exports = React.createClass({
|
||||||
<ChangeDisplayName />
|
<ChangeDisplayName />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{threepidsSection}
|
{ threepidsSection }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_UserSettings_avatarPicker">
|
<div className="mx_UserSettings_avatarPicker">
|
||||||
<div onClick={ this.onAvatarPickerClick }>
|
<div onClick={this.onAvatarPickerClick}>
|
||||||
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
||||||
showUploadSection={false} className="mx_UserSettings_avatarPicker_img"/>
|
showUploadSection={false} className="mx_UserSettings_avatarPicker_img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_avatarPicker_edit">
|
<div className="mx_UserSettings_avatarPicker_edit">
|
||||||
<label htmlFor="avatarInput" ref="file_label">
|
<label htmlFor="avatarInput" ref="file_label">
|
||||||
<img src="img/camera.svg" className="mx_filterFlipColor"
|
<img src="img/camera.svg" className="mx_filterFlipColor"
|
||||||
alt={ _t("Upload avatar") } title={ _t("Upload avatar") }
|
alt={_t("Upload avatar")} title={_t("Upload avatar")}
|
||||||
width="17" height="15" />
|
width="17" height="15" />
|
||||||
</label>
|
</label>
|
||||||
<input id="avatarInput" type="file" onChange={this.onAvatarSelected}/>
|
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1357,37 +1357,37 @@ module.exports = React.createClass({
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
{accountJsx}
|
{ accountJsx }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{this._renderReferral()}
|
{ this._renderReferral() }
|
||||||
|
|
||||||
{notificationArea}
|
{ notificationArea }
|
||||||
|
|
||||||
{this._renderUserInterfaceSettings()}
|
{ this._renderUserInterfaceSettings() }
|
||||||
{this._renderLabs()}
|
{ this._renderLabs() }
|
||||||
{this._renderWebRtcSettings()}
|
{ this._renderWebRtcSettings() }
|
||||||
{this._renderDevicesPanel()}
|
{ this._renderDevicesPanel() }
|
||||||
{this._renderCryptoInfo()}
|
{ this._renderCryptoInfo() }
|
||||||
{this._renderIgnoredUsers()}
|
{ this._renderIgnoredUsers() }
|
||||||
{this._renderBulkOptions()}
|
{ this._renderBulkOptions() }
|
||||||
{this._renderBugReport()}
|
{ this._renderBugReport() }
|
||||||
|
|
||||||
{PlatformPeg.get().isElectron() && this._renderElectronSettings()}
|
{ PlatformPeg.get().isElectron() && this._renderElectronSettings() }
|
||||||
|
|
||||||
{this._renderAnalyticsControl()}
|
{ this._renderAnalyticsControl() }
|
||||||
|
|
||||||
<h3>{ _t("Advanced") }</h3>
|
<h3>{ _t("Advanced") }</h3>
|
||||||
|
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<div className="mx_UserSettings_advanced">
|
<div className="mx_UserSettings_advanced">
|
||||||
{ _t("Logged in as:") } {this._me}
|
{ _t("Logged in as:") } { this._me }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_advanced">
|
<div className="mx_UserSettings_advanced">
|
||||||
{_t('Access Token:')}
|
{ _t('Access Token:') }
|
||||||
<span className="mx_UserSettings_advanced_spoiler"
|
<span className="mx_UserSettings_advanced_spoiler"
|
||||||
onClick={this._showSpoiler}
|
onClick={this._showSpoiler}
|
||||||
data-spoiler={ MatrixClientPeg.get().getAccessToken() }>
|
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
||||||
<{ _t("click to reveal") }>
|
<{ _t("click to reveal") }>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1398,23 +1398,23 @@ module.exports = React.createClass({
|
||||||
{ _t("Identity Server is") } { MatrixClientPeg.get().getIdentityServerUrl() }
|
{ _t("Identity Server is") } { MatrixClientPeg.get().getIdentityServerUrl() }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_advanced">
|
<div className="mx_UserSettings_advanced">
|
||||||
{_t('matrix-react-sdk version:')} {(REACT_SDK_VERSION !== '<local>')
|
{ _t('matrix-react-sdk version:') } { (REACT_SDK_VERSION !== '<local>')
|
||||||
? gHVersionLabel('matrix-org/matrix-react-sdk', REACT_SDK_VERSION)
|
? gHVersionLabel('matrix-org/matrix-react-sdk', REACT_SDK_VERSION)
|
||||||
: REACT_SDK_VERSION
|
: REACT_SDK_VERSION
|
||||||
}<br/>
|
}<br />
|
||||||
{_t('riot-web version:')} {(this.state.vectorVersion !== undefined)
|
{ _t('riot-web version:') } { (this.state.vectorVersion !== undefined)
|
||||||
? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion)
|
? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion)
|
||||||
: 'unknown'
|
: 'unknown'
|
||||||
}<br/>
|
}<br />
|
||||||
{ _t("olm version:") } {olmVersionString}<br/>
|
{ _t("olm version:") } { olmVersionString }<br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{this._renderCheckUpdate()}
|
{ this._renderCheckUpdate() }
|
||||||
|
|
||||||
{this._renderClearCache()}
|
{ this._renderClearCache() }
|
||||||
|
|
||||||
{this._renderDeactivateAccount()}
|
{ this._renderDeactivateAccount() }
|
||||||
|
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,11 +13,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
var React = require('react');
|
import React from "react";
|
||||||
var ContentRepo = require("matrix-js-sdk").ContentRepo;
|
import {ContentRepo} from "matrix-js-sdk";
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
import MatrixClientPeg from "../../../MatrixClientPeg";
|
||||||
var Avatar = require('../../../Avatar');
|
import sdk from "../../../index";
|
||||||
var sdk = require("../../../index");
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomAvatar',
|
displayName: 'RoomAvatar',
|
||||||
|
@ -30,7 +29,7 @@ module.exports = React.createClass({
|
||||||
oobData: React.PropTypes.object,
|
oobData: React.PropTypes.object,
|
||||||
width: React.PropTypes.number,
|
width: React.PropTypes.number,
|
||||||
height: React.PropTypes.number,
|
height: React.PropTypes.number,
|
||||||
resizeMethod: React.PropTypes.string
|
resizeMethod: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -44,13 +43,13 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
urls: this.getImageUrls(this.props)
|
urls: this.getImageUrls(this.props),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillReceiveProps: function(newProps) {
|
componentWillReceiveProps: function(newProps) {
|
||||||
this.setState({
|
this.setState({
|
||||||
urls: this.getImageUrls(newProps)
|
urls: this.getImageUrls(newProps),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -61,11 +60,10 @@ module.exports = React.createClass({
|
||||||
props.oobData.avatarUrl,
|
props.oobData.avatarUrl,
|
||||||
Math.floor(props.width * window.devicePixelRatio),
|
Math.floor(props.width * window.devicePixelRatio),
|
||||||
Math.floor(props.height * window.devicePixelRatio),
|
Math.floor(props.height * window.devicePixelRatio),
|
||||||
props.resizeMethod
|
props.resizeMethod,
|
||||||
), // highest priority
|
), // highest priority
|
||||||
this.getRoomAvatarUrl(props),
|
this.getRoomAvatarUrl(props),
|
||||||
this.getOneToOneAvatar(props),
|
this.getOneToOneAvatar(props), // lowest priority
|
||||||
this.getFallbackAvatar(props) // lowest priority
|
|
||||||
].filter(function(url) {
|
].filter(function(url) {
|
||||||
return (url != null && url != "");
|
return (url != null && url != "");
|
||||||
});
|
});
|
||||||
|
@ -79,17 +77,17 @@ module.exports = React.createClass({
|
||||||
Math.floor(props.width * window.devicePixelRatio),
|
Math.floor(props.width * window.devicePixelRatio),
|
||||||
Math.floor(props.height * window.devicePixelRatio),
|
Math.floor(props.height * window.devicePixelRatio),
|
||||||
props.resizeMethod,
|
props.resizeMethod,
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
getOneToOneAvatar: function(props) {
|
getOneToOneAvatar: function(props) {
|
||||||
if (!props.room) return null;
|
if (!props.room) return null;
|
||||||
|
|
||||||
var mlist = props.room.currentState.members;
|
const mlist = props.room.currentState.members;
|
||||||
var userIds = [];
|
const userIds = [];
|
||||||
// for .. in optimisation to return early if there are >2 keys
|
// for .. in optimisation to return early if there are >2 keys
|
||||||
for (var uid in mlist) {
|
for (const uid in mlist) {
|
||||||
if (mlist.hasOwnProperty(uid)) {
|
if (mlist.hasOwnProperty(uid)) {
|
||||||
userIds.push(uid);
|
userIds.push(uid);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +97,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userIds.length == 2) {
|
if (userIds.length == 2) {
|
||||||
var theOtherGuy = null;
|
let theOtherGuy = null;
|
||||||
if (mlist[userIds[0]].userId == MatrixClientPeg.get().credentials.userId) {
|
if (mlist[userIds[0]].userId == MatrixClientPeg.get().credentials.userId) {
|
||||||
theOtherGuy = mlist[userIds[1]];
|
theOtherGuy = mlist[userIds[1]];
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,7 +108,7 @@ module.exports = React.createClass({
|
||||||
Math.floor(props.width * window.devicePixelRatio),
|
Math.floor(props.width * window.devicePixelRatio),
|
||||||
Math.floor(props.height * window.devicePixelRatio),
|
Math.floor(props.height * window.devicePixelRatio),
|
||||||
props.resizeMethod,
|
props.resizeMethod,
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
} else if (userIds.length == 1) {
|
} else if (userIds.length == 1) {
|
||||||
return mlist[userIds[0]].getAvatarUrl(
|
return mlist[userIds[0]].getAvatarUrl(
|
||||||
|
@ -118,37 +116,24 @@ module.exports = React.createClass({
|
||||||
Math.floor(props.width * window.devicePixelRatio),
|
Math.floor(props.width * window.devicePixelRatio),
|
||||||
Math.floor(props.height * window.devicePixelRatio),
|
Math.floor(props.height * window.devicePixelRatio),
|
||||||
props.resizeMethod,
|
props.resizeMethod,
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getFallbackAvatar: function(props) {
|
|
||||||
let roomId = null;
|
|
||||||
if (props.oobData && props.oobData.roomId) {
|
|
||||||
roomId = this.props.oobData.roomId;
|
|
||||||
} else if (props.room) {
|
|
||||||
roomId = props.room.roomId;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Avatar.defaultAvatarUrlForString(roomId);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||||
|
|
||||||
var {room, oobData, ...otherProps} = this.props;
|
const {room, oobData, ...otherProps} = this.props;
|
||||||
|
|
||||||
var roomName = room ? room.name : oobData.name;
|
const roomName = room ? room.name : oobData.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseAvatar {...otherProps} name={roomName}
|
<BaseAvatar {...otherProps} name={roomName}
|
||||||
idName={room ? room.roomId : null}
|
idName={room ? room.roomId : null}
|
||||||
urls={this.state.urls} />
|
urls={this.state.urls} />
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,7 +41,11 @@ module.exports = React.createClass({
|
||||||
validAddressTypes: PropTypes.arrayOf(PropTypes.oneOf(addressTypes)),
|
validAddressTypes: PropTypes.arrayOf(PropTypes.oneOf(addressTypes)),
|
||||||
onFinished: PropTypes.func.isRequired,
|
onFinished: PropTypes.func.isRequired,
|
||||||
groupId: PropTypes.string,
|
groupId: PropTypes.string,
|
||||||
|
// The type of entity to search for. Default: 'user'.
|
||||||
pickerType: PropTypes.oneOf(['user', 'room']),
|
pickerType: PropTypes.oneOf(['user', 'room']),
|
||||||
|
// Whether the current user should be included in the addresses returned. Only
|
||||||
|
// applicable when pickerType is `user`. Default: false.
|
||||||
|
includeSelf: PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -50,6 +54,7 @@ module.exports = React.createClass({
|
||||||
focus: true,
|
focus: true,
|
||||||
validAddressTypes: addressTypes,
|
validAddressTypes: addressTypes,
|
||||||
pickerType: 'user',
|
pickerType: 'user',
|
||||||
|
includeSelf: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -358,7 +363,7 @@ module.exports = React.createClass({
|
||||||
results.forEach((result) => {
|
results.forEach((result) => {
|
||||||
if (result.room_id) {
|
if (result.room_id) {
|
||||||
queryList.push({
|
queryList.push({
|
||||||
addressType: 'mx',
|
addressType: 'mx-room-id',
|
||||||
address: result.room_id,
|
address: result.room_id,
|
||||||
displayName: result.name,
|
displayName: result.name,
|
||||||
avatarMxc: result.avatar_url,
|
avatarMxc: result.avatar_url,
|
||||||
|
@ -366,14 +371,16 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result.user_id === MatrixClientPeg.get().credentials.userId) {
|
if (!this.props.includeSelf &&
|
||||||
|
result.user_id === MatrixClientPeg.get().credentials.userId
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return objects, structure of which is defined
|
// Return objects, structure of which is defined
|
||||||
// by UserAddressType
|
// by UserAddressType
|
||||||
queryList.push({
|
queryList.push({
|
||||||
addressType: 'mx',
|
addressType: 'mx-user-id',
|
||||||
address: result.user_id,
|
address: result.user_id,
|
||||||
displayName: result.display_name,
|
displayName: result.display_name,
|
||||||
avatarMxc: result.avatar_url,
|
avatarMxc: result.avatar_url,
|
||||||
|
@ -412,16 +419,23 @@ module.exports = React.createClass({
|
||||||
address: addressText,
|
address: addressText,
|
||||||
isKnown: false,
|
isKnown: false,
|
||||||
};
|
};
|
||||||
if (addrType == null) {
|
if (!this.props.validAddressTypes.includes(addrType)) {
|
||||||
this.setState({ error: true });
|
this.setState({ error: true });
|
||||||
return null;
|
return null;
|
||||||
} else if (addrType == 'mx') {
|
} else if (addrType == 'mx-user-id') {
|
||||||
const user = MatrixClientPeg.get().getUser(addrObj.address);
|
const user = MatrixClientPeg.get().getUser(addrObj.address);
|
||||||
if (user) {
|
if (user) {
|
||||||
addrObj.displayName = user.displayName;
|
addrObj.displayName = user.displayName;
|
||||||
addrObj.avatarMxc = user.avatarUrl;
|
addrObj.avatarMxc = user.avatarUrl;
|
||||||
addrObj.isKnown = true;
|
addrObj.isKnown = true;
|
||||||
}
|
}
|
||||||
|
} else if (addrType == 'mx-room-id') {
|
||||||
|
const room = MatrixClientPeg.get().getRoom(addrObj.address);
|
||||||
|
if (room) {
|
||||||
|
addrObj.displayName = room.name;
|
||||||
|
addrObj.avatarMxc = room.avatarUrl;
|
||||||
|
addrObj.isKnown = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userList = this.state.userList.slice();
|
const userList = this.state.userList.slice();
|
||||||
|
@ -481,7 +495,7 @@ module.exports = React.createClass({
|
||||||
const AddressTile = sdk.getComponent("elements.AddressTile");
|
const AddressTile = sdk.getComponent("elements.AddressTile");
|
||||||
for (let i = 0; i < this.state.userList.length; i++) {
|
for (let i = 0; i < this.state.userList.length; i++) {
|
||||||
query.push(
|
query.push(
|
||||||
<AddressTile key={i} address={this.state.userList[i]} canDismiss={true} onDismissed={ this.onDismissed(i) } />,
|
<AddressTile key={i} address={this.state.userList[i]} canDismiss={true} onDismissed={this.onDismissed(i)} />,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,23 +517,36 @@ module.exports = React.createClass({
|
||||||
let error;
|
let error;
|
||||||
let addressSelector;
|
let addressSelector;
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
|
let tryUsing = '';
|
||||||
|
const validTypeDescriptions = this.props.validAddressTypes.map((t) => {
|
||||||
|
return {
|
||||||
|
'mx-user-id': _t("Matrix ID"),
|
||||||
|
'mx-room-id': _t("Matrix Room ID"),
|
||||||
|
'email': _t("email address"),
|
||||||
|
}[t];
|
||||||
|
});
|
||||||
|
tryUsing = _t("Try using one of the following valid address types: %(validTypesList)s.", {
|
||||||
|
validTypesList: validTypeDescriptions.join(", "),
|
||||||
|
});
|
||||||
error = <div className="mx_ChatInviteDialog_error">
|
error = <div className="mx_ChatInviteDialog_error">
|
||||||
{_t("You have entered an invalid contact. Try using their Matrix ID or email address.")}
|
{ _t("You have entered an invalid address.") }
|
||||||
|
<br />
|
||||||
|
{ tryUsing }
|
||||||
</div>;
|
</div>;
|
||||||
} else if (this.state.searchError) {
|
} else if (this.state.searchError) {
|
||||||
error = <div className="mx_ChatInviteDialog_error">{this.state.searchError}</div>;
|
error = <div className="mx_ChatInviteDialog_error">{ this.state.searchError }</div>;
|
||||||
} else if (
|
} else if (
|
||||||
this.state.query.length > 0 &&
|
this.state.query.length > 0 &&
|
||||||
this.state.queryList.length === 0 &&
|
this.state.queryList.length === 0 &&
|
||||||
!this.state.busy
|
!this.state.busy
|
||||||
) {
|
) {
|
||||||
error = <div className="mx_ChatInviteDialog_error">{_t("No results")}</div>;
|
error = <div className="mx_ChatInviteDialog_error">{ _t("No results") }</div>;
|
||||||
} else {
|
} else {
|
||||||
addressSelector = (
|
addressSelector = (
|
||||||
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
||||||
addressList={ this.state.queryList }
|
addressList={this.state.queryList}
|
||||||
onSelected={ this.onSelected }
|
onSelected={this.onSelected}
|
||||||
truncateAt={ TRUNCATE_QUERY_LIST }
|
truncateAt={TRUNCATE_QUERY_LIST}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -527,7 +554,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_ChatInviteDialog" onKeyDown={this.onKeyDown}>
|
<div className="mx_ChatInviteDialog" onKeyDown={this.onKeyDown}>
|
||||||
<div className="mx_Dialog_title">
|
<div className="mx_Dialog_title">
|
||||||
{this.props.title}
|
{ this.props.title }
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className="mx_ChatInviteDialog_cancel"
|
<AccessibleButton className="mx_ChatInviteDialog_cancel"
|
||||||
onClick={this.onCancel} >
|
onClick={this.onCancel} >
|
||||||
|
@ -543,7 +570,7 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className="mx_Dialog_primary" onClick={this.onButtonClick}>
|
<button className="mx_Dialog_primary" onClick={this.onButtonClick}>
|
||||||
{this.props.button}
|
{ this.props.button }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -52,20 +52,20 @@ export default React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
||||||
onEnterPressed={ this.onOk }
|
onEnterPressed={this.onOk}
|
||||||
title={title}
|
title={title}
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
{_t("Are you sure you wish to remove (delete) this event? " +
|
{ _t("Are you sure you wish to remove (delete) this event? " +
|
||||||
"Note that if you delete a room name or topic change, it could undo the change.")}
|
"Note that if you delete a room name or topic change, it could undo the change.") }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className={confirmButtonClass} onClick={this.onOk}>
|
<button className={confirmButtonClass} onClick={this.onOk}>
|
||||||
{_t("Remove")}
|
{ _t("Remove") }
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={this.onCancel}>
|
<button onClick={this.onCancel}>
|
||||||
{_t("Cancel")}
|
{ _t("Cancel") }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default React.createClass({
|
||||||
<form onSubmit={this.onOk}>
|
<form onSubmit={this.onOk}>
|
||||||
<input className="mx_ConfirmUserActionDialog_reasonField"
|
<input className="mx_ConfirmUserActionDialog_reasonField"
|
||||||
ref={this._collectReasonField}
|
ref={this._collectReasonField}
|
||||||
placeholder={ _t("Reason") }
|
placeholder={_t("Reason")}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -112,22 +112,22 @@ export default React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
||||||
onEnterPressed={ this.onOk }
|
onEnterPressed={this.onOk}
|
||||||
title={title}
|
title={title}
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<div className="mx_ConfirmUserActionDialog_avatar">
|
<div className="mx_ConfirmUserActionDialog_avatar">
|
||||||
{avatar}
|
{ avatar }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_ConfirmUserActionDialog_name">{name}</div>
|
<div className="mx_ConfirmUserActionDialog_name">{ name }</div>
|
||||||
<div className="mx_ConfirmUserActionDialog_userId">{userId}</div>
|
<div className="mx_ConfirmUserActionDialog_userId">{ userId }</div>
|
||||||
</div>
|
</div>
|
||||||
{reasonBox}
|
{ reasonBox }
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className={confirmButtonClass}
|
<button className={confirmButtonClass}
|
||||||
onClick={this.onOk} autoFocus={!this.props.askReason}
|
onClick={this.onOk} autoFocus={!this.props.askReason}
|
||||||
>
|
>
|
||||||
{this.props.action}
|
{ this.props.action }
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={this.onCancel}>
|
<button onClick={this.onCancel}>
|
||||||
|
|
|
@ -142,8 +142,8 @@ export default React.createClass({
|
||||||
// rather than displaying what the server gives us, but synapse doesn't give
|
// rather than displaying what the server gives us, but synapse doesn't give
|
||||||
// any yet.
|
// any yet.
|
||||||
createErrorNode = <div className="error">
|
createErrorNode = <div className="error">
|
||||||
<div>{_t('Room creation failed')}</div>
|
<div>{ _t('Room creation failed') }</div>
|
||||||
<div>{this.state.createError.message}</div>
|
<div>{ this.state.createError.message }</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ export default React.createClass({
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<div className="mx_CreateGroupDialog_inputRow">
|
<div className="mx_CreateGroupDialog_inputRow">
|
||||||
<div className="mx_CreateGroupDialog_label">
|
<div className="mx_CreateGroupDialog_label">
|
||||||
<label htmlFor="groupname">{_t('Group Name')}</label>
|
<label htmlFor="groupname">{ _t('Group Name') }</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input id="groupname" className="mx_CreateGroupDialog_input"
|
<input id="groupname" className="mx_CreateGroupDialog_input"
|
||||||
|
@ -169,7 +169,7 @@ export default React.createClass({
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_CreateGroupDialog_inputRow">
|
<div className="mx_CreateGroupDialog_inputRow">
|
||||||
<div className="mx_CreateGroupDialog_label">
|
<div className="mx_CreateGroupDialog_label">
|
||||||
<label htmlFor="groupid">{_t('Group ID')}</label>
|
<label htmlFor="groupid">{ _t('Group ID') }</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input id="groupid" className="mx_CreateGroupDialog_input"
|
<input id="groupid" className="mx_CreateGroupDialog_input"
|
||||||
|
@ -182,9 +182,9 @@ export default React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="error">
|
<div className="error">
|
||||||
{this.state.groupIdError}
|
{ this.state.groupIdError }
|
||||||
</div>
|
</div>
|
||||||
{createErrorNode}
|
{ createErrorNode }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button onClick={this._onCancel}>
|
<button onClick={this._onCancel}>
|
||||||
|
|
|
@ -28,25 +28,25 @@ export default function DeviceVerifyDialog(props) {
|
||||||
const body = (
|
const body = (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
{_t("To verify that this device can be trusted, please contact its " +
|
{ _t("To verify that this device can be trusted, please contact its " +
|
||||||
"owner using some other means (e.g. in person or a phone call) " +
|
"owner using some other means (e.g. in person or a phone call) " +
|
||||||
"and ask them whether the key they see in their User Settings " +
|
"and ask them whether the key they see in their User Settings " +
|
||||||
"for this device matches the key below:")}
|
"for this device matches the key below:") }
|
||||||
</p>
|
</p>
|
||||||
<div className="mx_UserSettings_cryptoSection">
|
<div className="mx_UserSettings_cryptoSection">
|
||||||
<ul>
|
<ul>
|
||||||
<li><label>{_t("Device name")}:</label> <span>{ props.device.getDisplayName() }</span></li>
|
<li><label>{ _t("Device name") }:</label> <span>{ props.device.getDisplayName() }</span></li>
|
||||||
<li><label>{_t("Device ID")}:</label> <span><code>{ props.device.deviceId}</code></span></li>
|
<li><label>{ _t("Device ID") }:</label> <span><code>{ props.device.deviceId }</code></span></li>
|
||||||
<li><label>{_t("Device key")}:</label> <span><code><b>{ key }</b></code></span></li>
|
<li><label>{ _t("Device key") }:</label> <span><code><b>{ key }</b></code></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
{_t("If it matches, press the verify button below. " +
|
{ _t("If it matches, press the verify button below. " +
|
||||||
"If it doesn't, then someone else is intercepting this device " +
|
"If it doesn't, then someone else is intercepting this device " +
|
||||||
"and you probably want to press the blacklist button instead.")}
|
"and you probably want to press the blacklist button instead.") }
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{_t("In future this verification process will be more sophisticated.")}
|
{ _t("In future this verification process will be more sophisticated.") }
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -63,11 +63,11 @@ export default React.createClass({
|
||||||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||||
title={this.props.title || _t('Error')}>
|
title={this.props.title || _t('Error')}>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
{this.props.description || _t('An error has occurred.')}
|
{ this.props.description || _t('An error has occurred.') }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button ref="button" className="mx_Dialog_primary" onClick={this.props.onFinished}>
|
<button ref="button" className="mx_Dialog_primary" onClick={this.props.onFinished}>
|
||||||
{this.props.button || _t('OK')}
|
{ this.props.button || _t('OK') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -126,17 +126,17 @@ export default React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{text}</p>
|
<p>{ text }</p>
|
||||||
|
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button onClick={this._onVerifyClicked}>
|
<button onClick={this._onVerifyClicked}>
|
||||||
{_t('Start verification')}
|
{ _t('Start verification') }
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this._onShareClicked}>
|
<button onClick={this._onShareClicked}>
|
||||||
{_t('Share without verifying')}
|
{ _t('Share without verifying') }
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this._onIgnoreClicked}>
|
<button onClick={this._onIgnoreClicked}>
|
||||||
{_t('Ignore request')}
|
{ _t('Ignore request') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,7 +154,7 @@ export default React.createClass({
|
||||||
} else {
|
} else {
|
||||||
content = (
|
content = (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t('Loading device info...')}</p>
|
<p>{ _t('Loading device info...') }</p>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -165,7 +165,7 @@ export default React.createClass({
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
title={_t('Encryption key request')}
|
title={_t('Encryption key request')}
|
||||||
>
|
>
|
||||||
{content}
|
{ content }
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default React.createClass({
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
const cancelButton = this.props.hasCancelButton ? (
|
const cancelButton = this.props.hasCancelButton ? (
|
||||||
<button onClick={this.onCancel}>
|
<button onClick={this.onCancel}>
|
||||||
{_t("Cancel")}
|
{ _t("Cancel") }
|
||||||
</button>
|
</button>
|
||||||
) : null;
|
) : null;
|
||||||
const buttonClasses = classnames({
|
const buttonClasses = classnames({
|
||||||
|
@ -64,18 +64,18 @@ export default React.createClass({
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished}
|
||||||
onEnterPressed={ this.onOk }
|
onEnterPressed={this.onOk}
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
{this.props.description}
|
{ this.props.description }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className={buttonClasses} onClick={this.onOk} autoFocus={this.props.focus}>
|
<button className={buttonClasses} onClick={this.onOk} autoFocus={this.props.focus}>
|
||||||
{this.props.button || _t('OK')}
|
{ this.props.button || _t('OK') }
|
||||||
</button>
|
</button>
|
||||||
{this.props.extraButtons}
|
{ this.props.extraButtons }
|
||||||
{cancelButton}
|
{ cancelButton }
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
|
|
|
@ -45,10 +45,10 @@ export default React.createClass({
|
||||||
if (SdkConfig.get().bug_report_endpoint_url) {
|
if (SdkConfig.get().bug_report_endpoint_url) {
|
||||||
bugreport = (
|
bugreport = (
|
||||||
<p>
|
<p>
|
||||||
{_tJsx(
|
{ _tJsx(
|
||||||
"Otherwise, <a>click here</a> to send a bug report.",
|
"Otherwise, <a>click here</a> to send a bug report.",
|
||||||
/<a>(.*?)<\/a>/, (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{sub}</a>,
|
/<a>(.*?)<\/a>/, (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{ sub }</a>,
|
||||||
)}
|
) }
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -57,19 +57,19 @@ export default React.createClass({
|
||||||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||||
title={_t('Unable to restore session')}>
|
title={_t('Unable to restore session')}>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<p>{_t("We encountered an error trying to restore your previous session. If " +
|
<p>{ _t("We encountered an error trying to restore your previous session. If " +
|
||||||
"you continue, you will need to log in again, and encrypted chat " +
|
"you continue, you will need to log in again, and encrypted chat " +
|
||||||
"history will be unreadable.")}</p>
|
"history will be unreadable.") }</p>
|
||||||
|
|
||||||
<p>{_t("If you have previously used a more recent version of Riot, your session " +
|
<p>{ _t("If you have previously used a more recent version of Riot, your session " +
|
||||||
"may be incompatible with this version. Close this window and return " +
|
"may be incompatible with this version. Close this window and return " +
|
||||||
"to the more recent version.")}</p>
|
"to the more recent version.") }</p>
|
||||||
|
|
||||||
{bugreport}
|
{ bugreport }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
||||||
{_t("Continue anyway")}
|
{ _t("Continue anyway") }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -130,10 +130,10 @@ export default React.createClass({
|
||||||
|
|
||||||
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
||||||
className="mx_SetEmailDialog_email_input"
|
className="mx_SetEmailDialog_email_input"
|
||||||
placeholder={ _t("Email address") }
|
placeholder={_t("Email address")}
|
||||||
placeholderClassName="mx_SetEmailDialog_email_input_placeholder"
|
placeholderClassName="mx_SetEmailDialog_email_input_placeholder"
|
||||||
blurToCancel={ false }
|
blurToCancel={false}
|
||||||
onValueChanged={ this.onEmailAddressChanged } />;
|
onValueChanged={this.onEmailAddressChanged} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_SetEmailDialog"
|
<BaseDialog className="mx_SetEmailDialog"
|
||||||
|
|
|
@ -226,7 +226,7 @@ export default React.createClass({
|
||||||
let usernameIndicator = null;
|
let usernameIndicator = null;
|
||||||
let usernameBusyIndicator = null;
|
let usernameBusyIndicator = null;
|
||||||
if (this.state.usernameBusy) {
|
if (this.state.usernameBusy) {
|
||||||
usernameBusyIndicator = <Spinner w="24" h="24"/>;
|
usernameBusyIndicator = <Spinner w="24" h="24" />;
|
||||||
} else {
|
} else {
|
||||||
const usernameAvailable = this.state.username &&
|
const usernameAvailable = this.state.username &&
|
||||||
this.state.usernameCheckSupport && !this.state.usernameError;
|
this.state.usernameCheckSupport && !this.state.usernameError;
|
||||||
|
@ -275,17 +275,17 @@ export default React.createClass({
|
||||||
/<a>(.*?)<\/a>/,
|
/<a>(.*?)<\/a>/,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
(sub) => <span>{this.props.homeserverUrl}</span>,
|
(sub) => <span>{ this.props.homeserverUrl }</span>,
|
||||||
(sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{sub}</a>,
|
(sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{ sub }</a>,
|
||||||
],
|
],
|
||||||
)}
|
) }
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{ _tJsx(
|
{ _tJsx(
|
||||||
'If you already have a Matrix account you can <a>log in</a> instead.',
|
'If you already have a Matrix account you can <a>log in</a> instead.',
|
||||||
/<a>(.*?)<\/a>/,
|
/<a>(.*?)<\/a>/,
|
||||||
[(sub) => <a href="#" onClick={this.props.onLoginClick}>{sub}</a>],
|
[(sub) => <a href="#" onClick={this.props.onLoginClick}>{ sub }</a>],
|
||||||
)}
|
) }
|
||||||
</p>
|
</p>
|
||||||
{ auth }
|
{ auth }
|
||||||
{ authErrorIndicator }
|
{ authErrorIndicator }
|
||||||
|
|
|
@ -65,10 +65,10 @@ export default React.createClass({
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<div className="mx_TextInputDialog_label">
|
<div className="mx_TextInputDialog_label">
|
||||||
<label htmlFor="textinput"> {this.props.description} </label>
|
<label htmlFor="textinput"> { this.props.description } </label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input id="textinput" ref="textinput" className="mx_TextInputDialog_input" defaultValue={this.props.value} autoFocus={this.props.focus} size="64" onKeyDown={this.onKeyDown}/>
|
<input id="textinput" ref="textinput" className="mx_TextInputDialog_input" defaultValue={this.props.value} autoFocus={this.props.focus} size="64" onKeyDown={this.onKeyDown} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
|
@ -76,7 +76,7 @@ export default React.createClass({
|
||||||
{ _t("Cancel") }
|
{ _t("Cancel") }
|
||||||
</button>
|
</button>
|
||||||
<button className="mx_Dialog_primary" onClick={this.onOk}>
|
<button className="mx_Dialog_primary" onClick={this.onOk}>
|
||||||
{this.props.button}
|
{ this.props.button }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -45,11 +45,12 @@ export default React.createClass({
|
||||||
const address = this.props.address;
|
const address = this.props.address;
|
||||||
const name = address.displayName || address.address;
|
const name = address.displayName || address.address;
|
||||||
|
|
||||||
let imgUrls = [];
|
const imgUrls = [];
|
||||||
|
const isMatrixAddress = ['mx-user-id', 'mx-room-id'].includes(address.addressType);
|
||||||
|
|
||||||
if (address.addressType === "mx" && address.avatarMxc) {
|
if (isMatrixAddress && address.avatarMxc) {
|
||||||
imgUrls.push(MatrixClientPeg.get().mxcUrlToHttp(
|
imgUrls.push(MatrixClientPeg.get().mxcUrlToHttp(
|
||||||
address.avatarMxc, 25, 25, 'crop'
|
address.avatarMxc, 25, 25, 'crop',
|
||||||
));
|
));
|
||||||
} else if (address.addressType === 'email') {
|
} else if (address.addressType === 'email') {
|
||||||
imgUrls.push('img/icon-email-user.svg');
|
imgUrls.push('img/icon-email-user.svg');
|
||||||
|
@ -77,7 +78,7 @@ export default React.createClass({
|
||||||
|
|
||||||
let info;
|
let info;
|
||||||
let error = false;
|
let error = false;
|
||||||
if (address.addressType === "mx" && address.isKnown) {
|
if (isMatrixAddress && address.isKnown) {
|
||||||
const idClasses = classNames({
|
const idClasses = classNames({
|
||||||
"mx_AddressTile_id": true,
|
"mx_AddressTile_id": true,
|
||||||
"mx_AddressTile_justified": this.props.justified,
|
"mx_AddressTile_justified": this.props.justified,
|
||||||
|
@ -89,7 +90,7 @@ export default React.createClass({
|
||||||
<div className={idClasses}>{ address.address }</div>
|
<div className={idClasses}>{ address.address }</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (address.addressType === "mx") {
|
} else if (isMatrixAddress) {
|
||||||
const unknownMxClasses = classNames({
|
const unknownMxClasses = classNames({
|
||||||
"mx_AddressTile_unknownMx": true,
|
"mx_AddressTile_unknownMx": true,
|
||||||
"mx_AddressTile_justified": this.props.justified,
|
"mx_AddressTile_justified": this.props.justified,
|
||||||
|
|
|
@ -50,16 +50,16 @@ export default class AppPermission extends React.Component {
|
||||||
let e2eWarningText;
|
let e2eWarningText;
|
||||||
if (this.props.isRoomEncrypted) {
|
if (this.props.isRoomEncrypted) {
|
||||||
e2eWarningText =
|
e2eWarningText =
|
||||||
<span className='mx_AppPermissionWarningTextLabel'>{_t('NOTE: Apps are not end-to-end encrypted')}</span>;
|
<span className='mx_AppPermissionWarningTextLabel'>{ _t('NOTE: Apps are not end-to-end encrypted') }</span>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className='mx_AppPermissionWarning'>
|
<div className='mx_AppPermissionWarning'>
|
||||||
<div className='mx_AppPermissionWarningImage'>
|
<div className='mx_AppPermissionWarningImage'>
|
||||||
<img src='img/warning.svg' alt={_t('Warning!')}/>
|
<img src='img/warning.svg' alt={_t('Warning!')} />
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_AppPermissionWarningText'>
|
<div className='mx_AppPermissionWarningText'>
|
||||||
<span className='mx_AppPermissionWarningTextLabel'>{_t('Do you want to load widget from URL:')}</span> <span className='mx_AppPermissionWarningTextURL'>{this.state.curlBase}</span>
|
<span className='mx_AppPermissionWarningTextLabel'>{ _t('Do you want to load widget from URL:') }</span> <span className='mx_AppPermissionWarningTextURL'>{ this.state.curlBase }</span>
|
||||||
{e2eWarningText}
|
{ e2eWarningText }
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
className='mx_AppPermissionButton'
|
className='mx_AppPermissionButton'
|
||||||
|
|
|
@ -261,7 +261,7 @@ export default React.createClass({
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
appTileBody = (
|
appTileBody = (
|
||||||
<div className='mx_AppTileBody mx_AppLoading'>
|
<div className='mx_AppTileBody mx_AppLoading'>
|
||||||
<MessageSpinner msg='Loading...'/>
|
<MessageSpinner msg='Loading...' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (this.state.hasPermissionToLoad == true) {
|
} else if (this.state.hasPermissionToLoad == true) {
|
||||||
|
@ -312,19 +312,19 @@ export default React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
|
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
|
||||||
<div ref="menu_bar" className="mx_AppTileMenuBar" onClick={this.onClickMenuBar}>
|
<div ref="menu_bar" className="mx_AppTileMenuBar" onClick={this.onClickMenuBar}>
|
||||||
{this.formatAppTileName()}
|
{ this.formatAppTileName() }
|
||||||
<span className="mx_AppTileMenuBarWidgets">
|
<span className="mx_AppTileMenuBarWidgets">
|
||||||
{/* Edit widget */}
|
{ /* Edit widget */ }
|
||||||
{showEditButton && <img
|
{ showEditButton && <img
|
||||||
src="img/edit.svg"
|
src="img/edit.svg"
|
||||||
className="mx_filterFlipColor mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
|
className="mx_filterFlipColor mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
|
||||||
width="8" height="8"
|
width="8" height="8"
|
||||||
alt={_t('Edit')}
|
alt={_t('Edit')}
|
||||||
title={_t('Edit')}
|
title={_t('Edit')}
|
||||||
onClick={this._onEditClick}
|
onClick={this._onEditClick}
|
||||||
/>}
|
/> }
|
||||||
|
|
||||||
{/* Delete widget */}
|
{ /* Delete widget */ }
|
||||||
<img src={deleteIcon}
|
<img src={deleteIcon}
|
||||||
className={deleteClasses}
|
className={deleteClasses}
|
||||||
width="8" height="8"
|
width="8" height="8"
|
||||||
|
@ -334,7 +334,7 @@ export default React.createClass({
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{appTileBody}
|
{ appTileBody }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,10 +6,10 @@ const AppWarning = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className='mx_AppPermissionWarning'>
|
<div className='mx_AppPermissionWarning'>
|
||||||
<div className='mx_AppPermissionWarningImage'>
|
<div className='mx_AppPermissionWarningImage'>
|
||||||
<img src='img/warning.svg' alt={_t('Warning!')}/>
|
<img src='img/warning.svg' alt={_t('Warning!')} />
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_AppPermissionWarningText'>
|
<div className='mx_AppPermissionWarningText'>
|
||||||
<span className='mx_AppPermissionWarningTextLabel'>{props.errorMsg}</span>
|
<span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -157,7 +157,12 @@ class FlairAvatar extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const httpUrl = this.context.matrixClient.mxcUrlToHttp(
|
const httpUrl = this.context.matrixClient.mxcUrlToHttp(
|
||||||
this.props.groupProfile.avatarUrl, 14, 14, 'scale', false);
|
this.props.groupProfile.avatarUrl, 14, 14, 'scale', false);
|
||||||
return <img src={httpUrl} width="14px" height="14px" onClick={this.onClick}/>;
|
return <img
|
||||||
|
src={httpUrl}
|
||||||
|
width="14px"
|
||||||
|
height="14px"
|
||||||
|
onClick={this.onClick}
|
||||||
|
title={this.props.groupProfile.groupId} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +191,7 @@ export default class Flair extends React.Component {
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this._unmounted = false;
|
this._unmounted = false;
|
||||||
if (UserSettingsStore.isFeatureEnabled('feature_flair') && groupSupport) {
|
if (UserSettingsStore.isFeatureEnabled('feature_groups') && groupSupport) {
|
||||||
this._generateAvatars();
|
this._generateAvatars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,11 +238,11 @@ export default class Flair extends React.Component {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
const avatars = this.state.profiles.map((profile, index) => {
|
const avatars = this.state.profiles.map((profile, index) => {
|
||||||
return <FlairAvatar key={index} groupProfile={profile}/>;
|
return <FlairAvatar key={index} groupProfile={profile} />;
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<span className="mx_Flair" style={{"marginLeft": "5px", "verticalAlign": "-3px"}}>
|
<span className="mx_Flair" style={{"marginLeft": "5px", "verticalAlign": "-3px"}}>
|
||||||
{avatars}
|
{ avatars }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
38
src/components/views/elements/GroupsButton.js
Normal file
38
src/components/views/elements/GroupsButton.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
|
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 sdk from '../../../index';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
|
const GroupsButton = function(props) {
|
||||||
|
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||||
|
return (
|
||||||
|
<ActionButton action="view_my_groups"
|
||||||
|
label={_t("Groups")}
|
||||||
|
iconPath="img/icons-groups.svg"
|
||||||
|
size={props.size}
|
||||||
|
tooltip={props.tooltip}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
GroupsButton.propTypes = {
|
||||||
|
size: PropTypes.string,
|
||||||
|
tooltip: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GroupsButton;
|
|
@ -80,7 +80,7 @@ export default class ManageIntegsButton extends React.Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.state.scalarError && !this.scalarClient.hasCredentials()) {
|
if (this.state.scalarError && !this.scalarClient.hasCredentials()) {
|
||||||
integrationsWarningTriangle = <img src="img/warning.svg" title={_t('Integrations Error')} width="17"/>;
|
integrationsWarningTriangle = <img src="img/warning.svg" title={_t('Integrations Error')} width="17" />;
|
||||||
// Popup shown when hovering over integrationsButton_error (via CSS)
|
// Popup shown when hovering over integrationsButton_error (via CSS)
|
||||||
integrationsErrorPopup = (
|
integrationsErrorPopup = (
|
||||||
<span className="mx_RoomSettings_integrationsButton_errorPopup">
|
<span className="mx_RoomSettings_integrationsButton_errorPopup">
|
||||||
|
@ -90,8 +90,8 @@ export default class ManageIntegsButton extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
integrationsButton = (
|
integrationsButton = (
|
||||||
<AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={ _t('Manage Integrations') }>
|
<AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={_t('Manage Integrations')}>
|
||||||
<TintableSvg src="img/icons-apps.svg" width="35" height="35"/>
|
<TintableSvg src="img/icons-apps.svg" width="35" height="35" />
|
||||||
{ integrationsWarningTriangle }
|
{ integrationsWarningTriangle }
|
||||||
{ integrationsErrorPopup }
|
{ integrationsErrorPopup }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
|
|
@ -26,8 +26,8 @@ module.exports = React.createClass({
|
||||||
const msg = this.props.msg || "Loading...";
|
const msg = this.props.msg || "Loading...";
|
||||||
return (
|
return (
|
||||||
<div className="mx_Spinner">
|
<div className="mx_Spinner">
|
||||||
<div className="mx_Spinner_Msg">{msg}</div>
|
<div className="mx_Spinner_Msg">{ msg }</div>
|
||||||
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
|
<img src="img/spinner.gif" width={w} height={h} className={imgClass} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -167,7 +167,7 @@ const Pill = React.createClass({
|
||||||
userId = member.userId;
|
userId = member.userId;
|
||||||
linkText = member.rawDisplayName.replace(' (IRC)', ''); // FIXME when groups are done
|
linkText = member.rawDisplayName.replace(' (IRC)', ''); // FIXME when groups are done
|
||||||
if (this.props.shouldShowPillAvatar) {
|
if (this.props.shouldShowPillAvatar) {
|
||||||
avatar = <MemberAvatar member={member} width={16} height={16}/>;
|
avatar = <MemberAvatar member={member} width={16} height={16} />;
|
||||||
}
|
}
|
||||||
pillClass = 'mx_UserPill';
|
pillClass = 'mx_UserPill';
|
||||||
href = null;
|
href = null;
|
||||||
|
@ -180,7 +180,7 @@ const Pill = React.createClass({
|
||||||
if (room) {
|
if (room) {
|
||||||
linkText = (room ? getDisplayAliasForRoom(room) : null) || resource;
|
linkText = (room ? getDisplayAliasForRoom(room) : null) || resource;
|
||||||
if (this.props.shouldShowPillAvatar) {
|
if (this.props.shouldShowPillAvatar) {
|
||||||
avatar = <RoomAvatar room={room} width={16} height={16}/>;
|
avatar = <RoomAvatar room={room} width={16} height={16} />;
|
||||||
}
|
}
|
||||||
pillClass = 'mx_RoomPill';
|
pillClass = 'mx_RoomPill';
|
||||||
}
|
}
|
||||||
|
@ -195,12 +195,12 @@ const Pill = React.createClass({
|
||||||
if (this.state.pillType) {
|
if (this.state.pillType) {
|
||||||
return this.props.inMessage ?
|
return this.props.inMessage ?
|
||||||
<a className={classes} href={href} onClick={onClick} title={resource} data-offset-key={this.props.offsetKey}>
|
<a className={classes} href={href} onClick={onClick} title={resource} data-offset-key={this.props.offsetKey}>
|
||||||
{avatar}
|
{ avatar }
|
||||||
{linkText}
|
{ linkText }
|
||||||
</a> :
|
</a> :
|
||||||
<span className={classes} title={resource} data-offset-key={this.props.offsetKey}>
|
<span className={classes} title={resource} data-offset-key={this.props.offsetKey}>
|
||||||
{avatar}
|
{ avatar }
|
||||||
{linkText}
|
{ linkText }
|
||||||
</span>;
|
</span>;
|
||||||
} else {
|
} else {
|
||||||
// Deliberately render nothing if the URL isn't recognised
|
// Deliberately render nothing if the URL isn't recognised
|
||||||
|
|
|
@ -46,7 +46,7 @@ module.exports = React.createClass({
|
||||||
truncateAt: 2,
|
truncateAt: 2,
|
||||||
createOverflowElement: function(overflowCount, totalCount) {
|
createOverflowElement: function(overflowCount, totalCount) {
|
||||||
return (
|
return (
|
||||||
<div>{_t("And %(count)s more...", {count: overflowCount})}</div>
|
<div>{ _t("And %(count)s more...", {count: overflowCount}) }</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -93,8 +93,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={this.props.className}>
|
<div className={this.props.className}>
|
||||||
{childNodes}
|
{ childNodes }
|
||||||
{overflowNode}
|
{ overflowNode }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default React.createClass({
|
||||||
className="mx_GroupInviteTile_name"
|
className="mx_GroupInviteTile_name"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
>
|
>
|
||||||
{this.props.group.name}
|
{ this.props.group.name }
|
||||||
</EmojiText>;
|
</EmojiText>;
|
||||||
|
|
||||||
const badge = <div className="mx_GroupInviteTile_badge">!</div>;
|
const badge = <div className="mx_GroupInviteTile_badge">!</div>;
|
||||||
|
@ -58,11 +58,11 @@ export default React.createClass({
|
||||||
return (
|
return (
|
||||||
<AccessibleButton className="mx_GroupInviteTile" onClick={this.onClick}>
|
<AccessibleButton className="mx_GroupInviteTile" onClick={this.onClick}>
|
||||||
<div className="mx_GroupInviteTile_avatarContainer">
|
<div className="mx_GroupInviteTile_avatarContainer">
|
||||||
{av}
|
{ av }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupInviteTile_nameContainer">
|
<div className="mx_GroupInviteTile_nameContainer">
|
||||||
{label}
|
{ label }
|
||||||
{badge}
|
{ badge }
|
||||||
</div>
|
</div>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
|
@ -128,7 +128,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
kickButton = (
|
kickButton = (
|
||||||
<AccessibleButton className="mx_MemberInfo_field"
|
<AccessibleButton className="mx_MemberInfo_field"
|
||||||
onClick={this._onKick}>
|
onClick={this._onKick}>
|
||||||
{_t('Remove from group')}
|
{ _t('Remove from group') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -143,11 +143,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
if (kickButton || adminButton) {
|
if (kickButton || adminButton) {
|
||||||
adminTools =
|
adminTools =
|
||||||
<div className="mx_MemberInfo_adminTools">
|
<div className="mx_MemberInfo_adminTools">
|
||||||
<h3>{_t("Admin Tools")}</h3>
|
<h3>{ _t("Admin Tools") }</h3>
|
||||||
|
|
||||||
<div className="mx_MemberInfo_buttons">
|
<div className="mx_MemberInfo_buttons">
|
||||||
{kickButton}
|
{ kickButton }
|
||||||
{adminButton}
|
{ adminButton }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
@ -173,13 +173,13 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
<div className="mx_MemberInfo">
|
<div className="mx_MemberInfo">
|
||||||
<GeminiScrollbar autoshow={true}>
|
<GeminiScrollbar autoshow={true}>
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel"onClick={this._onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel"onClick={this._onCancel}>
|
||||||
<img src="img/cancel.svg" width="18" height="18"/>
|
<img src="img/cancel.svg" width="18" height="18" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<div className="mx_MemberInfo_avatar">
|
<div className="mx_MemberInfo_avatar">
|
||||||
{avatar}
|
{ avatar }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<EmojiText element="h2">{groupMemberName}</EmojiText>
|
<EmojiText element="h2">{ groupMemberName }</EmojiText>
|
||||||
|
|
||||||
<div className="mx_MemberInfo_profile">
|
<div className="mx_MemberInfo_profile">
|
||||||
<div className="mx_MemberInfo_profileField">
|
<div className="mx_MemberInfo_profileField">
|
||||||
|
|
|
@ -124,7 +124,9 @@ export default withMatrixClient(React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.state.fetching) {
|
if (this.state.fetching) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return <Spinner />;
|
return (<div className="mx_MemberList">
|
||||||
|
<Spinner />
|
||||||
|
</div>);
|
||||||
} else if (this.state.members === null) {
|
} else if (this.state.members === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +135,7 @@ export default withMatrixClient(React.createClass({
|
||||||
<form autoComplete="off">
|
<form autoComplete="off">
|
||||||
<input className="mx_GroupMemberList_query" id="mx_GroupMemberList_query" type="text"
|
<input className="mx_GroupMemberList_query" id="mx_GroupMemberList_query" type="text"
|
||||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||||
placeholder={ _t('Filter group members') } />
|
placeholder={_t('Filter group members')} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,7 +146,7 @@ export default withMatrixClient(React.createClass({
|
||||||
<GeminiScrollbar autoshow={true} className="mx_MemberList_joined mx_MemberList_outerWrapper">
|
<GeminiScrollbar autoshow={true} className="mx_MemberList_joined mx_MemberList_outerWrapper">
|
||||||
<TruncatedList className="mx_MemberList_wrapper" truncateAt={this.state.truncateAt}
|
<TruncatedList className="mx_MemberList_wrapper" truncateAt={this.state.truncateAt}
|
||||||
createOverflowElement={this._createOverflowTile}>
|
createOverflowElement={this._createOverflowTile}>
|
||||||
{this.makeGroupMemberTiles(this.state.searchQuery)}
|
{ this.makeGroupMemberTiles(this.state.searchQuery) }
|
||||||
</TruncatedList>
|
</TruncatedList>
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -123,7 +123,7 @@ export default React.createClass({
|
||||||
<form autoComplete="off">
|
<form autoComplete="off">
|
||||||
<input className="mx_GroupRoomList_query" id="mx_GroupRoomList_query" type="text"
|
<input className="mx_GroupRoomList_query" id="mx_GroupRoomList_query" type="text"
|
||||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||||
placeholder={ _t('Filter group rooms') } />
|
placeholder={_t('Filter group rooms')} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ export default React.createClass({
|
||||||
<GeminiScrollbar autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
<GeminiScrollbar autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
||||||
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
||||||
createOverflowElement={this._createOverflowTile}>
|
createOverflowElement={this._createOverflowTile}>
|
||||||
{this.makeGroupRoomTiles(this.state.searchQuery)}
|
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
||||||
</TruncatedList>
|
</TruncatedList>
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -71,10 +71,10 @@ const GroupRoomTile = React.createClass({
|
||||||
return (
|
return (
|
||||||
<AccessibleButton className="mx_GroupRoomTile" onClick={this.onClick}>
|
<AccessibleButton className="mx_GroupRoomTile" onClick={this.onClick}>
|
||||||
<div className="mx_GroupRoomTile_avatar">
|
<div className="mx_GroupRoomTile_avatar">
|
||||||
{av}
|
{ av }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupRoomTile_name">
|
<div className="mx_GroupRoomTile_name">
|
||||||
{name}
|
{ name }
|
||||||
</div>
|
</div>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,7 +25,7 @@ module.exports = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Login_links">
|
<div className="mx_Login_links">
|
||||||
<a href="https://matrix.org">{_t("powered by Matrix")}</a>
|
<a href="https://matrix.org">{ _t("powered by Matrix") }</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,9 +32,9 @@ export default function SenderProfile(props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
|
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
|
||||||
<EmojiText className="mx_SenderProfile_name">{name || ''}</EmojiText>
|
<EmojiText className="mx_SenderProfile_name">{ name || '' }</EmojiText>
|
||||||
{props.enableFlair ? <Flair userId={mxEvent.getSender()} /> : null}
|
{ props.enableFlair ? <Flair userId={mxEvent.getSender()} /> : null }
|
||||||
{props.aux ? <EmojiText className="mx_SenderProfile_aux"> {props.aux}</EmojiText> : null}
|
{ props.aux ? <EmojiText className="mx_SenderProfile_aux"> { props.aux }</EmojiText> : null }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ module.exports = React.createClass({
|
||||||
const text = this.props.mxEvent.getContent().body;
|
const text = this.props.mxEvent.getContent().body;
|
||||||
return (
|
return (
|
||||||
<span className="mx_UnknownBody" title={tooltip}>
|
<span className="mx_UnknownBody" title={tooltip}>
|
||||||
{text}
|
{ text }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -231,16 +231,16 @@ module.exports = React.createClass({
|
||||||
"mx_AddWidget_button"
|
"mx_AddWidget_button"
|
||||||
}
|
}
|
||||||
title={_t('Add a widget')}>
|
title={_t('Add a widget')}>
|
||||||
[+] {_t('Add a widget')}
|
[+] { _t('Add a widget') }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_AppsDrawer">
|
<div className="mx_AppsDrawer">
|
||||||
<div id="apps" className="mx_AppsContainer">
|
<div id="apps" className="mx_AppsContainer">
|
||||||
{apps}
|
{ apps }
|
||||||
</div>
|
</div>
|
||||||
{this._canUserModify() && addWidget}
|
{ this._canUserModify() && addWidget }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -61,7 +61,7 @@ module.exports = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_ForwardMessage">
|
<div className="mx_ForwardMessage">
|
||||||
<h1>{_t('Please select the destination room for this message')}</h1>
|
<h1>{ _t('Please select the destination room for this message') }</h1>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -372,7 +372,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_getChildrenInvited: function(start, end) {
|
_getChildrenInvited: function(start, end) {
|
||||||
return this._makeMemberTiles(this.state.filteredInvitedMembers.slice(start, end));
|
return this._makeMemberTiles(this.state.filteredInvitedMembers.slice(start, end), 'invite');
|
||||||
},
|
},
|
||||||
|
|
||||||
_getChildCountInvited: function() {
|
_getChildCountInvited: function() {
|
||||||
|
|
|
@ -186,18 +186,18 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
saveButton = (
|
saveButton = (
|
||||||
<AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
|
<AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
|
||||||
{_t("Save")}
|
{ _t("Save") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.onCancelClick) {
|
if (this.props.onCancelClick) {
|
||||||
cancelButton = <CancelButton onClick={this.props.onCancelClick}/>;
|
cancelButton = <CancelButton onClick={this.props.onCancelClick} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.saving) {
|
if (this.props.saving) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
spinner = <div className="mx_RoomHeader_spinner"><Spinner/></div>;
|
spinner = <div className="mx_RoomHeader_spinner"><Spinner /></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSetRoomName) {
|
if (canSetRoomName) {
|
||||||
|
@ -254,7 +254,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
if (topic) {
|
if (topic) {
|
||||||
topicElement =
|
topicElement =
|
||||||
<div className="mx_RoomHeader_topic" ref="topic" title={ topic } dir="auto">{ topic }</div>;
|
<div className="mx_RoomHeader_topic" ref="topic" title={topic} dir="auto">{ topic }</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,16 +262,16 @@ module.exports = React.createClass({
|
||||||
if (canSetRoomAvatar) {
|
if (canSetRoomAvatar) {
|
||||||
roomAvatar = (
|
roomAvatar = (
|
||||||
<div className="mx_RoomHeader_avatarPicker">
|
<div className="mx_RoomHeader_avatarPicker">
|
||||||
<div onClick={ this.onAvatarPickerClick }>
|
<div onClick={this.onAvatarPickerClick}>
|
||||||
<ChangeAvatar ref="changeAvatar" room={this.props.room} showUploadSection={false} width={48} height={48} />
|
<ChangeAvatar ref="changeAvatar" room={this.props.room} showUploadSection={false} width={48} height={48} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomHeader_avatarPicker_edit">
|
<div className="mx_RoomHeader_avatarPicker_edit">
|
||||||
<label htmlFor="avatarInput" ref="file_label">
|
<label htmlFor="avatarInput" ref="file_label">
|
||||||
<img src="img/camera.svg"
|
<img src="img/camera.svg"
|
||||||
alt={ _t("Upload avatar") } title={ _t("Upload avatar") }
|
alt={_t("Upload avatar")} title={_t("Upload avatar")}
|
||||||
width="17" height="15" />
|
width="17" height="15" />
|
||||||
</label>
|
</label>
|
||||||
<input id="avatarInput" type="file" onChange={ this.onAvatarSelected }/>
|
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -286,7 +286,7 @@ module.exports = React.createClass({
|
||||||
if (this.props.onSettingsClick) {
|
if (this.props.onSettingsClick) {
|
||||||
settingsButton =
|
settingsButton =
|
||||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
|
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
|
||||||
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
|
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16" />
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,24 +301,24 @@ module.exports = React.createClass({
|
||||||
let forgetButton;
|
let forgetButton;
|
||||||
if (this.props.onForgetClick) {
|
if (this.props.onForgetClick) {
|
||||||
forgetButton =
|
forgetButton =
|
||||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={ _t("Forget room") }>
|
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}>
|
||||||
<TintableSvg src="img/leave.svg" width="26" height="20"/>
|
<TintableSvg src="img/leave.svg" width="26" height="20" />
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let searchButton;
|
let searchButton;
|
||||||
if (this.props.onSearchClick && this.props.inRoom) {
|
if (this.props.onSearchClick && this.props.inRoom) {
|
||||||
searchButton =
|
searchButton =
|
||||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={ _t("Search") }>
|
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}>
|
||||||
<TintableSvg src="img/icons-search.svg" width="35" height="35"/>
|
<TintableSvg src="img/icons-search.svg" width="35" height="35" />
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rightPanelButtons;
|
let rightPanelButtons;
|
||||||
if (this.props.collapsedRhs) {
|
if (this.props.collapsedRhs) {
|
||||||
rightPanelButtons =
|
rightPanelButtons =
|
||||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShowRhsClick} title={ _t('Show panel') }>
|
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShowRhsClick} title={_t('Show panel')}>
|
||||||
<TintableSvg src="img/maximise.svg" width="10" height="16"/>
|
<TintableSvg src="img/maximise.svg" width="10" height="16" />
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ "mx_RoomHeader " + (this.props.editing ? "mx_RoomHeader_editing" : "") }>
|
<div className={"mx_RoomHeader " + (this.props.editing ? "mx_RoomHeader_editing" : "")}>
|
||||||
<div className="mx_RoomHeader_wrapper">
|
<div className="mx_RoomHeader_wrapper">
|
||||||
<div className="mx_RoomHeader_leftRow">
|
<div className="mx_RoomHeader_leftRow">
|
||||||
<div className="mx_RoomHeader_avatar">
|
<div className="mx_RoomHeader_avatar">
|
||||||
|
@ -353,10 +353,10 @@ module.exports = React.createClass({
|
||||||
{ topicElement }
|
{ topicElement }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{spinner}
|
{ spinner }
|
||||||
{saveButton}
|
{ saveButton }
|
||||||
{cancelButton}
|
{ cancelButton }
|
||||||
{rightRow}
|
{ rightRow }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function CancelButton(props) {
|
||||||
return (
|
return (
|
||||||
<AccessibleButton className='mx_RoomHeader_cancelButton' onClick={onClick}>
|
<AccessibleButton className='mx_RoomHeader_cancelButton' onClick={onClick}>
|
||||||
<img src="img/cancel.svg" className='mx_filterFlipColor'
|
<img src="img/cancel.svg" className='mx_filterFlipColor'
|
||||||
width="18" height="18" alt={_t("Cancel")}/>
|
width="18" height="18" alt={_t("Cancel")} />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,17 +129,17 @@ module.exports = React.createClass({
|
||||||
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
||||||
const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
||||||
voice = (
|
voice = (
|
||||||
<div className="mx_CallView_voice" onClick={ this.props.onClick }>
|
<div className="mx_CallView_voice" onClick={this.props.onClick}>
|
||||||
{_t("Active call (%(roomName)s)", {roomName: callRoom.name})}
|
{ _t("Active call (%(roomName)s)", {roomName: callRoom.name}) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<VideoView ref="video" onClick={ this.props.onClick }
|
<VideoView ref="video" onClick={this.props.onClick}
|
||||||
onResize={ this.props.onResize }
|
onResize={this.props.onResize}
|
||||||
maxHeight={ this.props.maxVideoHeight }
|
maxHeight={this.props.maxVideoHeight}
|
||||||
/>
|
/>
|
||||||
{ voice }
|
{ voice }
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -62,17 +62,17 @@ module.exports = React.createClass({
|
||||||
<div className="mx_IncomingCallBox" id="incomingCallBox">
|
<div className="mx_IncomingCallBox" id="incomingCallBox">
|
||||||
<img className="mx_IncomingCallBox_chevron" src="img/chevron-left.png" width="9" height="16" />
|
<img className="mx_IncomingCallBox_chevron" src="img/chevron-left.png" width="9" height="16" />
|
||||||
<div className="mx_IncomingCallBox_title">
|
<div className="mx_IncomingCallBox_title">
|
||||||
{incomingCallText}
|
{ incomingCallText }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_IncomingCallBox_buttons">
|
<div className="mx_IncomingCallBox_buttons">
|
||||||
<div className="mx_IncomingCallBox_buttons_cell">
|
<div className="mx_IncomingCallBox_buttons_cell">
|
||||||
<div className="mx_IncomingCallBox_buttons_decline" onClick={this.onRejectClick}>
|
<div className="mx_IncomingCallBox_buttons_decline" onClick={this.onRejectClick}>
|
||||||
{_t("Decline")}
|
{ _t("Decline") }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_IncomingCallBox_buttons_cell">
|
<div className="mx_IncomingCallBox_buttons_cell">
|
||||||
<div className="mx_IncomingCallBox_buttons_accept" onClick={this.onAnswerClick}>
|
<div className="mx_IncomingCallBox_buttons_accept" onClick={this.onAnswerClick}>
|
||||||
{_t("Accept")}
|
{ _t("Accept") }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -110,13 +110,13 @@ module.exports = React.createClass({
|
||||||
const maxVideoHeight = fullscreenElement ? null : this.props.maxHeight;
|
const maxVideoHeight = fullscreenElement ? null : this.props.maxHeight;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_VideoView" ref={this.setContainer} onClick={ this.props.onClick }>
|
<div className="mx_VideoView" ref={this.setContainer} onClick={this.props.onClick}>
|
||||||
<div className="mx_VideoView_remoteVideoFeed">
|
<div className="mx_VideoView_remoteVideoFeed">
|
||||||
<VideoFeed ref="remote" onResize={this.props.onResize}
|
<VideoFeed ref="remote" onResize={this.props.onResize}
|
||||||
maxHeight={maxVideoHeight} />
|
maxHeight={maxVideoHeight} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_VideoView_localVideoFeed">
|
<div className="mx_VideoView_localVideoFeed">
|
||||||
<VideoFeed ref="local"/>
|
<VideoFeed ref="local" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -734,7 +734,6 @@
|
||||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und das Gerät %(deviceId)s ist \"%(fprint)s\", welcher nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Dies kann bedeuten, dass deine Kommunikation abgehört wird!",
|
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und das Gerät %(deviceId)s ist \"%(fprint)s\", welcher nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Dies kann bedeuten, dass deine Kommunikation abgehört wird!",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>deaktiviert</a>.",
|
"You have <a>disabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>deaktiviert</a>.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>aktiviert</a>.",
|
"You have <a>enabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>aktiviert</a>.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Du hast einen ungültigen Kontakt eingegeben. Versuche es mit der Matrix-Kennung oder der E-Mail-Adresse des Kontakts.",
|
|
||||||
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName hat das Raum-Bild geändert zu <img/>",
|
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName hat das Raum-Bild geändert zu <img/>",
|
||||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s hat das Raum-Bild für %(roomName)s geändert",
|
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s hat das Raum-Bild für %(roomName)s geändert",
|
||||||
"Hide removed messages": "Gelöschte Nachrichten verbergen",
|
"Hide removed messages": "Gelöschte Nachrichten verbergen",
|
||||||
|
|
|
@ -685,7 +685,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Έχετε αποσυνδεθεί από όλες τις συσκευές και δεν θα λαμβάνετε πλέον ειδοποιήσεις push. Για να ενεργοποιήσετε τις ειδοποιήσεις, συνδεθείτε ξανά σε κάθε συσκευή",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Έχετε αποσυνδεθεί από όλες τις συσκευές και δεν θα λαμβάνετε πλέον ειδοποιήσεις push. Για να ενεργοποιήσετε τις ειδοποιήσεις, συνδεθείτε ξανά σε κάθε συσκευή",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Έχετε <a>απενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
"You have <a>disabled</a> URL previews by default.": "Έχετε <a>απενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Έχετε <a>ενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
"You have <a>enabled</a> URL previews by default.": "Έχετε <a>ενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Έχετε πληκτρολογήσει μια άκυρη επαφή. Χρησιμοποιήστε το Matrix ID ή την ηλεκτρονική διεύθυνση αλληλογραφίας τους.",
|
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Μπορεί να θέλετε να συνδεθείτε με διαφορετικό λογαριασμό, ή να προσθέσετε αυτή τη διεύθυνση ηλεκτρονικής αλληλογραφίας σε αυτόν τον λογαριασμό.",
|
"You may wish to login with a different account, or add this email to this account.": "Μπορεί να θέλετε να συνδεθείτε με διαφορετικό λογαριασμό, ή να προσθέσετε αυτή τη διεύθυνση ηλεκτρονικής αλληλογραφίας σε αυτόν τον λογαριασμό.",
|
||||||
"You need to be able to invite users to do that.": "Για να το κάνετε αυτό πρέπει να έχετε τη δυνατότητα να προσκαλέσετε χρήστες.",
|
"You need to be able to invite users to do that.": "Για να το κάνετε αυτό πρέπει να έχετε τη δυνατότητα να προσκαλέσετε χρήστες.",
|
||||||
"You seem to be uploading files, are you sure you want to quit?": "Φαίνεται ότι αποστέλετε αρχεία, είστε βέβαιοι ότι θέλετε να αποχωρήσετε;",
|
"You seem to be uploading files, are you sure you want to quit?": "Φαίνεται ότι αποστέλετε αρχεία, είστε βέβαιοι ότι θέλετε να αποχωρήσετε;",
|
||||||
|
|
|
@ -554,7 +554,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device",
|
||||||
"You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
|
"You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
|
"You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "You have entered an invalid contact. Try using their Matrix ID or email address.",
|
|
||||||
"You have no visible notifications": "You have no visible notifications",
|
"You have no visible notifications": "You have no visible notifications",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.",
|
"You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.",
|
||||||
"you must be a": "you must be a",
|
"you must be a": "you must be a",
|
||||||
|
@ -894,5 +893,10 @@
|
||||||
"Unpublish": "Unpublish",
|
"Unpublish": "Unpublish",
|
||||||
"This group is published on your profile": "This group is published on your profile",
|
"This group is published on your profile": "This group is published on your profile",
|
||||||
"Publish": "Publish",
|
"Publish": "Publish",
|
||||||
"This group is not published on your profile": "This group is not published on your profile"
|
"This group is not published on your profile": "This group is not published on your profile",
|
||||||
|
"Matrix ID": "Matrix ID",
|
||||||
|
"Matrix Room ID": "Matrix Room ID",
|
||||||
|
"email address": "email address",
|
||||||
|
"Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.",
|
||||||
|
"You have entered an invalid address.": "You have entered an invalid address."
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,7 +478,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device",
|
||||||
"You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
|
"You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
|
"You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "You have entered an invalid contact. Try using their Matrix ID or email address.",
|
|
||||||
"You have no visible notifications": "You have no visible notifications",
|
"You have no visible notifications": "You have no visible notifications",
|
||||||
"you must be a": "you must be a",
|
"you must be a": "you must be a",
|
||||||
"You need to be able to invite users to do that.": "You need to be able to invite users to do that.",
|
"You need to be able to invite users to do that.": "You need to be able to invite users to do that.",
|
||||||
|
|
|
@ -621,7 +621,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Ha sido desconectado de todos los dispositivos y no continuara recibiendo notificaciones. Para volver a habilitar las notificaciones, vuelva a conectarse en cada dispositivo",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Ha sido desconectado de todos los dispositivos y no continuara recibiendo notificaciones. Para volver a habilitar las notificaciones, vuelva a conectarse en cada dispositivo",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Ha <a>deshabilitado</a> la vista previa de URL por defecto.",
|
"You have <a>disabled</a> URL previews by default.": "Ha <a>deshabilitado</a> la vista previa de URL por defecto.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Ha <a>habilitado</a> vista previa de URL por defecto.",
|
"You have <a>enabled</a> URL previews by default.": "Ha <a>habilitado</a> vista previa de URL por defecto.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Ha ingresado un contacto no valido. Intente usando la ID Matrix o e-mail del contacto.",
|
|
||||||
"You have no visible notifications": "No tiene notificaciones visibles",
|
"You have no visible notifications": "No tiene notificaciones visibles",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Puede ingresar con una cuenta diferente, o agregar este e-mail a esta cuenta.",
|
"You may wish to login with a different account, or add this email to this account.": "Puede ingresar con una cuenta diferente, o agregar este e-mail a esta cuenta.",
|
||||||
"you must be a": "usted debe ser un",
|
"you must be a": "usted debe ser un",
|
||||||
|
|
|
@ -555,7 +555,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Saioa amaitu duzu eta ez dituzu jakinarazpenak jasoko. Jakinarazpenak jaso nahi badituzu hasi saioa berriro gailu bakoitzean",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Saioa amaitu duzu eta ez dituzu jakinarazpenak jasoko. Jakinarazpenak jaso nahi badituzu hasi saioa berriro gailu bakoitzean",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Lehenetsita URLak aurreikustea <a>desgaitu</a> duzu.",
|
"You have <a>disabled</a> URL previews by default.": "Lehenetsita URLak aurreikustea <a>desgaitu</a> duzu.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Lehenetsita URLak aurreikustea <a>gaitu</a> duzu.",
|
"You have <a>enabled</a> URL previews by default.": "Lehenetsita URLak aurreikustea <a>gaitu</a> duzu.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Kontaktu baliogabea sartu duzu. Saiatu bere Matrix ID-a edo e-mail helbidea erabiltzen.",
|
|
||||||
"You have no visible notifications": "Ez daukazu jakinarazpen ikusgairik",
|
"You have no visible notifications": "Ez daukazu jakinarazpen ikusgairik",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Agian beste kontu batekin hasi nahi duzu saioa, edo e-mail hau kontu honetara gehitu.",
|
"You may wish to login with a different account, or add this email to this account.": "Agian beste kontu batekin hasi nahi duzu saioa, edo e-mail hau kontu honetara gehitu.",
|
||||||
"you must be a": "hau izan behar duzu:",
|
"you must be a": "hau izan behar duzu:",
|
||||||
|
|
|
@ -679,7 +679,6 @@
|
||||||
"Tagged as: ": "Étiquetter comme : ",
|
"Tagged as: ": "Étiquetter comme : ",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Vous avez <a>désactivé</a> les aperçus d’URL par défaut.",
|
"You have <a>disabled</a> URL previews by default.": "Vous avez <a>désactivé</a> les aperçus d’URL par défaut.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Vous avez <a>activé</a> les aperçus d’URL par défaut.",
|
"You have <a>enabled</a> URL previews by default.": "Vous avez <a>activé</a> les aperçus d’URL par défaut.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Vous avez entré un contact invalide. Essayez d’utiliser leur identifiant Matrix ou leur adresse email.",
|
|
||||||
"Hide removed messages": "Cacher les messages supprimés",
|
"Hide removed messages": "Cacher les messages supprimés",
|
||||||
"Add": "Ajouter",
|
"Add": "Ajouter",
|
||||||
"%(count)s new messages|one": "%(count)s nouveau message",
|
"%(count)s new messages|one": "%(count)s nouveau message",
|
||||||
|
|
|
@ -529,7 +529,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Kijelentkeztél minden eszközről így nem fogsz \"push\" értesítéseket kapni. Az értesítések engedélyezéséhez jelentkezz vissza mindegyik eszközön",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Kijelentkeztél minden eszközről így nem fogsz \"push\" értesítéseket kapni. Az értesítések engedélyezéséhez jelentkezz vissza mindegyik eszközön",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Az URL előnézet alapból <a>tiltva</a> van.",
|
"You have <a>disabled</a> URL previews by default.": "Az URL előnézet alapból <a>tiltva</a> van.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Az URL előnézet alapból <a>engedélyezve</a> van.",
|
"You have <a>enabled</a> URL previews by default.": "Az URL előnézet alapból <a>engedélyezve</a> van.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Érvénytelen kapcsolatot adtál meg. Próbáld meg a Matrix azonosítóját vagy e-mail címét használni.",
|
|
||||||
"You have no visible notifications": "Nincsenek látható értesítéseid",
|
"You have no visible notifications": "Nincsenek látható értesítéseid",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Lehet, hogy más fiókba szeretnél belépni vagy ezt az e-mail címet szeretnéd ehhez a fiókhoz kötni.",
|
"You may wish to login with a different account, or add this email to this account.": "Lehet, hogy más fiókba szeretnél belépni vagy ezt az e-mail címet szeretnéd ehhez a fiókhoz kötni.",
|
||||||
"you must be a": "szükséges szerep:",
|
"you must be a": "szükséges szerep:",
|
||||||
|
|
|
@ -535,7 +535,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "모든 장치에서 로그아웃되었고 더 이상 알림을 받지 않으실 거에요. 다시 알림을 받으시려면, 각 장치에 로그인해주세요",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "모든 장치에서 로그아웃되었고 더 이상 알림을 받지 않으실 거에요. 다시 알림을 받으시려면, 각 장치에 로그인해주세요",
|
||||||
"You have <a>disabled</a> URL previews by default.": "URL 미리보기 <a>쓰지 않기</a>를 기본으로 하셨어요.",
|
"You have <a>disabled</a> URL previews by default.": "URL 미리보기 <a>쓰지 않기</a>를 기본으로 하셨어요.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "URL 미리보기 <a>쓰기</a>를 기본으로 하셨어요.",
|
"You have <a>enabled</a> URL previews by default.": "URL 미리보기 <a>쓰기</a>를 기본으로 하셨어요.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "잘못된 연락처를 입력하셨어요. 매트릭스 ID나 이메일 주소를 써보세요.",
|
|
||||||
"You have no visible notifications": "보여드릴 알림이 없어요",
|
"You have no visible notifications": "보여드릴 알림이 없어요",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "다른 계정으로 로그인하거나, 이 이메일을 이 계정에 추가할 수도 있어요.",
|
"You may wish to login with a different account, or add this email to this account.": "다른 계정으로 로그인하거나, 이 이메일을 이 계정에 추가할 수도 있어요.",
|
||||||
"you must be a": "해야해요",
|
"you must be a": "해야해요",
|
||||||
|
|
|
@ -593,7 +593,6 @@
|
||||||
"You cannot place VoIP calls in this browser.": "Tu nevari veikt VoIP zvanus šajā pārlūkā.",
|
"You cannot place VoIP calls in this browser.": "Tu nevari veikt VoIP zvanus šajā pārlūkā.",
|
||||||
"You do not have permission to post to this room": "Tev nav vajadzīgās atļaujas pievienot ziņas šajā istabā",
|
"You do not have permission to post to this room": "Tev nav vajadzīgās atļaujas pievienot ziņas šajā istabā",
|
||||||
"You have <a>disabled</a> URL previews by default.": "URL priekšskatījums pēc noklusējuma Tev ir <a>atspējots</a>.",
|
"You have <a>disabled</a> URL previews by default.": "URL priekšskatījums pēc noklusējuma Tev ir <a>atspējots</a>.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Tu ievadīji nepareizu kontaktu. Mēģini izmantot viņa Matrix ID vai epasta adresi.",
|
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Tu varētu, iespējams, vēlēties pierakstīties no cita konta vai piesaistīt šo epastu šim kontam.",
|
"You may wish to login with a different account, or add this email to this account.": "Tu varētu, iespējams, vēlēties pierakstīties no cita konta vai piesaistīt šo epastu šim kontam.",
|
||||||
"you must be a": "Tev ir jābūt",
|
"you must be a": "Tev ir jābūt",
|
||||||
"You must <a>register</a> to use this functionality": "Lai izmantotu šo funkcionalitāti, Tev ir <a>jāreģistrējas</a>",
|
"You must <a>register</a> to use this functionality": "Lai izmantotu šo funkcionalitāti, Tev ir <a>jāreģistrējas</a>",
|
||||||
|
|
|
@ -560,7 +560,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Je bent op alle apparaten uitgelegd en je zal niet langer notificaties ontvangen. Om notificaties weer aan te zetten, log op elk apparaat opnieuw in",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Je bent op alle apparaten uitgelegd en je zal niet langer notificaties ontvangen. Om notificaties weer aan te zetten, log op elk apparaat opnieuw in",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Je hebt URL-voorvertoningen standaard <a>uitgezet</a>.",
|
"You have <a>disabled</a> URL previews by default.": "Je hebt URL-voorvertoningen standaard <a>uitgezet</a>.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Je hebt URL-voorvertoningen standaard <a>aangezet</a>.",
|
"You have <a>enabled</a> URL previews by default.": "Je hebt URL-voorvertoningen standaard <a>aangezet</a>.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Je hebt een ongeldig contact ingevoerd. Probeer zijn of haar Matrix-ID of e-mailadres te gebruiken.",
|
|
||||||
"You have no visible notifications": "Je hebt geen zichtbare notificaties",
|
"You have no visible notifications": "Je hebt geen zichtbare notificaties",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Je wilt misschien met een ander account inloggen of deze e-mail aan je account toevoegen.",
|
"You may wish to login with a different account, or add this email to this account.": "Je wilt misschien met een ander account inloggen of deze e-mail aan je account toevoegen.",
|
||||||
"you must be a": "wat je moet zijn is een",
|
"you must be a": "wat je moet zijn is een",
|
||||||
|
|
|
@ -603,7 +603,6 @@
|
||||||
"You have been kicked from %(roomName)s by %(userName)s.": "Zostałeś usunięty z %(roomName)s przez %(userName)s.",
|
"You have been kicked from %(roomName)s by %(userName)s.": "Zostałeś usunięty z %(roomName)s przez %(userName)s.",
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Wylogowałeś się ze wszystkich urządzeń i nie będziesz już otrzymywał powiadomień push. Aby ponownie aktywować powiadomienia zaloguj się ponownie na każdym urządzeniu",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Wylogowałeś się ze wszystkich urządzeń i nie będziesz już otrzymywał powiadomień push. Aby ponownie aktywować powiadomienia zaloguj się ponownie na każdym urządzeniu",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Masz domyślnie <a>wyłączone</a> podglądy linków.",
|
"You have <a>disabled</a> URL previews by default.": "Masz domyślnie <a>wyłączone</a> podglądy linków.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Wpisałeś niewłaściwy kontakt. Spróbuj używając Matrix ID lub adresu e-mail.",
|
|
||||||
"You have no visible notifications": "Nie masz widocznych powiadomień",
|
"You have no visible notifications": "Nie masz widocznych powiadomień",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Możesz chcieć zalogować się z innego konta lub dodać e-mail do tego konta.",
|
"You may wish to login with a different account, or add this email to this account.": "Możesz chcieć zalogować się z innego konta lub dodać e-mail do tego konta.",
|
||||||
"you must be a": "musisz być",
|
"you must be a": "musisz być",
|
||||||
|
|
|
@ -733,7 +733,6 @@
|
||||||
"Tagged as: ": "Marcado como: ",
|
"Tagged as: ": "Marcado como: ",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Você <a>desabilitou</a> pré-visualizações de links por padrão.",
|
"You have <a>disabled</a> URL previews by default.": "Você <a>desabilitou</a> pré-visualizações de links por padrão.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Você <a>habilitou</a> pré-visualizações de links por padrão.",
|
"You have <a>enabled</a> URL previews by default.": "Você <a>habilitou</a> pré-visualizações de links por padrão.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Você inseriu um contato inválido. Tente usar o ID Matrix ou endereço de e-mail da pessoa que está buscando.",
|
|
||||||
"You have been banned from %(roomName)s by %(userName)s.": "Você foi expulso(a) da sala %(roomName)s por %(userName)s.",
|
"You have been banned from %(roomName)s by %(userName)s.": "Você foi expulso(a) da sala %(roomName)s por %(userName)s.",
|
||||||
"Send anyway": "Enviar de qualquer maneira",
|
"Send anyway": "Enviar de qualquer maneira",
|
||||||
"This room": "Esta sala",
|
"This room": "Esta sala",
|
||||||
|
|
|
@ -730,7 +730,6 @@
|
||||||
"Tagged as: ": "Marcado como: ",
|
"Tagged as: ": "Marcado como: ",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Você <a>desabilitou</a> pré-visualizações de links por padrão.",
|
"You have <a>disabled</a> URL previews by default.": "Você <a>desabilitou</a> pré-visualizações de links por padrão.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Você <a>habilitou</a> pré-visualizações de links por padrão.",
|
"You have <a>enabled</a> URL previews by default.": "Você <a>habilitou</a> pré-visualizações de links por padrão.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Você inseriu um contato inválido. Tente usar o ID Matrix ou endereço de e-mail da pessoa que está buscando.",
|
|
||||||
"Hide removed messages": "Ocultar mensagens removidas",
|
"Hide removed messages": "Ocultar mensagens removidas",
|
||||||
"Add": "Adicionar",
|
"Add": "Adicionar",
|
||||||
"%(count)s new messages|one": "%(count)s nova mensagem",
|
"%(count)s new messages|one": "%(count)s nova mensagem",
|
||||||
|
|
|
@ -618,7 +618,6 @@
|
||||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!",
|
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!",
|
||||||
"You have <a>disabled</a> URL previews by default.": "Предварительный просмотр ссылок <a>отключен</a> по-умолчанию.",
|
"You have <a>disabled</a> URL previews by default.": "Предварительный просмотр ссылок <a>отключен</a> по-умолчанию.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "Предварительный просмотр ссылок <a>включен</a> по-умолчанию.",
|
"You have <a>enabled</a> URL previews by default.": "Предварительный просмотр ссылок <a>включен</a> по-умолчанию.",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес электронной почты.",
|
|
||||||
"You need to enter a user name.": "Необходимо ввести имя пользователя.",
|
"You need to enter a user name.": "Необходимо ввести имя пользователя.",
|
||||||
"You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?",
|
"You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?",
|
||||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.",
|
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.",
|
||||||
|
|
|
@ -516,7 +516,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Tüm cihazlardan çıkış yaptınız ve artık bildirimler almayacaksınız . Bildirimleri yeniden etkinleştirmek için , her cihazda tekrar giriş yapın",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Tüm cihazlardan çıkış yaptınız ve artık bildirimler almayacaksınız . Bildirimleri yeniden etkinleştirmek için , her cihazda tekrar giriş yapın",
|
||||||
"You have <a>disabled</a> URL previews by default.": "URL önizlemelerini varsayılan olarak <a> devre dışı </a> bıraktınız.",
|
"You have <a>disabled</a> URL previews by default.": "URL önizlemelerini varsayılan olarak <a> devre dışı </a> bıraktınız.",
|
||||||
"You have <a>enabled</a> URL previews by default.": "URL önizlemelerini varsayılan olarak <a> etkinleştirdiniz </a> .",
|
"You have <a>enabled</a> URL previews by default.": "URL önizlemelerini varsayılan olarak <a> etkinleştirdiniz </a> .",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "Geçersiz bir kişi girdiniz . Matrix ID veya e-posta adresini kullanarak tekrar deneyin.",
|
|
||||||
"You have no visible notifications": "Hiçbir görünür bildiriminiz yok",
|
"You have no visible notifications": "Hiçbir görünür bildiriminiz yok",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "Farklı bir hesap ile giriş yapmak veya bu e-postayı bu hesaba eklemek istemiş olabilirsiniz.",
|
"You may wish to login with a different account, or add this email to this account.": "Farklı bir hesap ile giriş yapmak veya bu e-postayı bu hesaba eklemek istemiş olabilirsiniz.",
|
||||||
"you must be a": "olabilirsiniz",
|
"you must be a": "olabilirsiniz",
|
||||||
|
|
|
@ -630,7 +630,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "你已经登出了所有的设备并不再接收推送通知。要重新启用通知,请再在每个设备上登录",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "你已经登出了所有的设备并不再接收推送通知。要重新启用通知,请再在每个设备上登录",
|
||||||
"You have <a>disabled</a> URL previews by default.": "你已经默认 <a>禁用</a> URL 预览。",
|
"You have <a>disabled</a> URL previews by default.": "你已经默认 <a>禁用</a> URL 预览。",
|
||||||
"You have <a>enabled</a> URL previews by default.": "你已经默认 <a>启用</a> URL 预览。",
|
"You have <a>enabled</a> URL previews by default.": "你已经默认 <a>启用</a> URL 预览。",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "你输入了一个非法的联系人。尝试使用他们的 Matrix ID 或者电子邮件地址。",
|
|
||||||
"Your home server does not support device management.": "你的 home server 不支持设备管理。",
|
"Your home server does not support device management.": "你的 home server 不支持设备管理。",
|
||||||
"Set a display name:": "设置一个昵称:",
|
"Set a display name:": "设置一个昵称:",
|
||||||
"This server does not support authentication with a phone number.": "这个服务器不支持用电话号码认证。",
|
"This server does not support authentication with a phone number.": "这个服务器不支持用电话号码认证。",
|
||||||
|
|
|
@ -574,7 +574,6 @@
|
||||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "您已在所有裝置上登出,並且不會再收到推送通知。要重新啟用通知,再次於每個裝置上登入",
|
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "您已在所有裝置上登出,並且不會再收到推送通知。要重新啟用通知,再次於每個裝置上登入",
|
||||||
"You have <a>disabled</a> URL previews by default.": "您已預設<a>停用</a> URL 預覽。",
|
"You have <a>disabled</a> URL previews by default.": "您已預設<a>停用</a> URL 預覽。",
|
||||||
"You have <a>enabled</a> URL previews by default.": "您已預設<a>啟用</a> URL 預覽。",
|
"You have <a>enabled</a> URL previews by default.": "您已預設<a>啟用</a> URL 預覽。",
|
||||||
"You have entered an invalid contact. Try using their Matrix ID or email address.": "您輸入了無效的聯絡人。嘗試使用他們的 Matrix ID 或電子郵件地址。",
|
|
||||||
"You have no visible notifications": "您沒有可見的通知",
|
"You have no visible notifications": "您沒有可見的通知",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "您可能會想要以不同的帳號登入,或是把這個電子郵件加入到此帳號中。",
|
"You may wish to login with a different account, or add this email to this account.": "您可能會想要以不同的帳號登入,或是把這個電子郵件加入到此帳號中。",
|
||||||
"you must be a": "您一定是",
|
"you must be a": "您一定是",
|
||||||
|
|
Loading…
Reference in a new issue