Merge branch 'develop' into luke/groups-button
This commit is contained in:
commit
739ddb8410
67 changed files with 388 additions and 376 deletions
13
.eslintrc.js
13
.eslintrc.js
|
@ -40,6 +40,19 @@ module.exports = {
|
|||
}],
|
||||
"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/require-parameter-type": ["warn", {
|
||||
"excludeArrowFunctions": true,
|
||||
|
|
|
@ -21,9 +21,7 @@ npm run test -- --no-colors
|
|||
npm run lintall -- -f checkstyle -o eslint.xml || true
|
||||
|
||||
# re-run the linter, excluding any files known to have errors or warnings.
|
||||
./node_modules/.bin/eslint --max-warnings 0 \
|
||||
--ignore-path .eslintignore.errorfiles \
|
||||
src test
|
||||
npm run lintwithexclusions
|
||||
|
||||
# delete the old tarball, if it exists
|
||||
rm -f matrix-react-sdk-*.tgz
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
"start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"",
|
||||
"lint": "eslint src/",
|
||||
"lintall": "eslint src/ test/",
|
||||
"lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test",
|
||||
"clean": "rimraf lib",
|
||||
"prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt",
|
||||
"test": "karma start --single-run=true --browsers ChromeHeadless",
|
||||
|
@ -99,7 +100,7 @@
|
|||
"eslint-config-google": "^0.7.1",
|
||||
"eslint-plugin-babel": "^4.0.1",
|
||||
"eslint-plugin-flowtype": "^2.30.0",
|
||||
"eslint-plugin-react": "^6.9.0",
|
||||
"eslint-plugin-react": "^7.4.0",
|
||||
"expect": "^1.16.0",
|
||||
"json-loader": "^0.5.3",
|
||||
"karma": "^1.7.0",
|
||||
|
|
|
@ -6,6 +6,4 @@ npm run test
|
|||
./.travis-test-riot.sh
|
||||
|
||||
# run the linter, but exclude any files known to have errors or warnings.
|
||||
./node_modules/.bin/eslint --max-warnings 0 \
|
||||
--ignore-path .eslintignore.errorfiles \
|
||||
src test
|
||||
npm run lintwithexclusions
|
||||
|
|
|
@ -28,7 +28,7 @@ export function inviteToRoom(roomId, addr) {
|
|||
|
||||
if (addrType == 'email') {
|
||||
return MatrixClientPeg.get().inviteByEmail(roomId, addr);
|
||||
} else if (addrType == 'mx') {
|
||||
} else if (addrType == 'mx-user-id') {
|
||||
return MatrixClientPeg.get().invite(roomId, addr);
|
||||
} else {
|
||||
throw new Error('Unsupported address');
|
||||
|
|
|
@ -254,7 +254,7 @@ const commands = {
|
|||
title: _t("Ignored user"),
|
||||
description: (
|
||||
<div>
|
||||
<p>{_t("You are now ignoring %(userId)s", {userId: userId})}</p>
|
||||
<p>{ _t("You are now ignoring %(userId)s", {userId: userId}) }</p>
|
||||
</div>
|
||||
),
|
||||
hasCancelButton: false,
|
||||
|
@ -281,7 +281,7 @@ const commands = {
|
|||
title: _t("Unignored user"),
|
||||
description: (
|
||||
<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>
|
||||
),
|
||||
hasCancelButton: false,
|
||||
|
|
|
@ -136,13 +136,13 @@ export default React.createClass({
|
|||
) }
|
||||
</p>
|
||||
<div className='error'>
|
||||
{this.state.errStr}
|
||||
{ this.state.errStr }
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputTable'>
|
||||
<div className='mx_E2eKeysDialog_inputRow'>
|
||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||
<label htmlFor='passphrase1'>
|
||||
{_t("Enter passphrase")}
|
||||
{ _t("Enter passphrase") }
|
||||
</label>
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputCell'>
|
||||
|
@ -155,7 +155,7 @@ export default React.createClass({
|
|||
<div className='mx_E2eKeysDialog_inputRow'>
|
||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||
<label htmlFor='passphrase2'>
|
||||
{_t("Confirm passphrase")}
|
||||
{ _t("Confirm passphrase") }
|
||||
</label>
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputCell'>
|
||||
|
@ -172,7 +172,7 @@ export default React.createClass({
|
|||
disabled={disableForm}
|
||||
/>
|
||||
<button onClick={this._onCancelClick} disabled={disableForm}>
|
||||
{_t("Cancel")}
|
||||
{ _t("Cancel") }
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -134,13 +134,13 @@ export default React.createClass({
|
|||
) }
|
||||
</p>
|
||||
<div className='error'>
|
||||
{this.state.errStr}
|
||||
{ this.state.errStr }
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputTable'>
|
||||
<div className='mx_E2eKeysDialog_inputRow'>
|
||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||
<label htmlFor='importFile'>
|
||||
{_t("File to import")}
|
||||
{ _t("File to import") }
|
||||
</label>
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputCell'>
|
||||
|
@ -153,14 +153,14 @@ export default React.createClass({
|
|||
<div className='mx_E2eKeysDialog_inputRow'>
|
||||
<div className='mx_E2eKeysDialog_inputLabel'>
|
||||
<label htmlFor='passphrase'>
|
||||
{_t("Enter passphrase")}
|
||||
{ _t("Enter passphrase") }
|
||||
</label>
|
||||
</div>
|
||||
<div className='mx_E2eKeysDialog_inputCell'>
|
||||
<input ref='passphrase' id='passphrase'
|
||||
size='64' type='password'
|
||||
onChange={this._onFormChange}
|
||||
disabled={disableForm}/>
|
||||
disabled={disableForm} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -170,7 +170,7 @@ export default React.createClass({
|
|||
disabled={!this.state.enableSubmit || disableForm}
|
||||
/>
|
||||
<button onClick={this._onCancelClick} disabled={disableForm}>
|
||||
{_t("Cancel")}
|
||||
{ _t("Cancel") }
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -129,7 +129,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
|||
component: (<TextualCompletion
|
||||
title={result.command}
|
||||
subtitle={result.args}
|
||||
description={ _t(result.description) }
|
||||
description={_t(result.description)}
|
||||
/>),
|
||||
range,
|
||||
};
|
||||
|
@ -150,7 +150,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
|||
|
||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||
return <div className="mx_Autocomplete_Completion_container_block">
|
||||
{completions}
|
||||
{ completions }
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
|||
|
||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||
return <div className="mx_Autocomplete_Completion_container_pill mx_Autocomplete_Completion_container_truncate">
|
||||
{completions}
|
||||
{ completions }
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ const CategoryRoomList = React.createClass({
|
|||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
const addButton = this.props.editing ?
|
||||
(<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">
|
||||
{_t('Add a Room')}
|
||||
{ _t('Add a Room') }
|
||||
</div>
|
||||
</AccessibleButton>) : <div />;
|
||||
|
||||
|
@ -117,17 +117,19 @@ const CategoryRoomList = React.createClass({
|
|||
key={r.room_id}
|
||||
groupId={this.props.groupId}
|
||||
editing={this.props.editing}
|
||||
summaryInfo={r}/>;
|
||||
summaryInfo={r} />;
|
||||
});
|
||||
|
||||
let catHeader = <div />;
|
||||
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">
|
||||
{catHeader}
|
||||
{roomNodes}
|
||||
{addButton}
|
||||
{ catHeader }
|
||||
{ roomNodes }
|
||||
{ addButton }
|
||||
</div>;
|
||||
},
|
||||
});
|
||||
|
@ -196,9 +198,9 @@ const FeaturedRoom = React.createClass({
|
|||
|
||||
let roomNameNode = null;
|
||||
if (permalink) {
|
||||
roomNameNode = <a href={permalink} onClick={this.onClick} >{roomName}</a>;
|
||||
roomNameNode = <a href={permalink} onClick={this.onClick} >{ roomName }</a>;
|
||||
} else {
|
||||
roomNameNode = <span>{roomName}</span>;
|
||||
roomNameNode = <span>{ roomName }</span>;
|
||||
}
|
||||
|
||||
const deleteButton = this.props.editing ?
|
||||
|
@ -208,13 +210,13 @@ const FeaturedRoom = React.createClass({
|
|||
width="14"
|
||||
height="14"
|
||||
alt="Delete"
|
||||
onClick={this.onDeleteClicked}/>
|
||||
onClick={this.onDeleteClicked} />
|
||||
: <div />;
|
||||
|
||||
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
||||
<RoomAvatar oobData={oobData} width={64} height={64} />
|
||||
<div className="mx_GroupView_featuredThing_name">{roomNameNode}</div>
|
||||
{deleteButton}
|
||||
<div className="mx_GroupView_featuredThing_name">{ roomNameNode }</div>
|
||||
{ deleteButton }
|
||||
</AccessibleButton>;
|
||||
},
|
||||
});
|
||||
|
@ -278,9 +280,9 @@ const RoleUserList = React.createClass({
|
|||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
const addButton = this.props.editing ?
|
||||
(<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">
|
||||
{_t('Add a User')}
|
||||
{ _t('Add a User') }
|
||||
</div>
|
||||
</AccessibleButton>) : <div />;
|
||||
const userNodes = this.props.users.map((u) => {
|
||||
|
@ -288,16 +290,16 @@ const RoleUserList = React.createClass({
|
|||
key={u.user_id}
|
||||
summaryInfo={u}
|
||||
editing={this.props.editing}
|
||||
groupId={this.props.groupId}/>;
|
||||
groupId={this.props.groupId} />;
|
||||
});
|
||||
let roleHeader = <div />;
|
||||
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">
|
||||
{roleHeader}
|
||||
{userNodes}
|
||||
{addButton}
|
||||
{ roleHeader }
|
||||
{ userNodes }
|
||||
{ addButton }
|
||||
</div>;
|
||||
},
|
||||
});
|
||||
|
@ -349,7 +351,7 @@ const FeaturedUser = React.createClass({
|
|||
const name = this.props.summaryInfo.displayname || 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()
|
||||
.mxcUrlToHttp(this.props.summaryInfo.avatar_url, 64, 64);
|
||||
|
||||
|
@ -360,13 +362,13 @@ const FeaturedUser = React.createClass({
|
|||
width="14"
|
||||
height="14"
|
||||
alt="Delete"
|
||||
onClick={this.onDeleteClicked}/>
|
||||
onClick={this.onDeleteClicked} />
|
||||
: <div />;
|
||||
|
||||
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
|
||||
<BaseAvatar name={name} url={httpUrl} width={64} height={64} />
|
||||
<div className="mx_GroupView_featuredThing_name">{userNameNode}</div>
|
||||
{deleteButton}
|
||||
<div className="mx_GroupView_featuredThing_name">{ userNameNode }</div>
|
||||
{ deleteButton }
|
||||
</AccessibleButton>;
|
||||
},
|
||||
});
|
||||
|
@ -632,7 +634,7 @@ export default React.createClass({
|
|||
const defaultCategoryNode = <CategoryRoomList
|
||||
rooms={defaultCategoryRooms}
|
||||
groupId={this.props.groupId}
|
||||
editing={this.state.editing}/>;
|
||||
editing={this.state.editing} />;
|
||||
const categoryRoomNodes = Object.keys(categoryRooms).map((catId) => {
|
||||
const cat = summary.rooms_section.categories[catId];
|
||||
return <CategoryRoomList
|
||||
|
@ -640,15 +642,15 @@ export default React.createClass({
|
|||
rooms={categoryRooms[catId]}
|
||||
category={cat}
|
||||
groupId={this.props.groupId}
|
||||
editing={this.state.editing}/>;
|
||||
editing={this.state.editing} />;
|
||||
});
|
||||
|
||||
return <div className="mx_GroupView_featuredThings">
|
||||
<div className="mx_GroupView_featuredThings_header">
|
||||
{_t('Featured Rooms:')}
|
||||
{ _t('Featured Rooms:') }
|
||||
</div>
|
||||
{defaultCategoryNode}
|
||||
{categoryRoomNodes}
|
||||
{ defaultCategoryNode }
|
||||
{ categoryRoomNodes }
|
||||
</div>;
|
||||
},
|
||||
|
||||
|
@ -673,7 +675,7 @@ export default React.createClass({
|
|||
const noRoleNode = <RoleUserList
|
||||
users={noRoleUsers}
|
||||
groupId={this.props.groupId}
|
||||
editing={this.state.editing}/>;
|
||||
editing={this.state.editing} />;
|
||||
const roleUserNodes = Object.keys(roleUsers).map((roleId) => {
|
||||
const role = summary.users_section.roles[roleId];
|
||||
return <RoleUserList
|
||||
|
@ -681,15 +683,15 @@ export default React.createClass({
|
|||
users={roleUsers[roleId]}
|
||||
role={role}
|
||||
groupId={this.props.groupId}
|
||||
editing={this.state.editing}/>;
|
||||
editing={this.state.editing} />;
|
||||
});
|
||||
|
||||
return <div className="mx_GroupView_featuredThings">
|
||||
<div className="mx_GroupView_featuredThings_header">
|
||||
{_t('Featured Users:')}
|
||||
{ _t('Featured Users:') }
|
||||
</div>
|
||||
{noRoleNode}
|
||||
{roleUserNodes}
|
||||
{ noRoleNode }
|
||||
{ roleUserNodes }
|
||||
</div>;
|
||||
},
|
||||
|
||||
|
@ -708,18 +710,18 @@ export default React.createClass({
|
|||
|
||||
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_invited">
|
||||
<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 className="mx_GroupView_membership_buttonContainer">
|
||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onAcceptInviteClick}
|
||||
>
|
||||
{_t("Accept")}
|
||||
{ _t("Accept") }
|
||||
</AccessibleButton>
|
||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onRejectInviteClick}
|
||||
>
|
||||
{_t("Decline")}
|
||||
{ _t("Decline") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>;
|
||||
|
@ -740,13 +742,13 @@ export default React.createClass({
|
|||
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onPubliciseOffClick}
|
||||
>
|
||||
{_t("Unpublish")}
|
||||
{ _t("Unpublish") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
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">
|
||||
{publicisedButton}
|
||||
{ publicisedButton }
|
||||
</div>
|
||||
</div>;
|
||||
} else {
|
||||
|
@ -754,13 +756,13 @@ export default React.createClass({
|
|||
publicisedButton = <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onPubliciseOnClick}
|
||||
>
|
||||
{_t("Publish")}
|
||||
{ _t("Publish") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
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">
|
||||
{publicisedButton}
|
||||
{ publicisedButton }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
@ -768,17 +770,17 @@ export default React.createClass({
|
|||
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_joined">
|
||||
<div className="mx_GroupView_membershipSubSection">
|
||||
<div className="mx_GroupView_membershipSection_description">
|
||||
{youAreAMemberText}
|
||||
{ youAreAMemberText }
|
||||
</div>
|
||||
<div className="mx_GroupView_membership_buttonContainer">
|
||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onLeaveClick}
|
||||
>
|
||||
{_t("Leave")}
|
||||
{ _t("Leave") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>
|
||||
{publicisedSection}
|
||||
{ publicisedSection }
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -818,15 +820,15 @@ export default React.createClass({
|
|||
avatarNode = (
|
||||
<div className="mx_GroupView_avatarPicker">
|
||||
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
||||
{avatarImage}
|
||||
{ avatarImage }
|
||||
</label>
|
||||
<div className="mx_GroupView_avatarPicker_edit">
|
||||
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
|
||||
<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" />
|
||||
</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>
|
||||
);
|
||||
|
@ -846,13 +848,13 @@ export default React.createClass({
|
|||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
onClick={this._onSaveClick} key="_saveButton"
|
||||
>
|
||||
{_t('Save')}
|
||||
{ _t('Save') }
|
||||
</AccessibleButton>,
|
||||
);
|
||||
rightButtons.push(
|
||||
<AccessibleButton className="mx_RoomHeader_cancelButton" onClick={this._onCancelClick} key="_cancelButton">
|
||||
<img src="img/cancel.svg" className="mx_filterFlipColor"
|
||||
width="18" height="18" alt={_t("Cancel")}/>
|
||||
width="18" height="18" alt={_t("Cancel")} />
|
||||
</AccessibleButton>,
|
||||
);
|
||||
roomBody = <div>
|
||||
|
@ -860,8 +862,8 @@ export default React.createClass({
|
|||
onChange={this._onLongDescChange}
|
||||
tabIndex="3"
|
||||
/>
|
||||
{this._getFeaturedRoomsNode()}
|
||||
{this._getFeaturedUsersNode()}
|
||||
{ this._getFeaturedRoomsNode() }
|
||||
{ this._getFeaturedUsersNode() }
|
||||
</div>;
|
||||
} else {
|
||||
const groupAvatarUrl = summary.profile ? summary.profile.avatar_url : null;
|
||||
|
@ -872,41 +874,41 @@ export default React.createClass({
|
|||
/>;
|
||||
if (summary.profile && summary.profile.name) {
|
||||
nameNode = <div>
|
||||
<span>{summary.profile.name}</span>
|
||||
<span>{ summary.profile.name }</span>
|
||||
<span className="mx_GroupView_header_groupid">
|
||||
({this.props.groupId})
|
||||
({ this.props.groupId })
|
||||
</span>
|
||||
</div>;
|
||||
} 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;
|
||||
if (summary.profile && summary.profile.long_description) {
|
||||
description = sanitizedHtmlNode(summary.profile.long_description);
|
||||
}
|
||||
roomBody = <div>
|
||||
{this._getMembershipSection()}
|
||||
<div className="mx_GroupView_groupDesc">{description}</div>
|
||||
{this._getFeaturedRoomsNode()}
|
||||
{this._getFeaturedUsersNode()}
|
||||
{ this._getMembershipSection() }
|
||||
<div className="mx_GroupView_groupDesc">{ description }</div>
|
||||
{ this._getFeaturedRoomsNode() }
|
||||
{ this._getFeaturedUsersNode() }
|
||||
</div>;
|
||||
if (summary.user && summary.user.is_privileged) {
|
||||
rightButtons.push(
|
||||
<AccessibleButton className="mx_GroupHeader_button"
|
||||
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>,
|
||||
);
|
||||
}
|
||||
if (this.props.collapsedRhs) {
|
||||
rightButtons.push(
|
||||
<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>,
|
||||
);
|
||||
}
|
||||
|
@ -919,40 +921,40 @@ export default React.createClass({
|
|||
<div className={classnames(headerClasses)}>
|
||||
<div className="mx_GroupView_header_leftCol">
|
||||
<div className="mx_GroupView_header_avatar">
|
||||
{avatarNode}
|
||||
{ avatarNode }
|
||||
</div>
|
||||
<div className="mx_GroupView_header_info">
|
||||
<div className="mx_GroupView_header_name">
|
||||
{nameNode}
|
||||
{ nameNode }
|
||||
</div>
|
||||
<div className="mx_GroupView_header_shortDesc">
|
||||
{shortDescNode}
|
||||
{ shortDescNode }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_GroupView_header_rightCol">
|
||||
{rightButtons}
|
||||
{ rightButtons }
|
||||
</div>
|
||||
</div>
|
||||
{roomBody}
|
||||
{ roomBody }
|
||||
</div>
|
||||
);
|
||||
} else if (this.state.error) {
|
||||
if (this.state.error.httpStatus === 404) {
|
||||
return (
|
||||
<div className="mx_GroupView_error">
|
||||
Group {this.props.groupId} not found
|
||||
Group { this.props.groupId } not found
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
let extraText;
|
||||
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 (
|
||||
<div className="mx_GroupView_error">
|
||||
Failed to load {this.props.groupId}
|
||||
{extraText}
|
||||
Failed to load { this.props.groupId }
|
||||
{ extraText }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -853,7 +853,7 @@ module.exports = React.createClass({
|
|||
title: _t("Leave room"),
|
||||
description: (
|
||||
<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>
|
||||
),
|
||||
onFinished: (shouldLeave) => {
|
||||
|
@ -1450,7 +1450,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_MatrixChat_splash">
|
||||
<Spinner />
|
||||
<a href="#" className="mx_MatrixChat_splashButtons" onClick={ this.onLogoutClick }>
|
||||
<a href="#" className="mx_MatrixChat_splashButtons" onClick={this.onLogoutClick}>
|
||||
{ _t('Logout') }
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@ const GroupTile = React.createClass({
|
|||
},
|
||||
|
||||
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>
|
||||
<div>{_t('You are a member of these groups:')}</div>
|
||||
{groupNodes}
|
||||
<div>{ _t('You are a member of these groups:') }</div>
|
||||
{ groupNodes }
|
||||
</div>;
|
||||
} else if (this.state.error) {
|
||||
content = <div className="mx_MyGroups_error">
|
||||
{_t('Error whilst fetching joined groups')}
|
||||
{ _t('Error whilst fetching joined groups') }
|
||||
</div>;
|
||||
} else {
|
||||
content = <Loader />;
|
||||
}
|
||||
|
||||
return <div className="mx_MyGroups">
|
||||
<SimpleRoomHeader title={ _t("Groups") } icon="img/icons-groups.svg" />
|
||||
<SimpleRoomHeader title={_t("Groups")} icon="img/icons-groups.svg" />
|
||||
<div className='mx_MyGroups_joinCreateBox'>
|
||||
<div className="mx_MyGroups_createBox">
|
||||
<div className="mx_MyGroups_joinCreateHeader">
|
||||
{_t('Create a new group')}
|
||||
{ _t('Create a new group') }
|
||||
</div>
|
||||
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onCreateGroupClick}>
|
||||
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
||||
</AccessibleButton>
|
||||
{_t(
|
||||
{ _t(
|
||||
'Create a group to represent your community! '+
|
||||
'Define a set of rooms and your own custom homepage '+
|
||||
'to mark out your space in the Matrix universe.',
|
||||
)}
|
||||
) }
|
||||
</div>
|
||||
<div className="mx_MyGroups_joinBox">
|
||||
<div className="mx_MyGroups_joinCreateHeader">
|
||||
{_t('Join an existing group')}
|
||||
{ _t('Join an existing group') }
|
||||
</div>
|
||||
<AccessibleButton className='mx_MyGroups_joinCreateButton' onClick={this._onJoinGroupClick}>
|
||||
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
||||
</AccessibleButton>
|
||||
{_tJsx(
|
||||
{ _tJsx(
|
||||
'To join an existing group you\'ll have to '+
|
||||
'know its group identifier; this will look '+
|
||||
'something like <i>+example:matrix.org</i>.',
|
||||
/<i>(.*)<\/i>/,
|
||||
(sub) => <i>{sub}</i>,
|
||||
)}
|
||||
(sub) => <i>{ sub }</i>,
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_MyGroups_content">
|
||||
{content}
|
||||
{ content }
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
|
|
@ -52,7 +52,7 @@ const gHVersionLabel = function(repo, token='') {
|
|||
} else {
|
||||
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).
|
||||
|
@ -674,7 +674,7 @@ module.exports = React.createClass({
|
|||
<div>
|
||||
<h3>Referral</h3>
|
||||
<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>
|
||||
);
|
||||
|
@ -693,7 +693,7 @@ module.exports = React.createClass({
|
|||
_renderLanguageSetting: function() {
|
||||
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown');
|
||||
return <div>
|
||||
<label htmlFor="languageSelector">{_t('Interface Language')}</label>
|
||||
<label htmlFor="languageSelector">{ _t('Interface Language') }</label>
|
||||
<LanguageDropdown ref="language" onOptionChange={this.onLanguageChange}
|
||||
className="mx_UserSettings_language"
|
||||
value={this.state.language}
|
||||
|
@ -716,7 +716,7 @@ module.exports = React.createClass({
|
|||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>{_t('Autocomplete Delay (ms):')}</strong></td>
|
||||
<td><strong>{ _t('Autocomplete Delay (ms):') }</strong></td>
|
||||
<td>
|
||||
<input
|
||||
type="number"
|
||||
|
@ -737,8 +737,8 @@ module.exports = React.createClass({
|
|||
return <div className="mx_UserSettings_toggle">
|
||||
<input id="urlPreviewsDisabled"
|
||||
type="checkbox"
|
||||
defaultChecked={ UserSettingsStore.getUrlPreviewsDisabled() }
|
||||
onChange={ this._onPreviewsDisabledChanged }
|
||||
defaultChecked={UserSettingsStore.getUrlPreviewsDisabled()}
|
||||
onChange={this._onPreviewsDisabledChanged}
|
||||
/>
|
||||
<label htmlFor="urlPreviewsDisabled">
|
||||
{ _t("Disable inline URL previews by default") }
|
||||
|
@ -759,13 +759,13 @@ module.exports = React.createClass({
|
|||
if (setting.fn) setting.fn(e.target.checked);
|
||||
};
|
||||
|
||||
return <div className="mx_UserSettings_toggle" key={ setting.id }>
|
||||
<input id={ setting.id }
|
||||
return <div className="mx_UserSettings_toggle" key={setting.id}>
|
||||
<input id={setting.id}
|
||||
type="checkbox"
|
||||
defaultChecked={ this._syncedSettings[setting.id] }
|
||||
onChange={ onChange }
|
||||
defaultChecked={this._syncedSettings[setting.id]}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<label htmlFor={ setting.id }>
|
||||
<label htmlFor={setting.id}>
|
||||
{ _t(setting.label) }
|
||||
</label>
|
||||
</div>;
|
||||
|
@ -784,15 +784,15 @@ module.exports = React.createClass({
|
|||
value: setting.value,
|
||||
});
|
||||
};
|
||||
return <div className="mx_UserSettings_toggle" key={ setting.id + "_" + setting.value }>
|
||||
<input id={ setting.id + "_" + setting.value }
|
||||
return <div className="mx_UserSettings_toggle" key={setting.id + "_" + setting.value}>
|
||||
<input id={setting.id + "_" + setting.value}
|
||||
type="radio"
|
||||
name={ setting.id }
|
||||
value={ setting.value }
|
||||
checked={ this._syncedSettings[setting.id] === setting.value }
|
||||
onChange={ onChange }
|
||||
name={setting.id}
|
||||
value={setting.value}
|
||||
checked={this._syncedSettings[setting.id] === setting.value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<label htmlFor={ setting.id + "_" + setting.value }>
|
||||
<label htmlFor={setting.id + "_" + setting.value}>
|
||||
{ setting.label }
|
||||
</label>
|
||||
</div>;
|
||||
|
@ -829,10 +829,10 @@ module.exports = React.createClass({
|
|||
<h3>{ _t("Cryptography") }</h3>
|
||||
<div className="mx_UserSettings_section mx_UserSettings_cryptoSection">
|
||||
<ul>
|
||||
<li><label>{_t("Device ID:")}</label>
|
||||
<span><code>{deviceId}</code></span></li>
|
||||
<li><label>{_t("Device key:")}</label>
|
||||
<span><code><b>{identityKey}</b></code></span></li>
|
||||
<li><label>{ _t("Device ID:") }</label>
|
||||
<span><code>{ deviceId }</code></span></li>
|
||||
<li><label>{ _t("Device key:") }</label>
|
||||
<span><code><b>{ identityKey }</b></code></span></li>
|
||||
</ul>
|
||||
{ importExportButtons }
|
||||
</div>
|
||||
|
@ -851,11 +851,11 @@ module.exports = React.createClass({
|
|||
<h3>{ _t("Ignored Users") }</h3>
|
||||
<div className="mx_UserSettings_section mx_UserSettings_ignoredUsersSection">
|
||||
<ul>
|
||||
{this.state.ignoredUsers.map(function(userId) {
|
||||
{ this.state.ignoredUsers.map(function(userId) {
|
||||
return (<IgnoredUser key={userId}
|
||||
userId={userId}
|
||||
onUnignored={updateHandler}></IgnoredUser>);
|
||||
})}
|
||||
}) }
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -871,13 +871,13 @@ module.exports = React.createClass({
|
|||
if (setting.fn) setting.fn(e.target.checked);
|
||||
};
|
||||
|
||||
return <div className="mx_UserSettings_toggle" key={ setting.id }>
|
||||
<input id={ setting.id }
|
||||
return <div className="mx_UserSettings_toggle" key={setting.id}>
|
||||
<input id={setting.id}
|
||||
type="checkbox"
|
||||
defaultChecked={ this._localSettings[setting.id] }
|
||||
onChange={ onChange }
|
||||
defaultChecked={this._localSettings[setting.id]}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<label htmlFor={ setting.id }>
|
||||
<label htmlFor={setting.id}>
|
||||
{ _t(setting.label) }
|
||||
</label>
|
||||
</div>;
|
||||
|
@ -887,8 +887,8 @@ module.exports = React.createClass({
|
|||
const DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
||||
return (
|
||||
<div>
|
||||
<h3>{_t("Devices")}</h3>
|
||||
<DevicesPanel className="mx_UserSettings_section"/>
|
||||
<h3>{ _t("Devices") }</h3>
|
||||
<DevicesPanel className="mx_UserSettings_section" />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
@ -903,7 +903,7 @@ module.exports = React.createClass({
|
|||
<div className="mx_UserSettings_section">
|
||||
<p>{ _t("Found a bug?") }</p>
|
||||
<button className="mx_UserSettings_button danger"
|
||||
onClick={this._onBugReportClicked}>{_t('Report it')}
|
||||
onClick={this._onBugReportClicked}>{ _t('Report it') }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -911,13 +911,13 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_renderAnalyticsControl: function() {
|
||||
if (!SdkConfig.get().piwik) return <div/>;
|
||||
if (!SdkConfig.get().piwik) return <div />;
|
||||
|
||||
return <div>
|
||||
<h3>{ _t('Analytics') }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
{_t('Riot collects anonymous analytics to allow us to improve the application.')}
|
||||
{ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting )}
|
||||
{ _t('Riot collects anonymous analytics to allow us to improve the application.') }
|
||||
{ ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting ) }
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
@ -947,10 +947,10 @@ module.exports = React.createClass({
|
|||
type="checkbox"
|
||||
id={feature.id}
|
||||
name={feature.id}
|
||||
defaultChecked={ UserSettingsStore.isFeatureEnabled(feature.id) }
|
||||
onChange={ onChange }
|
||||
defaultChecked={UserSettingsStore.isFeatureEnabled(feature.id)}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<label htmlFor={feature.id}>{feature.name}</label>
|
||||
<label htmlFor={feature.id}>{ feature.name }</label>
|
||||
</div>);
|
||||
});
|
||||
|
||||
|
@ -964,7 +964,7 @@ module.exports = React.createClass({
|
|||
<h3>{ _t("Labs") }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<p>{ _t("These are experimental features that may break in unexpected ways") }. { _t("Use with caution") }.</p>
|
||||
{features}
|
||||
{ features }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -997,10 +997,10 @@ module.exports = React.createClass({
|
|||
const platform = PlatformPeg.get();
|
||||
if ('canSelfUpdate' in platform && platform.canSelfUpdate() && 'startUpdateCheck' in platform) {
|
||||
return <div>
|
||||
<h3>{_t('Updates')}</h3>
|
||||
<h3>{ _t('Updates') }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<AccessibleButton className="mx_UserSettings_button" onClick={platform.startUpdateCheck}>
|
||||
{_t('Check for update')}
|
||||
{ _t('Check for update') }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>;
|
||||
|
@ -1026,7 +1026,7 @@ module.exports = React.createClass({
|
|||
reject = (
|
||||
<AccessibleButton className="mx_UserSettings_button danger"
|
||||
onClick={onClick}>
|
||||
{_t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length})}
|
||||
{ _t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length}) }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
@ -1034,7 +1034,7 @@ module.exports = React.createClass({
|
|||
return <div>
|
||||
<h3>{ _t("Bulk Options") }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
{reject}
|
||||
{ reject }
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
@ -1052,7 +1052,7 @@ module.exports = React.createClass({
|
|||
defaultChecked={settings['auto-launch']}
|
||||
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>;
|
||||
|
@ -1064,7 +1064,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_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) {
|
||||
|
@ -1100,15 +1100,15 @@ module.exports = React.createClass({
|
|||
if (this.state.mediaDevices === false) {
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
} else if (!this.state.mediaDevices) return;
|
||||
|
||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||
|
||||
let microphoneDropdown = <p>{_t('No Microphones detected')}</p>;
|
||||
let webcamDropdown = <p>{_t('No Webcams detected')}</p>;
|
||||
let microphoneDropdown = <p>{ _t('No Microphones detected') }</p>;
|
||||
let webcamDropdown = <p>{ _t('No Webcams detected') }</p>;
|
||||
|
||||
const defaultOption = {
|
||||
deviceId: '',
|
||||
|
@ -1125,12 +1125,12 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
microphoneDropdown = <div>
|
||||
<h4>{_t('Microphone')}</h4>
|
||||
<h4>{ _t('Microphone') }</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeAudioInput || defaultInput}
|
||||
onOptionChange={this._setAudioInput}>
|
||||
{this._mapWebRtcDevicesToSpans(audioInputs)}
|
||||
{ this._mapWebRtcDevicesToSpans(audioInputs) }
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
@ -1145,25 +1145,25 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
webcamDropdown = <div>
|
||||
<h4>{_t('Camera')}</h4>
|
||||
<h4>{ _t('Camera') }</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeVideoInput || defaultInput}
|
||||
onOptionChange={this._setVideoInput}>
|
||||
{this._mapWebRtcDevicesToSpans(videoInputs)}
|
||||
{ this._mapWebRtcDevicesToSpans(videoInputs) }
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <div>
|
||||
{microphoneDropdown}
|
||||
{webcamDropdown}
|
||||
{ microphoneDropdown }
|
||||
{ webcamDropdown }
|
||||
</div>;
|
||||
},
|
||||
|
||||
_renderWebRtcSettings: function() {
|
||||
return <div>
|
||||
<h3>{_t('VoIP')}</h3>
|
||||
<h3>{ _t('VoIP') }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
{ WEBRTC_SETTINGS_LABELS.map(this._renderLocalSetting) }
|
||||
{ this._renderWebRtcDeviceSettings() }
|
||||
|
@ -1229,7 +1229,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_UserSettings_profileTableRow" key={pidIndex}>
|
||||
<div className="mx_UserSettings_profileLabelCell">
|
||||
<label htmlFor={id}>{this.nameForMedium(val.medium)}</label>
|
||||
<label htmlFor={id}>{ this.nameForMedium(val.medium) }</label>
|
||||
</div>
|
||||
<div className="mx_UserSettings_profileInputCell">
|
||||
<input type="text" key={val.address} id={id}
|
||||
|
@ -1237,7 +1237,7 @@ module.exports = React.createClass({
|
|||
/>
|
||||
</div>
|
||||
<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} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1250,16 +1250,16 @@ module.exports = React.createClass({
|
|||
addEmailSection = (
|
||||
<div className="mx_UserSettings_profileTableRow" key="_newEmail">
|
||||
<div className="mx_UserSettings_profileLabelCell">
|
||||
<label>{_t('Email')}</label>
|
||||
<label>{ _t('Email') }</label>
|
||||
</div>
|
||||
<div className="mx_UserSettings_profileInputCell">
|
||||
<EditableText
|
||||
ref="add_email_input"
|
||||
className="mx_UserSettings_editable"
|
||||
placeholderClassName="mx_UserSettings_threepidPlaceholder"
|
||||
placeholder={ _t("Add email address") }
|
||||
blurToCancel={ false }
|
||||
onValueChanged={ this._onAddEmailEditFinished } />
|
||||
placeholder={_t("Add email address")}
|
||||
blurToCancel={false}
|
||||
onValueChanged={this._onAddEmailEditFinished} />
|
||||
</div>
|
||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||
|
@ -1307,8 +1307,8 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_UserSettings">
|
||||
<SimpleRoomHeader
|
||||
title={ _t("Settings") }
|
||||
onCancelClick={ this.props.onClose }
|
||||
title={_t("Settings")}
|
||||
onCancelClick={this.props.onClose}
|
||||
/>
|
||||
|
||||
<GeminiScrollbar className="mx_UserSettings_body"
|
||||
|
@ -1326,21 +1326,21 @@ module.exports = React.createClass({
|
|||
<ChangeDisplayName />
|
||||
</div>
|
||||
</div>
|
||||
{threepidsSection}
|
||||
{ threepidsSection }
|
||||
</div>
|
||||
|
||||
<div className="mx_UserSettings_avatarPicker">
|
||||
<div onClick={ this.onAvatarPickerClick }>
|
||||
<div onClick={this.onAvatarPickerClick}>
|
||||
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
||||
showUploadSection={false} className="mx_UserSettings_avatarPicker_img"/>
|
||||
showUploadSection={false} className="mx_UserSettings_avatarPicker_img" />
|
||||
</div>
|
||||
<div className="mx_UserSettings_avatarPicker_edit">
|
||||
<label htmlFor="avatarInput" ref="file_label">
|
||||
<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" />
|
||||
</label>
|
||||
<input id="avatarInput" type="file" onChange={this.onAvatarSelected}/>
|
||||
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1357,37 +1357,37 @@ module.exports = React.createClass({
|
|||
</div> : null
|
||||
}
|
||||
|
||||
{accountJsx}
|
||||
{ accountJsx }
|
||||
</div>
|
||||
|
||||
{this._renderReferral()}
|
||||
{ this._renderReferral() }
|
||||
|
||||
{notificationArea}
|
||||
{ notificationArea }
|
||||
|
||||
{this._renderUserInterfaceSettings()}
|
||||
{this._renderLabs()}
|
||||
{this._renderWebRtcSettings()}
|
||||
{this._renderDevicesPanel()}
|
||||
{this._renderCryptoInfo()}
|
||||
{this._renderIgnoredUsers()}
|
||||
{this._renderBulkOptions()}
|
||||
{this._renderBugReport()}
|
||||
{ this._renderUserInterfaceSettings() }
|
||||
{ this._renderLabs() }
|
||||
{ this._renderWebRtcSettings() }
|
||||
{ this._renderDevicesPanel() }
|
||||
{ this._renderCryptoInfo() }
|
||||
{ this._renderIgnoredUsers() }
|
||||
{ this._renderBulkOptions() }
|
||||
{ this._renderBugReport() }
|
||||
|
||||
{PlatformPeg.get().isElectron() && this._renderElectronSettings()}
|
||||
{ PlatformPeg.get().isElectron() && this._renderElectronSettings() }
|
||||
|
||||
{this._renderAnalyticsControl()}
|
||||
{ this._renderAnalyticsControl() }
|
||||
|
||||
<h3>{ _t("Advanced") }</h3>
|
||||
|
||||
<div className="mx_UserSettings_section">
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{ _t("Logged in as:") } {this._me}
|
||||
{ _t("Logged in as:") } { this._me }
|
||||
</div>
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{_t('Access Token:')}
|
||||
{ _t('Access Token:') }
|
||||
<span className="mx_UserSettings_advanced_spoiler"
|
||||
onClick={this._showSpoiler}
|
||||
data-spoiler={ MatrixClientPeg.get().getAccessToken() }>
|
||||
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
||||
<{ _t("click to reveal") }>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1398,23 +1398,23 @@ module.exports = React.createClass({
|
|||
{ _t("Identity Server is") } { MatrixClientPeg.get().getIdentityServerUrl() }
|
||||
</div>
|
||||
<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)
|
||||
: REACT_SDK_VERSION
|
||||
}<br/>
|
||||
{_t('riot-web version:')} {(this.state.vectorVersion !== undefined)
|
||||
}<br />
|
||||
{ _t('riot-web version:') } { (this.state.vectorVersion !== undefined)
|
||||
? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion)
|
||||
: 'unknown'
|
||||
}<br/>
|
||||
{ _t("olm version:") } {olmVersionString}<br/>
|
||||
}<br />
|
||||
{ _t("olm version:") } { olmVersionString }<br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{this._renderCheckUpdate()}
|
||||
{ this._renderCheckUpdate() }
|
||||
|
||||
{this._renderClearCache()}
|
||||
{ this._renderClearCache() }
|
||||
|
||||
{this._renderDeactivateAccount()}
|
||||
{ this._renderDeactivateAccount() }
|
||||
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
|
|
|
@ -419,7 +419,7 @@ module.exports = React.createClass({
|
|||
address: addressText,
|
||||
isKnown: false,
|
||||
};
|
||||
if (addrType == null) {
|
||||
if (!this.props.validAddressTypes.includes(addrType)) {
|
||||
this.setState({ error: true });
|
||||
return null;
|
||||
} else if (addrType == 'mx-user-id') {
|
||||
|
@ -495,7 +495,7 @@ module.exports = React.createClass({
|
|||
const AddressTile = sdk.getComponent("elements.AddressTile");
|
||||
for (let i = 0; i < this.state.userList.length; i++) {
|
||||
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)} />,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -517,23 +517,36 @@ module.exports = React.createClass({
|
|||
let error;
|
||||
let addressSelector;
|
||||
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">
|
||||
{_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>;
|
||||
} 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 (
|
||||
this.state.query.length > 0 &&
|
||||
this.state.queryList.length === 0 &&
|
||||
!this.state.busy
|
||||
) {
|
||||
error = <div className="mx_ChatInviteDialog_error">{_t("No results")}</div>;
|
||||
error = <div className="mx_ChatInviteDialog_error">{ _t("No results") }</div>;
|
||||
} else {
|
||||
addressSelector = (
|
||||
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
||||
addressList={ this.state.queryList }
|
||||
onSelected={ this.onSelected }
|
||||
truncateAt={ TRUNCATE_QUERY_LIST }
|
||||
addressList={this.state.queryList}
|
||||
onSelected={this.onSelected}
|
||||
truncateAt={TRUNCATE_QUERY_LIST}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -541,7 +554,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_ChatInviteDialog" onKeyDown={this.onKeyDown}>
|
||||
<div className="mx_Dialog_title">
|
||||
{this.props.title}
|
||||
{ this.props.title }
|
||||
</div>
|
||||
<AccessibleButton className="mx_ChatInviteDialog_cancel"
|
||||
onClick={this.onCancel} >
|
||||
|
@ -557,7 +570,7 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this.onButtonClick}>
|
||||
{this.props.button}
|
||||
{ this.props.button }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -52,20 +52,20 @@ export default React.createClass({
|
|||
|
||||
return (
|
||||
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
||||
onEnterPressed={ this.onOk }
|
||||
onEnterPressed={this.onOk}
|
||||
title={title}
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
{_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.")}
|
||||
{ _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.") }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className={confirmButtonClass} onClick={this.onOk}>
|
||||
{_t("Remove")}
|
||||
{ _t("Remove") }
|
||||
</button>
|
||||
|
||||
<button onClick={this.onCancel}>
|
||||
{_t("Cancel")}
|
||||
{ _t("Cancel") }
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -88,7 +88,7 @@ export default React.createClass({
|
|||
<form onSubmit={this.onOk}>
|
||||
<input className="mx_ConfirmUserActionDialog_reasonField"
|
||||
ref={this._collectReasonField}
|
||||
placeholder={ _t("Reason") }
|
||||
placeholder={_t("Reason")}
|
||||
autoFocus={true}
|
||||
/>
|
||||
</form>
|
||||
|
@ -112,22 +112,22 @@ export default React.createClass({
|
|||
|
||||
return (
|
||||
<BaseDialog className="mx_ConfirmUserActionDialog" onFinished={this.props.onFinished}
|
||||
onEnterPressed={ this.onOk }
|
||||
onEnterPressed={this.onOk}
|
||||
title={title}
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
<div className="mx_ConfirmUserActionDialog_avatar">
|
||||
{avatar}
|
||||
{ avatar }
|
||||
</div>
|
||||
<div className="mx_ConfirmUserActionDialog_name">{name}</div>
|
||||
<div className="mx_ConfirmUserActionDialog_userId">{userId}</div>
|
||||
<div className="mx_ConfirmUserActionDialog_name">{ name }</div>
|
||||
<div className="mx_ConfirmUserActionDialog_userId">{ userId }</div>
|
||||
</div>
|
||||
{reasonBox}
|
||||
{ reasonBox }
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className={confirmButtonClass}
|
||||
onClick={this.onOk} autoFocus={!this.props.askReason}
|
||||
>
|
||||
{this.props.action}
|
||||
{ this.props.action }
|
||||
</button>
|
||||
|
||||
<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
|
||||
// any yet.
|
||||
createErrorNode = <div className="error">
|
||||
<div>{_t('Room creation failed')}</div>
|
||||
<div>{this.state.createError.message}</div>
|
||||
<div>{ _t('Room creation failed') }</div>
|
||||
<div>{ this.state.createError.message }</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ export default React.createClass({
|
|||
<div className="mx_Dialog_content">
|
||||
<div className="mx_CreateGroupDialog_inputRow">
|
||||
<div className="mx_CreateGroupDialog_label">
|
||||
<label htmlFor="groupname">{_t('Group Name')}</label>
|
||||
<label htmlFor="groupname">{ _t('Group Name') }</label>
|
||||
</div>
|
||||
<div>
|
||||
<input id="groupname" className="mx_CreateGroupDialog_input"
|
||||
|
@ -169,7 +169,7 @@ export default React.createClass({
|
|||
</div>
|
||||
<div className="mx_CreateGroupDialog_inputRow">
|
||||
<div className="mx_CreateGroupDialog_label">
|
||||
<label htmlFor="groupid">{_t('Group ID')}</label>
|
||||
<label htmlFor="groupid">{ _t('Group ID') }</label>
|
||||
</div>
|
||||
<div>
|
||||
<input id="groupid" className="mx_CreateGroupDialog_input"
|
||||
|
@ -182,9 +182,9 @@ export default React.createClass({
|
|||
</div>
|
||||
</div>
|
||||
<div className="error">
|
||||
{this.state.groupIdError}
|
||||
{ this.state.groupIdError }
|
||||
</div>
|
||||
{createErrorNode}
|
||||
{ createErrorNode }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={this._onCancel}>
|
||||
|
|
|
@ -28,25 +28,25 @@ export default function DeviceVerifyDialog(props) {
|
|||
const body = (
|
||||
<div>
|
||||
<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) " +
|
||||
"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>
|
||||
<div className="mx_UserSettings_cryptoSection">
|
||||
<ul>
|
||||
<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 key")}:</label> <span><code><b>{ key }</b></code></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 key") }:</label> <span><code><b>{ key }</b></code></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<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 " +
|
||||
"and you probably want to press the blacklist button instead.")}
|
||||
"and you probably want to press the blacklist button instead.") }
|
||||
</p>
|
||||
<p>
|
||||
{_t("In future this verification process will be more sophisticated.")}
|
||||
{ _t("In future this verification process will be more sophisticated.") }
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -63,11 +63,11 @@ export default React.createClass({
|
|||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||
title={this.props.title || _t('Error')}>
|
||||
<div className="mx_Dialog_content">
|
||||
{this.props.description || _t('An error has occurred.')}
|
||||
{ this.props.description || _t('An error has occurred.') }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button ref="button" className="mx_Dialog_primary" onClick={this.props.onFinished}>
|
||||
{this.props.button || _t('OK')}
|
||||
{ this.props.button || _t('OK') }
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -126,17 +126,17 @@ export default React.createClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p>{text}</p>
|
||||
<p>{ text }</p>
|
||||
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={this._onVerifyClicked}>
|
||||
{_t('Start verification')}
|
||||
{ _t('Start verification') }
|
||||
</button>
|
||||
<button onClick={this._onShareClicked}>
|
||||
{_t('Share without verifying')}
|
||||
{ _t('Share without verifying') }
|
||||
</button>
|
||||
<button onClick={this._onIgnoreClicked}>
|
||||
{_t('Ignore request')}
|
||||
{ _t('Ignore request') }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -154,7 +154,7 @@ export default React.createClass({
|
|||
} else {
|
||||
content = (
|
||||
<div>
|
||||
<p>{_t('Loading device info...')}</p>
|
||||
<p>{ _t('Loading device info...') }</p>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
@ -165,7 +165,7 @@ export default React.createClass({
|
|||
onFinished={this.props.onFinished}
|
||||
title={_t('Encryption key request')}
|
||||
>
|
||||
{content}
|
||||
{ content }
|
||||
</BaseDialog>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -55,7 +55,7 @@ export default React.createClass({
|
|||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
const cancelButton = this.props.hasCancelButton ? (
|
||||
<button onClick={this.onCancel}>
|
||||
{_t("Cancel")}
|
||||
{ _t("Cancel") }
|
||||
</button>
|
||||
) : null;
|
||||
const buttonClasses = classnames({
|
||||
|
@ -64,18 +64,18 @@ export default React.createClass({
|
|||
});
|
||||
return (
|
||||
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished}
|
||||
onEnterPressed={ this.onOk }
|
||||
onEnterPressed={this.onOk}
|
||||
title={this.props.title}
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
{this.props.description}
|
||||
{ this.props.description }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className={buttonClasses} onClick={this.onOk} autoFocus={this.props.focus}>
|
||||
{this.props.button || _t('OK')}
|
||||
{ this.props.button || _t('OK') }
|
||||
</button>
|
||||
{this.props.extraButtons}
|
||||
{cancelButton}
|
||||
{ this.props.extraButtons }
|
||||
{ cancelButton }
|
||||
</div>
|
||||
</BaseDialog>
|
||||
);
|
||||
|
|
|
@ -45,10 +45,10 @@ export default React.createClass({
|
|||
if (SdkConfig.get().bug_report_endpoint_url) {
|
||||
bugreport = (
|
||||
<p>
|
||||
{_tJsx(
|
||||
{ _tJsx(
|
||||
"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>
|
||||
);
|
||||
}
|
||||
|
@ -57,19 +57,19 @@ export default React.createClass({
|
|||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||
title={_t('Unable to restore session')}>
|
||||
<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 " +
|
||||
"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 " +
|
||||
"to the more recent version.")}</p>
|
||||
"to the more recent version.") }</p>
|
||||
|
||||
{bugreport}
|
||||
{ bugreport }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
||||
{_t("Continue anyway")}
|
||||
{ _t("Continue anyway") }
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -130,10 +130,10 @@ export default React.createClass({
|
|||
|
||||
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
||||
className="mx_SetEmailDialog_email_input"
|
||||
placeholder={ _t("Email address") }
|
||||
placeholder={_t("Email address")}
|
||||
placeholderClassName="mx_SetEmailDialog_email_input_placeholder"
|
||||
blurToCancel={ false }
|
||||
onValueChanged={ this.onEmailAddressChanged } />;
|
||||
blurToCancel={false}
|
||||
onValueChanged={this.onEmailAddressChanged} />;
|
||||
|
||||
return (
|
||||
<BaseDialog className="mx_SetEmailDialog"
|
||||
|
|
|
@ -226,7 +226,7 @@ export default React.createClass({
|
|||
let usernameIndicator = null;
|
||||
let usernameBusyIndicator = null;
|
||||
if (this.state.usernameBusy) {
|
||||
usernameBusyIndicator = <Spinner w="24" h="24"/>;
|
||||
usernameBusyIndicator = <Spinner w="24" h="24" />;
|
||||
} else {
|
||||
const usernameAvailable = this.state.username &&
|
||||
this.state.usernameCheckSupport && !this.state.usernameError;
|
||||
|
@ -275,17 +275,17 @@ export default React.createClass({
|
|||
/<a>(.*?)<\/a>/,
|
||||
],
|
||||
[
|
||||
(sub) => <span>{this.props.homeserverUrl}</span>,
|
||||
(sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{sub}</a>,
|
||||
(sub) => <span>{ this.props.homeserverUrl }</span>,
|
||||
(sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{ sub }</a>,
|
||||
],
|
||||
)}
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ _tJsx(
|
||||
'If you already have a Matrix account you can <a>log in</a> instead.',
|
||||
/<a>(.*?)<\/a>/,
|
||||
[(sub) => <a href="#" onClick={this.props.onLoginClick}>{sub}</a>],
|
||||
)}
|
||||
[(sub) => <a href="#" onClick={this.props.onLoginClick}>{ sub }</a>],
|
||||
) }
|
||||
</p>
|
||||
{ auth }
|
||||
{ authErrorIndicator }
|
||||
|
|
|
@ -65,10 +65,10 @@ export default React.createClass({
|
|||
>
|
||||
<div className="mx_Dialog_content">
|
||||
<div className="mx_TextInputDialog_label">
|
||||
<label htmlFor="textinput"> {this.props.description} </label>
|
||||
<label htmlFor="textinput"> { this.props.description } </label>
|
||||
</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 className="mx_Dialog_buttons">
|
||||
|
@ -76,7 +76,7 @@ export default React.createClass({
|
|||
{ _t("Cancel") }
|
||||
</button>
|
||||
<button className="mx_Dialog_primary" onClick={this.onOk}>
|
||||
{this.props.button}
|
||||
{ this.props.button }
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -50,16 +50,16 @@ export default class AppPermission extends React.Component {
|
|||
let e2eWarningText;
|
||||
if (this.props.isRoomEncrypted) {
|
||||
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 (
|
||||
<div className='mx_AppPermissionWarning'>
|
||||
<div className='mx_AppPermissionWarningImage'>
|
||||
<img src='img/warning.svg' alt={_t('Warning!')}/>
|
||||
<img src='img/warning.svg' alt={_t('Warning!')} />
|
||||
</div>
|
||||
<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>
|
||||
{e2eWarningText}
|
||||
<span className='mx_AppPermissionWarningTextLabel'>{ _t('Do you want to load widget from URL:') }</span> <span className='mx_AppPermissionWarningTextURL'>{ this.state.curlBase }</span>
|
||||
{ e2eWarningText }
|
||||
</div>
|
||||
<input
|
||||
className='mx_AppPermissionButton'
|
||||
|
|
|
@ -261,7 +261,7 @@ export default React.createClass({
|
|||
if (this.state.loading) {
|
||||
appTileBody = (
|
||||
<div className='mx_AppTileBody mx_AppLoading'>
|
||||
<MessageSpinner msg='Loading...'/>
|
||||
<MessageSpinner msg='Loading...' />
|
||||
</div>
|
||||
);
|
||||
} else if (this.state.hasPermissionToLoad == true) {
|
||||
|
@ -312,19 +312,19 @@ export default React.createClass({
|
|||
return (
|
||||
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
|
||||
<div ref="menu_bar" className="mx_AppTileMenuBar" onClick={this.onClickMenuBar}>
|
||||
{this.formatAppTileName()}
|
||||
{ this.formatAppTileName() }
|
||||
<span className="mx_AppTileMenuBarWidgets">
|
||||
{/* Edit widget */}
|
||||
{showEditButton && <img
|
||||
{ /* Edit widget */ }
|
||||
{ showEditButton && <img
|
||||
src="img/edit.svg"
|
||||
className="mx_filterFlipColor mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
|
||||
width="8" height="8"
|
||||
alt={_t('Edit')}
|
||||
title={_t('Edit')}
|
||||
onClick={this._onEditClick}
|
||||
/>}
|
||||
/> }
|
||||
|
||||
{/* Delete widget */}
|
||||
{ /* Delete widget */ }
|
||||
<img src={deleteIcon}
|
||||
className={deleteClasses}
|
||||
width="8" height="8"
|
||||
|
@ -334,7 +334,7 @@ export default React.createClass({
|
|||
/>
|
||||
</span>
|
||||
</div>
|
||||
{appTileBody}
|
||||
{ appTileBody }
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -6,10 +6,10 @@ const AppWarning = (props) => {
|
|||
return (
|
||||
<div className='mx_AppPermissionWarning'>
|
||||
<div className='mx_AppPermissionWarningImage'>
|
||||
<img src='img/warning.svg' alt={_t('Warning!')}/>
|
||||
<img src='img/warning.svg' alt={_t('Warning!')} />
|
||||
</div>
|
||||
<div className='mx_AppPermissionWarningText'>
|
||||
<span className='mx_AppPermissionWarningTextLabel'>{props.errorMsg}</span>
|
||||
<span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -238,11 +238,11 @@ export default class Flair extends React.Component {
|
|||
return <div />;
|
||||
}
|
||||
const avatars = this.state.profiles.map((profile, index) => {
|
||||
return <FlairAvatar key={index} groupProfile={profile}/>;
|
||||
return <FlairAvatar key={index} groupProfile={profile} />;
|
||||
});
|
||||
return (
|
||||
<span className="mx_Flair" style={{"marginLeft": "5px", "verticalAlign": "-3px"}}>
|
||||
{avatars}
|
||||
{ avatars }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ export default class ManageIntegsButton extends React.Component {
|
|||
});
|
||||
|
||||
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)
|
||||
integrationsErrorPopup = (
|
||||
<span className="mx_RoomSettings_integrationsButton_errorPopup">
|
||||
|
@ -90,8 +90,8 @@ export default class ManageIntegsButton extends React.Component {
|
|||
}
|
||||
|
||||
integrationsButton = (
|
||||
<AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={ _t('Manage Integrations') }>
|
||||
<TintableSvg src="img/icons-apps.svg" width="35" height="35"/>
|
||||
<AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={_t('Manage Integrations')}>
|
||||
<TintableSvg src="img/icons-apps.svg" width="35" height="35" />
|
||||
{ integrationsWarningTriangle }
|
||||
{ integrationsErrorPopup }
|
||||
</AccessibleButton>
|
||||
|
|
|
@ -26,8 +26,8 @@ module.exports = React.createClass({
|
|||
const msg = this.props.msg || "Loading...";
|
||||
return (
|
||||
<div className="mx_Spinner">
|
||||
<div className="mx_Spinner_Msg">{msg}</div>
|
||||
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
|
||||
<div className="mx_Spinner_Msg">{ msg }</div>
|
||||
<img src="img/spinner.gif" width={w} height={h} className={imgClass} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -167,7 +167,7 @@ const Pill = React.createClass({
|
|||
userId = member.userId;
|
||||
linkText = member.rawDisplayName.replace(' (IRC)', ''); // FIXME when groups are done
|
||||
if (this.props.shouldShowPillAvatar) {
|
||||
avatar = <MemberAvatar member={member} width={16} height={16}/>;
|
||||
avatar = <MemberAvatar member={member} width={16} height={16} />;
|
||||
}
|
||||
pillClass = 'mx_UserPill';
|
||||
href = null;
|
||||
|
@ -180,7 +180,7 @@ const Pill = React.createClass({
|
|||
if (room) {
|
||||
linkText = (room ? getDisplayAliasForRoom(room) : null) || resource;
|
||||
if (this.props.shouldShowPillAvatar) {
|
||||
avatar = <RoomAvatar room={room} width={16} height={16}/>;
|
||||
avatar = <RoomAvatar room={room} width={16} height={16} />;
|
||||
}
|
||||
pillClass = 'mx_RoomPill';
|
||||
}
|
||||
|
@ -195,12 +195,12 @@ const Pill = React.createClass({
|
|||
if (this.state.pillType) {
|
||||
return this.props.inMessage ?
|
||||
<a className={classes} href={href} onClick={onClick} title={resource} data-offset-key={this.props.offsetKey}>
|
||||
{avatar}
|
||||
{linkText}
|
||||
{ avatar }
|
||||
{ linkText }
|
||||
</a> :
|
||||
<span className={classes} title={resource} data-offset-key={this.props.offsetKey}>
|
||||
{avatar}
|
||||
{linkText}
|
||||
{ avatar }
|
||||
{ linkText }
|
||||
</span>;
|
||||
} else {
|
||||
// Deliberately render nothing if the URL isn't recognised
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = React.createClass({
|
|||
truncateAt: 2,
|
||||
createOverflowElement: function(overflowCount, totalCount) {
|
||||
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 (
|
||||
<div className={this.props.className}>
|
||||
{childNodes}
|
||||
{overflowNode}
|
||||
{ childNodes }
|
||||
{ overflowNode }
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -50,7 +50,7 @@ export default React.createClass({
|
|||
className="mx_GroupInviteTile_name"
|
||||
dir="auto"
|
||||
>
|
||||
{this.props.group.name}
|
||||
{ this.props.group.name }
|
||||
</EmojiText>;
|
||||
|
||||
const badge = <div className="mx_GroupInviteTile_badge">!</div>;
|
||||
|
@ -58,11 +58,11 @@ export default React.createClass({
|
|||
return (
|
||||
<AccessibleButton className="mx_GroupInviteTile" onClick={this.onClick}>
|
||||
<div className="mx_GroupInviteTile_avatarContainer">
|
||||
{av}
|
||||
{ av }
|
||||
</div>
|
||||
<div className="mx_GroupInviteTile_nameContainer">
|
||||
{label}
|
||||
{badge}
|
||||
{ label }
|
||||
{ badge }
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
|
|
@ -128,7 +128,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
kickButton = (
|
||||
<AccessibleButton className="mx_MemberInfo_field"
|
||||
onClick={this._onKick}>
|
||||
{_t('Remove from group')}
|
||||
{ _t('Remove from group') }
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
||||
|
@ -143,11 +143,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (kickButton || adminButton) {
|
||||
adminTools =
|
||||
<div className="mx_MemberInfo_adminTools">
|
||||
<h3>{_t("Admin Tools")}</h3>
|
||||
<h3>{ _t("Admin Tools") }</h3>
|
||||
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
{kickButton}
|
||||
{adminButton}
|
||||
{ kickButton }
|
||||
{ adminButton }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
@ -173,13 +173,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
<div className="mx_MemberInfo">
|
||||
<GeminiScrollbar autoshow={true}>
|
||||
<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>
|
||||
<div className="mx_MemberInfo_avatar">
|
||||
{avatar}
|
||||
{ avatar }
|
||||
</div>
|
||||
|
||||
<EmojiText element="h2">{groupMemberName}</EmojiText>
|
||||
<EmojiText element="h2">{ groupMemberName }</EmojiText>
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
|
|
|
@ -135,7 +135,7 @@ export default withMatrixClient(React.createClass({
|
|||
<form autoComplete="off">
|
||||
<input className="mx_GroupMemberList_query" id="mx_GroupMemberList_query" type="text"
|
||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||
placeholder={ _t('Filter group members') } />
|
||||
placeholder={_t('Filter group members')} />
|
||||
</form>
|
||||
);
|
||||
|
||||
|
@ -146,7 +146,7 @@ export default withMatrixClient(React.createClass({
|
|||
<GeminiScrollbar autoshow={true} className="mx_MemberList_joined mx_MemberList_outerWrapper">
|
||||
<TruncatedList className="mx_MemberList_wrapper" truncateAt={this.state.truncateAt}
|
||||
createOverflowElement={this._createOverflowTile}>
|
||||
{this.makeGroupMemberTiles(this.state.searchQuery)}
|
||||
{ this.makeGroupMemberTiles(this.state.searchQuery) }
|
||||
</TruncatedList>
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
|
|
|
@ -123,7 +123,7 @@ export default React.createClass({
|
|||
<form autoComplete="off">
|
||||
<input className="mx_GroupRoomList_query" id="mx_GroupRoomList_query" type="text"
|
||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||
placeholder={ _t('Filter group rooms') } />
|
||||
placeholder={_t('Filter group rooms')} />
|
||||
</form>
|
||||
);
|
||||
|
||||
|
@ -134,7 +134,7 @@ export default React.createClass({
|
|||
<GeminiScrollbar autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
||||
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
||||
createOverflowElement={this._createOverflowTile}>
|
||||
{this.makeGroupRoomTiles(this.state.searchQuery)}
|
||||
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
||||
</TruncatedList>
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
|
|
|
@ -71,10 +71,10 @@ const GroupRoomTile = React.createClass({
|
|||
return (
|
||||
<AccessibleButton className="mx_GroupRoomTile" onClick={this.onClick}>
|
||||
<div className="mx_GroupRoomTile_avatar">
|
||||
{av}
|
||||
{ av }
|
||||
</div>
|
||||
<div className="mx_GroupRoomTile_name">
|
||||
{name}
|
||||
{ name }
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
|
|
@ -25,7 +25,7 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -32,9 +32,9 @@ export default function SenderProfile(props) {
|
|||
|
||||
return (
|
||||
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
|
||||
<EmojiText className="mx_SenderProfile_name">{name || ''}</EmojiText>
|
||||
{props.enableFlair ? <Flair userId={mxEvent.getSender()} /> : null}
|
||||
{props.aux ? <EmojiText className="mx_SenderProfile_aux"> {props.aux}</EmojiText> : null}
|
||||
<EmojiText className="mx_SenderProfile_name">{ name || '' }</EmojiText>
|
||||
{ props.enableFlair ? <Flair userId={mxEvent.getSender()} /> : null }
|
||||
{ props.aux ? <EmojiText className="mx_SenderProfile_aux"> { props.aux }</EmojiText> : null }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports = React.createClass({
|
|||
const text = this.props.mxEvent.getContent().body;
|
||||
return (
|
||||
<span className="mx_UnknownBody" title={tooltip}>
|
||||
{text}
|
||||
{ text }
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -231,16 +231,16 @@ module.exports = React.createClass({
|
|||
"mx_AddWidget_button"
|
||||
}
|
||||
title={_t('Add a widget')}>
|
||||
[+] {_t('Add a widget')}
|
||||
[+] { _t('Add a widget') }
|
||||
</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_AppsDrawer">
|
||||
<div id="apps" className="mx_AppsContainer">
|
||||
{apps}
|
||||
{ apps }
|
||||
</div>
|
||||
{this._canUserModify() && addWidget}
|
||||
{ this._canUserModify() && addWidget }
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -61,7 +61,7 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -186,18 +186,18 @@ module.exports = React.createClass({
|
|||
|
||||
saveButton = (
|
||||
<AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
|
||||
{_t("Save")}
|
||||
{ _t("Save") }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.onCancelClick) {
|
||||
cancelButton = <CancelButton onClick={this.props.onCancelClick}/>;
|
||||
cancelButton = <CancelButton onClick={this.props.onCancelClick} />;
|
||||
}
|
||||
|
||||
if (this.props.saving) {
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
spinner = <div className="mx_RoomHeader_spinner"><Spinner/></div>;
|
||||
spinner = <div className="mx_RoomHeader_spinner"><Spinner /></div>;
|
||||
}
|
||||
|
||||
if (canSetRoomName) {
|
||||
|
@ -254,7 +254,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
if (topic) {
|
||||
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) {
|
||||
roomAvatar = (
|
||||
<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} />
|
||||
</div>
|
||||
<div className="mx_RoomHeader_avatarPicker_edit">
|
||||
<label htmlFor="avatarInput" ref="file_label">
|
||||
<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" />
|
||||
</label>
|
||||
<input id="avatarInput" type="file" onChange={ this.onAvatarSelected }/>
|
||||
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -286,7 +286,7 @@ module.exports = React.createClass({
|
|||
if (this.props.onSettingsClick) {
|
||||
settingsButton =
|
||||
<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>;
|
||||
}
|
||||
|
||||
|
@ -301,24 +301,24 @@ module.exports = React.createClass({
|
|||
let forgetButton;
|
||||
if (this.props.onForgetClick) {
|
||||
forgetButton =
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={ _t("Forget room") }>
|
||||
<TintableSvg src="img/leave.svg" width="26" height="20"/>
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}>
|
||||
<TintableSvg src="img/leave.svg" width="26" height="20" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
let searchButton;
|
||||
if (this.props.onSearchClick && this.props.inRoom) {
|
||||
searchButton =
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={ _t("Search") }>
|
||||
<TintableSvg src="img/icons-search.svg" width="35" height="35"/>
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}>
|
||||
<TintableSvg src="img/icons-search.svg" width="35" height="35" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
let rightPanelButtons;
|
||||
if (this.props.collapsedRhs) {
|
||||
rightPanelButtons =
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShowRhsClick} title={ _t('Show panel') }>
|
||||
<TintableSvg src="img/maximise.svg" width="10" height="16"/>
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShowRhsClick} title={_t('Show panel')}>
|
||||
<TintableSvg src="img/maximise.svg" width="10" height="16" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
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_leftRow">
|
||||
<div className="mx_RoomHeader_avatar">
|
||||
|
@ -353,10 +353,10 @@ module.exports = React.createClass({
|
|||
{ topicElement }
|
||||
</div>
|
||||
</div>
|
||||
{spinner}
|
||||
{saveButton}
|
||||
{cancelButton}
|
||||
{rightRow}
|
||||
{ spinner }
|
||||
{ saveButton }
|
||||
{ cancelButton }
|
||||
{ rightRow }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -26,7 +26,7 @@ export function CancelButton(props) {
|
|||
return (
|
||||
<AccessibleButton className='mx_RoomHeader_cancelButton' onClick={onClick}>
|
||||
<img src="img/cancel.svg" className='mx_filterFlipColor'
|
||||
width="18" height="18" alt={_t("Cancel")}/>
|
||||
width="18" height="18" alt={_t("Cancel")} />
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -129,17 +129,17 @@ module.exports = React.createClass({
|
|||
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
||||
const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
||||
voice = (
|
||||
<div className="mx_CallView_voice" onClick={ this.props.onClick }>
|
||||
{_t("Active call (%(roomName)s)", {roomName: callRoom.name})}
|
||||
<div className="mx_CallView_voice" onClick={this.props.onClick}>
|
||||
{ _t("Active call (%(roomName)s)", {roomName: callRoom.name}) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<VideoView ref="video" onClick={ this.props.onClick }
|
||||
onResize={ this.props.onResize }
|
||||
maxHeight={ this.props.maxVideoHeight }
|
||||
<VideoView ref="video" onClick={this.props.onClick}
|
||||
onResize={this.props.onResize}
|
||||
maxHeight={this.props.maxVideoHeight}
|
||||
/>
|
||||
{ voice }
|
||||
</div>
|
||||
|
|
|
@ -62,17 +62,17 @@ module.exports = React.createClass({
|
|||
<div className="mx_IncomingCallBox" id="incomingCallBox">
|
||||
<img className="mx_IncomingCallBox_chevron" src="img/chevron-left.png" width="9" height="16" />
|
||||
<div className="mx_IncomingCallBox_title">
|
||||
{incomingCallText}
|
||||
{ incomingCallText }
|
||||
</div>
|
||||
<div className="mx_IncomingCallBox_buttons">
|
||||
<div className="mx_IncomingCallBox_buttons_cell">
|
||||
<div className="mx_IncomingCallBox_buttons_decline" onClick={this.onRejectClick}>
|
||||
{_t("Decline")}
|
||||
{ _t("Decline") }
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_IncomingCallBox_buttons_cell">
|
||||
<div className="mx_IncomingCallBox_buttons_accept" onClick={this.onAnswerClick}>
|
||||
{_t("Accept")}
|
||||
{ _t("Accept") }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -110,13 +110,13 @@ module.exports = React.createClass({
|
|||
const maxVideoHeight = fullscreenElement ? null : this.props.maxHeight;
|
||||
|
||||
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">
|
||||
<VideoFeed ref="remote" onResize={this.props.onResize}
|
||||
maxHeight={maxVideoHeight} />
|
||||
</div>
|
||||
<div className="mx_VideoView_localVideoFeed">
|
||||
<VideoFeed ref="local"/>
|
||||
<VideoFeed ref="local" />
|
||||
</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!",
|
||||
"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 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)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",
|
||||
|
|
|
@ -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 <a>disabled</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 need to be able to invite users to do that.": "Για να το κάνετε αυτό πρέπει να έχετε τη δυνατότητα να προσκαλέσετε χρήστες.",
|
||||
"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 <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 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 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",
|
||||
|
@ -891,5 +890,10 @@
|
|||
"Unpublish": "Unpublish",
|
||||
"This group is published on your profile": "This group is published on your profile",
|
||||
"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 <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 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 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.",
|
||||
|
|
|
@ -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 <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 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 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",
|
||||
|
|
|
@ -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 <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 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 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:",
|
||||
|
|
|
@ -679,7 +679,6 @@
|
|||
"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>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",
|
||||
"Add": "Ajouter",
|
||||
"%(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 <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 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 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:",
|
||||
|
|
|
@ -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 <a>disabled</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 may wish to login with a different account, or add this email to this account.": "다른 계정으로 로그인하거나, 이 이메일을 이 계정에 추가할 수도 있어요.",
|
||||
"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 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 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 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>",
|
||||
|
|
|
@ -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 <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 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 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",
|
||||
|
|
|
@ -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 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 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 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ć",
|
||||
|
|
|
@ -733,7 +733,6 @@
|
|||
"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>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.",
|
||||
"Send anyway": "Enviar de qualquer maneira",
|
||||
"This room": "Esta sala",
|
||||
|
|
|
@ -730,7 +730,6 @@
|
|||
"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>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",
|
||||
"Add": "Adicionar",
|
||||
"%(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\". Это может означать, что ваше общение перехватывается!",
|
||||
"You have <a>disabled</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 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.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.",
|
||||
|
|
|
@ -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 <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 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 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",
|
||||
|
|
|
@ -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 <a>disabled</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 不支持设备管理。",
|
||||
"Set a display name:": "设置一个昵称:",
|
||||
"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 <a>disabled</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 may wish to login with a different account, or add this email to this account.": "您可能會想要以不同的帳號登入,或是把這個電子郵件加入到此帳號中。",
|
||||
"you must be a": "您一定是",
|
||||
|
|
Loading…
Reference in a new issue