Merge in upstream changes
This commit is contained in:
commit
876899948f
126 changed files with 6421 additions and 1378 deletions
|
@ -19,8 +19,10 @@ import MatrixClientPeg from './MatrixClientPeg';
|
|||
import PlatformPeg from './PlatformPeg';
|
||||
import SdkConfig from './SdkConfig';
|
||||
|
||||
function redact(str) {
|
||||
return str.replace(/#\/(room|user)\/(.+)/, "#/$1/<redacted>");
|
||||
function getRedactedUrl() {
|
||||
const redactedHash = window.location.hash.replace(/#\/(room|user)\/(.+)/, "#/$1/<redacted>");
|
||||
// hardcoded url to make piwik happy
|
||||
return 'https://riot.im/app/' + redactedHash;
|
||||
}
|
||||
|
||||
const customVariables = {
|
||||
|
@ -28,6 +30,7 @@ const customVariables = {
|
|||
'App Version': 2,
|
||||
'User Type': 3,
|
||||
'Chosen Language': 4,
|
||||
'Instance': 5,
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,6 +56,7 @@ class Analytics {
|
|||
* but this is second best, Piwik should not pull anything implicitly.
|
||||
*/
|
||||
disable() {
|
||||
this.trackEvent('Analytics', 'opt-out');
|
||||
this.disabled = true;
|
||||
}
|
||||
|
||||
|
@ -84,6 +88,10 @@ class Analytics {
|
|||
|
||||
this._setVisitVariable('Chosen Language', getCurrentLanguage());
|
||||
|
||||
if (window.location.hostname === 'riot.im') {
|
||||
this._setVisitVariable('Instance', window.location.pathname);
|
||||
}
|
||||
|
||||
(function() {
|
||||
const g = document.createElement('script');
|
||||
const s = document.getElementsByTagName('script')[0];
|
||||
|
@ -108,7 +116,7 @@ class Analytics {
|
|||
this.firstPage = false;
|
||||
return;
|
||||
}
|
||||
this._paq.push(['setCustomUrl', redact(window.location.href)]);
|
||||
this._paq.push(['setCustomUrl', getRedactedUrl()]);
|
||||
this._paq.push(['trackPageView']);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
import UserSettingsStore from './UserSettingsStore';
|
||||
import * as Matrix from 'matrix-js-sdk';
|
||||
import q from 'q';
|
||||
|
||||
export default {
|
||||
getDevices: function() {
|
||||
|
|
|
@ -345,6 +345,7 @@ export function bodyToHtml(content, highlights, opts) {
|
|||
}
|
||||
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
|
||||
safeBody = unicodeToImage(safeBody);
|
||||
safeBody = addCodeCopyButton(safeBody);
|
||||
}
|
||||
finally {
|
||||
delete sanitizeHtmlParams.textFilter;
|
||||
|
@ -363,6 +364,23 @@ export function bodyToHtml(content, highlights, opts) {
|
|||
return <span className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" />;
|
||||
}
|
||||
|
||||
function addCodeCopyButton(safeBody) {
|
||||
// Adds 'copy' buttons to pre blocks
|
||||
// Note that this only manipulates the markup to add the buttons:
|
||||
// we need to add the event handlers once the nodes are in the DOM
|
||||
// since we can't save functions in the markup.
|
||||
// This is done in TextualBody
|
||||
const el = document.createElement("div");
|
||||
el.innerHTML = safeBody;
|
||||
const codeBlocks = Array.from(el.getElementsByTagName("pre"));
|
||||
codeBlocks.forEach(p => {
|
||||
const button = document.createElement("span");
|
||||
button.className = "mx_EventTile_copyButton";
|
||||
p.appendChild(button);
|
||||
});
|
||||
return el.innerHTML;
|
||||
}
|
||||
|
||||
export function emojifyText(text) {
|
||||
return {
|
||||
__html: unicodeToImage(escape(text)),
|
||||
|
|
|
@ -32,4 +32,5 @@ module.exports = {
|
|||
DELETE: 46,
|
||||
KEY_D: 68,
|
||||
KEY_E: 69,
|
||||
KEY_M: 77,
|
||||
};
|
||||
|
|
|
@ -187,6 +187,14 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) {
|
|||
|
||||
// returns a promise which resolves to true if a session is found in
|
||||
// localstorage
|
||||
//
|
||||
// N.B. Lifecycle.js should not maintain any further localStorage state, we
|
||||
// are moving towards using SessionStore to keep track of state related
|
||||
// to the current session (which is typically backed by localStorage).
|
||||
//
|
||||
// The plan is to gradually move the localStorage access done here into
|
||||
// SessionStore to avoid bugs where the view becomes out-of-sync with
|
||||
// localStorage (e.g. teamToken, isGuest etc.)
|
||||
function _restoreFromLocalStorage() {
|
||||
if (!localStorage) {
|
||||
return q(false);
|
||||
|
@ -314,6 +322,16 @@ export function setLoggedIn(credentials) {
|
|||
localStorage.setItem("mx_device_id", credentials.deviceId);
|
||||
}
|
||||
|
||||
// The user registered as a PWLU (PassWord-Less User), the generated password
|
||||
// is cached here such that the user can change it at a later time.
|
||||
if (credentials.password) {
|
||||
// Update SessionStore
|
||||
dis.dispatch({
|
||||
action: 'cached_password',
|
||||
cachedPassword: credentials.password,
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Session persisted for %s", credentials.userId);
|
||||
} catch (e) {
|
||||
console.warn("Error using local storage: can't persist session!", e);
|
||||
|
|
20
src/Login.js
20
src/Login.js
|
@ -97,11 +97,6 @@ export default class Login {
|
|||
guest: true
|
||||
};
|
||||
}, (error) => {
|
||||
if (error.httpStatus === 403) {
|
||||
error.friendlyText = _t("Guest access is disabled on this Home Server.");
|
||||
} else {
|
||||
error.friendlyText = _t("Failed to register as guest:") + ' ' + error.data;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
@ -157,15 +152,7 @@ export default class Login {
|
|||
accessToken: data.access_token
|
||||
});
|
||||
}, function(error) {
|
||||
if (error.httpStatus == 400 && loginParams.medium) {
|
||||
error.friendlyText = (
|
||||
_t('This Home Server does not support login using email address.')
|
||||
);
|
||||
}
|
||||
else if (error.httpStatus === 403) {
|
||||
error.friendlyText = (
|
||||
_t('Incorrect username and/or password.')
|
||||
);
|
||||
if (error.httpStatus === 403) {
|
||||
if (self._fallbackHsUrl) {
|
||||
var fbClient = Matrix.createClient({
|
||||
baseUrl: self._fallbackHsUrl,
|
||||
|
@ -186,11 +173,6 @@ export default class Login {
|
|||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
error.friendlyText = (
|
||||
_t("There was a problem logging in.") + ' (HTTP ' + error.httpStatus + ")"
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
import q from "q";
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
import utils from 'matrix-js-sdk/lib/utils';
|
||||
import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline';
|
||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import MatrixClientPeg from './MatrixClientPeg';
|
||||
import DMRoomMap from './utils/DMRoomMap';
|
||||
import q from 'q';
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,6 +94,22 @@ Example:
|
|||
}
|
||||
}
|
||||
|
||||
get_membership_count
|
||||
--------------------
|
||||
Get the number of joined users in the room.
|
||||
|
||||
Request:
|
||||
- room_id is the room to get the count in.
|
||||
Response:
|
||||
78
|
||||
Example:
|
||||
{
|
||||
action: "get_membership_count",
|
||||
room_id: "!foo:bar",
|
||||
response: 78
|
||||
}
|
||||
|
||||
|
||||
membership_state AND bot_options
|
||||
--------------------------------
|
||||
Get the content of the "m.room.member" or "m.room.bot.options" state event respectively.
|
||||
|
@ -256,6 +272,21 @@ function botOptions(event, roomId, userId) {
|
|||
returnStateEvent(event, roomId, "m.room.bot.options", "_" + userId);
|
||||
}
|
||||
|
||||
function getMembershipCount(event, roomId) {
|
||||
const client = MatrixClientPeg.get();
|
||||
if (!client) {
|
||||
sendError(event, _t('You need to be logged in.'));
|
||||
return;
|
||||
}
|
||||
const room = client.getRoom(roomId);
|
||||
if (!room) {
|
||||
sendError(event, _t('This room is not recognised.'));
|
||||
return;
|
||||
}
|
||||
const count = room.getJoinedMembers().length;
|
||||
sendResponse(event, count);
|
||||
}
|
||||
|
||||
function returnStateEvent(event, roomId, eventType, stateKey) {
|
||||
const client = MatrixClientPeg.get();
|
||||
if (!client) {
|
||||
|
@ -343,6 +374,9 @@ const onMessage = function(event) {
|
|||
} else if (event.data.action === "set_plumbing_state") {
|
||||
setPlumbingState(event, roomId, event.data.status);
|
||||
return;
|
||||
} else if (event.data.action === "get_membership_count") {
|
||||
getMembershipCount(event, roomId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
|
|
|
@ -120,7 +120,7 @@ export default React.createClass({
|
|||
'you have received in encrypted rooms to a local file. You ' +
|
||||
'will then be able to import the file into another Matrix ' +
|
||||
'client in the future, so that client will also be able to ' +
|
||||
'decrypt these messages.'
|
||||
'decrypt these messages.',
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
|
@ -130,7 +130,7 @@ export default React.createClass({
|
|||
'careful to keep it secure. To help with this, you should enter ' +
|
||||
'a passphrase below, which will be used to encrypt the exported ' +
|
||||
'data. It will only be possible to import the data by using the ' +
|
||||
'same passphrase.'
|
||||
'same passphrase.',
|
||||
) }
|
||||
</p>
|
||||
<div className='error'>
|
||||
|
|
|
@ -122,13 +122,13 @@ export default React.createClass({
|
|||
'This process allows you to import encryption keys ' +
|
||||
'that you had previously exported from another Matrix ' +
|
||||
'client. You will then be able to decrypt any ' +
|
||||
'messages that the other client could decrypt.'
|
||||
'messages that the other client could decrypt.',
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ _t(
|
||||
'The export file will be protected with a passphrase. ' +
|
||||
'You should enter the passphrase here, to decrypt the file.'
|
||||
'You should enter the passphrase here, to decrypt the file.',
|
||||
) }
|
||||
</p>
|
||||
<div className='error'>
|
||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/* These were earlier stateless functional components but had to be converted
|
||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import { _t } from '../languageHandler';
|
||||
import AutocompleteProvider from './AutocompleteProvider';
|
||||
import Q from 'q';
|
||||
import Fuse from 'fuse.js';
|
||||
import {PillCompletion} from './Components';
|
||||
import sdk from '../index';
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import q from 'q';
|
||||
import { _t } from '../../languageHandler';
|
||||
import sdk from '../../index';
|
||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||
|
@ -232,7 +231,7 @@ module.exports = React.createClass({
|
|||
if (curr_phase == this.phases.ERROR) {
|
||||
error_box = (
|
||||
<div className="mx_Error">
|
||||
{_t('An error occured: %(error_string)s', {error_string: this.state.error_string})}
|
||||
{_t('An error occurred: %(error_string)s', {error_string: this.state.error_string})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -247,7 +246,7 @@ module.exports = React.createClass({
|
|||
|
||||
return (
|
||||
<div className="mx_CreateRoom">
|
||||
<SimpleRoomHeader title="CreateRoom" collapsedRhs={ this.props.collapsedRhs }/>
|
||||
<SimpleRoomHeader title={_t("Create Room")} collapsedRhs={ this.props.collapsedRhs }/>
|
||||
<div className="mx_CreateRoom_body">
|
||||
<input type="text" ref="room_name" value={this.state.room_name} onChange={this.onNameChange} placeholder={_t('Name')}/> <br />
|
||||
<textarea className="mx_CreateRoom_description" ref="topic" value={this.state.topic} onChange={this.onTopicChange} placeholder={_t('Topic')}/> <br />
|
||||
|
|
|
@ -19,7 +19,7 @@ import React from 'react';
|
|||
import Matrix from 'matrix-js-sdk';
|
||||
import sdk from '../../index';
|
||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||
import { _t } from '../../languageHandler';
|
||||
import { _t, _tJsx } from '../../languageHandler';
|
||||
|
||||
/*
|
||||
* Component which shows the filtered file using a TimelinePanel
|
||||
|
@ -91,7 +91,9 @@ var FilePanel = React.createClass({
|
|||
render: function() {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
||||
<div className="mx_RoomView_empty">You must <a href="#/register">register</a> to use this functionality</div>
|
||||
<div className="mx_RoomView_empty">
|
||||
{_tJsx("You must <a>register</a> to use this functionality", /<a>(.*?)<\/a>/, (sub) => <a href="#/register" key="sub">{sub}</a>)}
|
||||
</div>
|
||||
</div>;
|
||||
} else if (this.noRoom) {
|
||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
||||
|
|
|
@ -19,8 +19,6 @@ const InteractiveAuth = Matrix.InteractiveAuth;
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import sdk from '../../index';
|
||||
|
||||
import {getEntryComponentForLoginType} from '../views/login/InteractiveAuthEntryComponents';
|
||||
|
||||
export default React.createClass({
|
||||
|
|
|
@ -25,6 +25,8 @@ import PageTypes from '../../PageTypes';
|
|||
import CallMediaHandler from '../../CallMediaHandler';
|
||||
import sdk from '../../index';
|
||||
import dis from '../../dispatcher';
|
||||
import sessionStore from '../../stores/SessionStore';
|
||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||
|
||||
/**
|
||||
* This is what our MatrixChat shows when we are logged in. The precise view is
|
||||
|
@ -41,10 +43,13 @@ export default React.createClass({
|
|||
propTypes: {
|
||||
matrixClient: React.PropTypes.instanceOf(Matrix.MatrixClient).isRequired,
|
||||
page_type: React.PropTypes.string.isRequired,
|
||||
onRoomIdResolved: React.PropTypes.func,
|
||||
onRoomCreated: React.PropTypes.func,
|
||||
onUserSettingsClose: React.PropTypes.func,
|
||||
|
||||
// Called with the credentials of a registered user (if they were a ROU that
|
||||
// transitioned to PWLU)
|
||||
onRegistered: React.PropTypes.func,
|
||||
|
||||
teamToken: React.PropTypes.string,
|
||||
|
||||
// and lots and lots of other stuff.
|
||||
|
@ -83,12 +88,32 @@ export default React.createClass({
|
|||
CallMediaHandler.loadDevices();
|
||||
|
||||
document.addEventListener('keydown', this._onKeyDown);
|
||||
|
||||
this._sessionStore = sessionStore;
|
||||
this._sessionStoreToken = this._sessionStore.addListener(
|
||||
this._setStateFromSessionStore,
|
||||
);
|
||||
this._setStateFromSessionStore();
|
||||
|
||||
this._matrixClient.on("accountData", this.onAccountData);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
document.removeEventListener('keydown', this._onKeyDown);
|
||||
this._matrixClient.removeListener("accountData", this.onAccountData);
|
||||
if (this._sessionStoreToken) {
|
||||
this._sessionStoreToken.remove();
|
||||
}
|
||||
},
|
||||
|
||||
// Child components assume that the client peg will not be null, so give them some
|
||||
// sort of assurance here by only allowing a re-render if the client is truthy.
|
||||
//
|
||||
// This is required because `LoggedInView` maintains its own state and if this state
|
||||
// updates after the client peg has been made null (during logout), then it will
|
||||
// attempt to re-render and the children will throw errors.
|
||||
shouldComponentUpdate: function() {
|
||||
return Boolean(MatrixClientPeg.get());
|
||||
},
|
||||
|
||||
getScrollStateForRoom: function(roomId) {
|
||||
|
@ -102,10 +127,16 @@ export default React.createClass({
|
|||
return this.refs.roomView.canResetTimeline();
|
||||
},
|
||||
|
||||
_setStateFromSessionStore() {
|
||||
this.setState({
|
||||
userHasGeneratedPassword: Boolean(this._sessionStore.getCachedPassword()),
|
||||
});
|
||||
},
|
||||
|
||||
onAccountData: function(event) {
|
||||
if (event.getType() === "im.vector.web.settings") {
|
||||
this.setState({
|
||||
useCompactLayout: event.getContent().useCompactLayout
|
||||
useCompactLayout: event.getContent().useCompactLayout,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -180,8 +211,8 @@ export default React.createClass({
|
|||
const RoomDirectory = sdk.getComponent('structures.RoomDirectory');
|
||||
const HomePage = sdk.getComponent('structures.HomePage');
|
||||
const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
|
||||
const GuestWarningBar = sdk.getComponent('globals.GuestWarningBar');
|
||||
const NewVersionBar = sdk.getComponent('globals.NewVersionBar');
|
||||
const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar');
|
||||
|
||||
let page_element;
|
||||
let right_panel = '';
|
||||
|
@ -190,15 +221,12 @@ export default React.createClass({
|
|||
case PageTypes.RoomView:
|
||||
page_element = <RoomView
|
||||
ref='roomView'
|
||||
roomAddress={this.props.currentRoomAlias || this.props.currentRoomId}
|
||||
autoJoin={this.props.autoJoin}
|
||||
onRoomIdResolved={this.props.onRoomIdResolved}
|
||||
eventId={this.props.initialEventId}
|
||||
onRegistered={this.props.onRegistered}
|
||||
thirdPartyInvite={this.props.thirdPartyInvite}
|
||||
oobData={this.props.roomOobData}
|
||||
highlightedEventId={this.props.highlightedEventId}
|
||||
eventPixelOffset={this.props.initialEventPixelOffset}
|
||||
key={this.props.currentRoomAlias || this.props.currentRoomId}
|
||||
key={this.props.currentRoomId || 'roomview'}
|
||||
opacity={this.props.middleOpacity}
|
||||
collapsedRhs={this.props.collapse_rhs}
|
||||
ConferenceHandler={this.props.ConferenceHandler}
|
||||
|
@ -235,12 +263,18 @@ export default React.createClass({
|
|||
break;
|
||||
|
||||
case PageTypes.HomePage:
|
||||
// If team server config is present, pass the teamServerURL. props.teamToken
|
||||
// must also be set for the team page to be displayed, otherwise the
|
||||
// welcomePageUrl is used (which might be undefined).
|
||||
const teamServerUrl = this.props.config.teamServerConfig ?
|
||||
this.props.config.teamServerConfig.teamServerURL : null;
|
||||
|
||||
page_element = <HomePage
|
||||
collapsedRhs={this.props.collapse_rhs}
|
||||
teamServerUrl={this.props.config.teamServerConfig.teamServerURL}
|
||||
teamServerUrl={teamServerUrl}
|
||||
teamToken={this.props.teamToken}
|
||||
/>
|
||||
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>
|
||||
homePageUrl={this.props.config.welcomePageUrl}
|
||||
/>;
|
||||
break;
|
||||
|
||||
case PageTypes.UserView:
|
||||
|
@ -249,16 +283,15 @@ export default React.createClass({
|
|||
break;
|
||||
}
|
||||
|
||||
const isGuest = this.props.matrixClient.isGuest();
|
||||
var topBar;
|
||||
if (this.props.hasNewVersion) {
|
||||
topBar = <NewVersionBar version={this.props.version} newVersion={this.props.newVersion}
|
||||
releaseNotes={this.props.newVersionReleaseNotes}
|
||||
/>;
|
||||
}
|
||||
else if (this.props.matrixClient.isGuest()) {
|
||||
topBar = <GuestWarningBar />;
|
||||
}
|
||||
else if (Notifier.supportsDesktopNotifications() && !Notifier.isEnabled() && !Notifier.isToolbarHidden()) {
|
||||
} else if (this.state.userHasGeneratedPassword) {
|
||||
topBar = <PasswordNagBar />;
|
||||
} else if (!isGuest && Notifier.supportsDesktopNotifications() && !Notifier.isEnabled() && !Notifier.isToolbarHidden()) {
|
||||
topBar = <MatrixToolbar />;
|
||||
}
|
||||
|
||||
|
@ -278,7 +311,6 @@ export default React.createClass({
|
|||
selectedRoom={this.props.currentRoomId}
|
||||
collapsed={this.props.collapse_lhs || false}
|
||||
opacity={this.props.leftOpacity}
|
||||
teamToken={this.props.teamToken}
|
||||
/>
|
||||
<main className='mx_MatrixChat_middlePanel'>
|
||||
{page_element}
|
||||
|
|
|
@ -34,6 +34,9 @@ import sdk from '../../index';
|
|||
import * as Rooms from '../../Rooms';
|
||||
import linkifyMatrix from "../../linkify-matrix";
|
||||
import * as Lifecycle from '../../Lifecycle';
|
||||
// LifecycleStore is not used but does listen to and dispatch actions
|
||||
import LifecycleStore from '../../stores/LifecycleStore';
|
||||
import RoomViewStore from '../../stores/RoomViewStore';
|
||||
import PageTypes from '../../PageTypes';
|
||||
|
||||
import createRoom from "../../createRoom";
|
||||
|
@ -102,9 +105,6 @@ module.exports = React.createClass({
|
|||
// What the LoggedInView would be showing if visible
|
||||
page_type: null,
|
||||
|
||||
// If we are viewing a room by alias, this contains the alias
|
||||
currentRoomAlias: null,
|
||||
|
||||
// The ID of the room we're viewing. This is either populated directly
|
||||
// in the case where we view a room by ID or by RoomView when it resolves
|
||||
// what ID an alias points at.
|
||||
|
@ -191,6 +191,9 @@ module.exports = React.createClass({
|
|||
componentWillMount: function() {
|
||||
SdkConfig.put(this.props.config);
|
||||
|
||||
RoomViewStore.addListener(this._onRoomViewStoreUpdated);
|
||||
this._onRoomViewStoreUpdated();
|
||||
|
||||
if (!UserSettingsStore.getLocalSetting('analyticsOptOut', false)) Analytics.enable();
|
||||
|
||||
// Used by _viewRoom before getting state from sync
|
||||
|
@ -322,7 +325,6 @@ module.exports = React.createClass({
|
|||
onAction: function(payload) {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog");
|
||||
|
||||
switch (payload.action) {
|
||||
case 'logout':
|
||||
|
@ -374,6 +376,11 @@ module.exports = React.createClass({
|
|||
});
|
||||
this.notifyNewScreen('forgot_password');
|
||||
break;
|
||||
case 'start_chat':
|
||||
createRoom({
|
||||
dmUserId: payload.user_id,
|
||||
});
|
||||
break;
|
||||
case 'leave_room':
|
||||
this._leaveRoom(payload.room_id);
|
||||
break;
|
||||
|
@ -434,37 +441,36 @@ module.exports = React.createClass({
|
|||
this._viewIndexedRoom(payload.roomIndex);
|
||||
break;
|
||||
case 'view_user_settings':
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
deferred_action: {
|
||||
action: 'view_user_settings',
|
||||
},
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
break;
|
||||
}
|
||||
this._setPage(PageTypes.UserSettings);
|
||||
this.notifyNewScreen('settings');
|
||||
break;
|
||||
case 'view_create_room':
|
||||
//this._setPage(PageTypes.CreateRoom);
|
||||
//this.notifyNewScreen('new');
|
||||
Modal.createDialog(TextInputDialog, {
|
||||
title: _t('Create Room'),
|
||||
description: _t('Room name (optional)'),
|
||||
button: _t('Create Room'),
|
||||
onFinished: (shouldCreate, name) => {
|
||||
if (shouldCreate) {
|
||||
const createOpts = {};
|
||||
if (name) createOpts.name = name;
|
||||
createRoom({createOpts}).done();
|
||||
}
|
||||
},
|
||||
});
|
||||
this._createRoom();
|
||||
break;
|
||||
case 'view_room_directory':
|
||||
this._setPage(PageTypes.RoomDirectory);
|
||||
this.notifyNewScreen('directory');
|
||||
break;
|
||||
case 'view_home_page':
|
||||
if (!this._teamToken) {
|
||||
dis.dispatch({action: 'view_room_directory'});
|
||||
return;
|
||||
}
|
||||
this._setPage(PageTypes.HomePage);
|
||||
this.notifyNewScreen('home');
|
||||
break;
|
||||
case 'view_set_mxid':
|
||||
this._setMxId(payload);
|
||||
break;
|
||||
case 'view_start_chat_or_reuse':
|
||||
this._chatCreateOrReuse(payload.user_id);
|
||||
break;
|
||||
case 'view_create_chat':
|
||||
this._createChat();
|
||||
break;
|
||||
|
@ -506,7 +512,11 @@ module.exports = React.createClass({
|
|||
this._onSetTheme(payload.value);
|
||||
break;
|
||||
case 'on_logging_in':
|
||||
this.setState({loggingIn: true});
|
||||
// We are now logging in, so set the state to reflect that
|
||||
// and also that we're not ready (we'll be marked as logged
|
||||
// in once the login completes, then ready once the sync
|
||||
// completes).
|
||||
this.setState({loggingIn: true, ready: false});
|
||||
break;
|
||||
case 'on_logged_in':
|
||||
this._onLoggedIn(payload.teamToken);
|
||||
|
@ -529,6 +539,10 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_onRoomViewStoreUpdated: function() {
|
||||
this.setState({ currentRoomId: RoomViewStore.getRoomId() });
|
||||
},
|
||||
|
||||
_setPage: function(pageType) {
|
||||
this.setState({
|
||||
page_type: pageType,
|
||||
|
@ -551,10 +565,20 @@ module.exports = React.createClass({
|
|||
this.notifyNewScreen('register');
|
||||
},
|
||||
|
||||
// TODO: Move to RoomViewStore
|
||||
_viewNextRoom: function(roomIndexDelta) {
|
||||
const allRooms = RoomListSorter.mostRecentActivityFirst(
|
||||
MatrixClientPeg.get().getRooms(),
|
||||
);
|
||||
// If there are 0 rooms or 1 room, view the home page because otherwise
|
||||
// if there are 0, we end up trying to index into an empty array, and
|
||||
// if there is 1, we end up viewing the same room.
|
||||
if (allRooms.length < 2) {
|
||||
dis.dispatch({
|
||||
action: 'view_home_page',
|
||||
});
|
||||
return;
|
||||
}
|
||||
let roomIndex = -1;
|
||||
for (let i = 0; i < allRooms.length; ++i) {
|
||||
if (allRooms[i].roomId == this.state.currentRoomId) {
|
||||
|
@ -564,15 +588,22 @@ module.exports = React.createClass({
|
|||
}
|
||||
roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
|
||||
if (roomIndex < 0) roomIndex = allRooms.length - 1;
|
||||
this._viewRoom({ room_id: allRooms[roomIndex].roomId });
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: allRooms[roomIndex].roomId,
|
||||
});
|
||||
},
|
||||
|
||||
// TODO: Move to RoomViewStore
|
||||
_viewIndexedRoom: function(roomIndex) {
|
||||
const allRooms = RoomListSorter.mostRecentActivityFirst(
|
||||
MatrixClientPeg.get().getRooms(),
|
||||
);
|
||||
if (allRooms[roomIndex]) {
|
||||
this._viewRoom({ room_id: allRooms[roomIndex].roomId });
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: allRooms[roomIndex].roomId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -585,6 +616,8 @@ module.exports = React.createClass({
|
|||
// @param {boolean=} roomInfo.show_settings Makes RoomView show the room settings dialog.
|
||||
// @param {string=} roomInfo.event_id ID of the event in this room to show: this will cause a switch to the
|
||||
// context of that particular event.
|
||||
// @param {boolean=} roomInfo.highlighted If true, add event_id to the hash of the URL
|
||||
// and alter the EventTile to appear highlighted.
|
||||
// @param {Object=} roomInfo.third_party_invite Object containing data about the third party
|
||||
// we received to join the room, if any.
|
||||
// @param {string=} roomInfo.third_party_invite.inviteSignUrl 3pid invite sign URL
|
||||
|
@ -596,30 +629,21 @@ module.exports = React.createClass({
|
|||
this.focusComposer = true;
|
||||
|
||||
const newState = {
|
||||
initialEventId: roomInfo.event_id,
|
||||
highlightedEventId: roomInfo.event_id,
|
||||
initialEventPixelOffset: undefined,
|
||||
page_type: PageTypes.RoomView,
|
||||
thirdPartyInvite: roomInfo.third_party_invite,
|
||||
roomOobData: roomInfo.oob_data,
|
||||
currentRoomAlias: roomInfo.room_alias,
|
||||
autoJoin: roomInfo.auto_join,
|
||||
};
|
||||
|
||||
if (!roomInfo.room_alias) {
|
||||
newState.currentRoomId = roomInfo.room_id;
|
||||
}
|
||||
|
||||
// if we aren't given an explicit event id, look for one in the
|
||||
// scrollStateMap.
|
||||
//
|
||||
// TODO: do this in RoomView rather than here
|
||||
if (!roomInfo.event_id && this.refs.loggedInView) {
|
||||
const scrollState = this.refs.loggedInView.getScrollStateForRoom(roomInfo.room_id);
|
||||
if (scrollState) {
|
||||
newState.initialEventId = scrollState.focussedEvent;
|
||||
newState.initialEventPixelOffset = scrollState.pixelOffset;
|
||||
}
|
||||
if (roomInfo.room_alias) {
|
||||
console.log(
|
||||
`Switching to room alias ${roomInfo.room_alias} at event ` +
|
||||
roomInfo.event_id,
|
||||
);
|
||||
} else {
|
||||
console.log(`Switching to room id ${roomInfo.room_id} at event ` +
|
||||
roomInfo.event_id,
|
||||
);
|
||||
}
|
||||
|
||||
// Wait for the first sync to complete so that if a room does have an alias,
|
||||
|
@ -647,7 +671,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
|
||||
if (roomInfo.event_id) {
|
||||
if (roomInfo.event_id && roomInfo.highlighted) {
|
||||
presentedId += "/" + roomInfo.event_id;
|
||||
}
|
||||
this.notifyNewScreen('room/' + presentedId);
|
||||
|
@ -656,7 +680,46 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
_setMxId: function(payload) {
|
||||
const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog');
|
||||
const close = Modal.createDialog(SetMxIdDialog, {
|
||||
homeserverUrl: MatrixClientPeg.get().getHomeserverUrl(),
|
||||
onFinished: (submitted, credentials) => {
|
||||
if (!submitted) {
|
||||
dis.dispatch({
|
||||
action: 'cancel_after_sync_prepared',
|
||||
});
|
||||
if (payload.go_home_on_cancel) {
|
||||
dis.dispatch({
|
||||
action: 'view_home_page',
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.onRegistered(credentials);
|
||||
},
|
||||
onDifferentServerClicked: (ev) => {
|
||||
dis.dispatch({action: 'start_registration'});
|
||||
close();
|
||||
},
|
||||
onLoginClick: (ev) => {
|
||||
dis.dispatch({action: 'start_login'});
|
||||
close();
|
||||
},
|
||||
}).close;
|
||||
},
|
||||
|
||||
_createChat: function() {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
deferred_action: {
|
||||
action: 'view_create_chat',
|
||||
},
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog");
|
||||
Modal.createDialog(ChatInviteDialog, {
|
||||
title: _t('Start a chat'),
|
||||
|
@ -666,6 +729,86 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
_createRoom: function() {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
deferred_action: {
|
||||
action: 'view_create_room',
|
||||
},
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog");
|
||||
Modal.createDialog(TextInputDialog, {
|
||||
title: _t('Create Room'),
|
||||
description: _t('Room name (optional)'),
|
||||
button: _t('Create Room'),
|
||||
onFinished: (should_create, name) => {
|
||||
if (should_create) {
|
||||
const createOpts = {};
|
||||
if (name) createOpts.name = name;
|
||||
createRoom({createOpts}).done();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
_chatCreateOrReuse: function(userId) {
|
||||
const ChatCreateOrReuseDialog = sdk.getComponent(
|
||||
'views.dialogs.ChatCreateOrReuseDialog',
|
||||
);
|
||||
// Use a deferred action to reshow the dialog once the user has registered
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
// No point in making 2 DMs with welcome bot. This assumes view_set_mxid will
|
||||
// result in a new DM with the welcome user.
|
||||
if (userId !== this.props.config.welcomeUserId) {
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
deferred_action: {
|
||||
action: 'view_start_chat_or_reuse',
|
||||
user_id: userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
dis.dispatch({
|
||||
action: 'view_set_mxid',
|
||||
// If the set_mxid dialog is cancelled, view /home because if the browser
|
||||
// was pointing at /user/@someone:domain?action=chat, the URL needs to be
|
||||
// reset so that they can revisit /user/.. // (and trigger
|
||||
// `_chatCreateOrReuse` again)
|
||||
go_home_on_cancel: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const close = Modal.createDialog(ChatCreateOrReuseDialog, {
|
||||
userId: userId,
|
||||
onFinished: (success) => {
|
||||
if (!success) {
|
||||
// Dialog cancelled, default to home
|
||||
dis.dispatch({ action: 'view_home_page' });
|
||||
}
|
||||
},
|
||||
onNewDMClick: () => {
|
||||
dis.dispatch({
|
||||
action: 'start_chat',
|
||||
user_id: userId,
|
||||
});
|
||||
// Close the dialog, indicate success (calls onFinished(true))
|
||||
close(true);
|
||||
},
|
||||
onExistingRoomSelected: (roomId) => {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
});
|
||||
close(true);
|
||||
},
|
||||
}).close;
|
||||
},
|
||||
|
||||
_invite: function(roomId) {
|
||||
const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog");
|
||||
Modal.createDialog(ChatInviteDialog, {
|
||||
|
@ -699,7 +842,7 @@ module.exports = React.createClass({
|
|||
|
||||
d.then(() => {
|
||||
modal.close();
|
||||
if (this.currentRoomId === roomId) {
|
||||
if (this.state.currentRoomId === roomId) {
|
||||
dis.dispatch({action: 'view_next_room'});
|
||||
}
|
||||
}, (err) => {
|
||||
|
@ -794,12 +937,27 @@ module.exports = React.createClass({
|
|||
this._teamToken = teamToken;
|
||||
dis.dispatch({action: 'view_home_page'});
|
||||
} else if (this._is_registered) {
|
||||
this._is_registered = false;
|
||||
// reset the 'have completed first sync' flag,
|
||||
// since we've just logged in and will be about to sync
|
||||
this.firstSyncComplete = false;
|
||||
this.firstSyncPromise = q.defer();
|
||||
|
||||
// Set the display name = user ID localpart
|
||||
MatrixClientPeg.get().setDisplayName(
|
||||
MatrixClientPeg.get().getUserIdLocalpart(),
|
||||
);
|
||||
|
||||
if (this.props.config.welcomeUserId && getCurrentLanguage().startsWith("en")) {
|
||||
createRoom({dmUserId: this.props.config.welcomeUserId});
|
||||
createRoom({
|
||||
dmUserId: this.props.config.welcomeUserId,
|
||||
// Only view the welcome user if we're NOT looking at a room
|
||||
andView: !this.state.currentRoomId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// The user has just logged in after registering
|
||||
dis.dispatch({action: 'view_room_directory'});
|
||||
dis.dispatch({action: 'view_home_page'});
|
||||
} else {
|
||||
this._showScreenAfterLogin();
|
||||
}
|
||||
|
@ -821,12 +979,8 @@ module.exports = React.createClass({
|
|||
action: 'view_room',
|
||||
room_id: localStorage.getItem('mx_last_room_id'),
|
||||
});
|
||||
} else if (this._teamToken) {
|
||||
// Team token might be set if we're a guest.
|
||||
// Guests do not call _onLoggedIn with a teamToken
|
||||
dis.dispatch({action: 'view_home_page'});
|
||||
} else {
|
||||
dis.dispatch({action: 'view_room_directory'});
|
||||
dis.dispatch({action: 'view_home_page'});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -840,7 +994,6 @@ module.exports = React.createClass({
|
|||
ready: false,
|
||||
collapse_lhs: false,
|
||||
collapse_rhs: false,
|
||||
currentRoomAlias: null,
|
||||
currentRoomId: null,
|
||||
page_type: PageTypes.RoomDirectory,
|
||||
});
|
||||
|
@ -878,6 +1031,12 @@ module.exports = React.createClass({
|
|||
});
|
||||
|
||||
cli.on('sync', function(state, prevState) {
|
||||
// LifecycleStore and others cannot directly subscribe to matrix client for
|
||||
// events because flux only allows store state changes during flux dispatches.
|
||||
// So dispatch directly from here. Ideally we'd use a SyncStateStore that
|
||||
// would do this dispatch and expose the sync state itself (by listening to
|
||||
// its own dispatch).
|
||||
dis.dispatch({action: 'sync_state', prevState, state});
|
||||
self.updateStatusIndicator(state, prevState);
|
||||
if (state === "SYNCING" && prevState === "SYNCING") {
|
||||
return;
|
||||
|
@ -947,6 +1106,11 @@ module.exports = React.createClass({
|
|||
dis.dispatch({
|
||||
action: 'view_home_page',
|
||||
});
|
||||
} else if (screen == 'start') {
|
||||
this.showScreen('home');
|
||||
dis.dispatch({
|
||||
action: 'view_set_mxid',
|
||||
});
|
||||
} else if (screen == 'directory') {
|
||||
dis.dispatch({
|
||||
action: 'view_room_directory',
|
||||
|
@ -974,6 +1138,10 @@ module.exports = React.createClass({
|
|||
const payload = {
|
||||
action: 'view_room',
|
||||
event_id: eventId,
|
||||
// If an event ID is given in the URL hash, notify RoomViewStore to mark
|
||||
// it as highlighted, which will propagate to RoomView and highlight the
|
||||
// associated EventTile.
|
||||
highlighted: Boolean(eventId),
|
||||
third_party_invite: thirdPartyInvite,
|
||||
oob_data: oobData,
|
||||
};
|
||||
|
@ -990,6 +1158,12 @@ module.exports = React.createClass({
|
|||
}
|
||||
} else if (screen.indexOf('user/') == 0) {
|
||||
const userId = screen.substring(5);
|
||||
|
||||
if (params.action === 'chat') {
|
||||
this._chatCreateOrReuse(userId);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ viewUserId: userId });
|
||||
this._setPage(PageTypes.UserView);
|
||||
this.notifyNewScreen('user/' + userId);
|
||||
|
@ -1086,6 +1260,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onRegistered: function(credentials, teamToken) {
|
||||
// XXX: These both should be in state or ideally store(s) because we risk not
|
||||
// rendering the most up-to-date view of state otherwise.
|
||||
// teamToken may not be truthy
|
||||
this._teamToken = teamToken;
|
||||
this._is_registered = true;
|
||||
|
@ -1129,7 +1305,15 @@ module.exports = React.createClass({
|
|||
PlatformPeg.get().setNotificationCount(notifCount);
|
||||
}
|
||||
|
||||
document.title = `Riot ${state === "ERROR" ? " [offline]" : ""}${notifCount > 0 ? ` [${notifCount}]` : ""}`;
|
||||
let title = "Riot ";
|
||||
if (state === "ERROR") {
|
||||
title += `[${_t("Offline")}] `;
|
||||
}
|
||||
if (notifCount > 0) {
|
||||
title += `[${notifCount}]`;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
},
|
||||
|
||||
onUserSettingsClose: function() {
|
||||
|
@ -1142,18 +1326,11 @@ module.exports = React.createClass({
|
|||
});
|
||||
} else {
|
||||
dis.dispatch({
|
||||
action: 'view_room_directory',
|
||||
action: 'view_home_page',
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onRoomIdResolved: function(roomId) {
|
||||
// It's the RoomView's resposibility to look up room aliases, but we need the
|
||||
// ID to pass into things like the Member List, so the Room View tells us when
|
||||
// its done that resolution so we can display things that take a room ID.
|
||||
this.setState({currentRoomId: roomId});
|
||||
},
|
||||
|
||||
_makeRegistrationUrl: function(params) {
|
||||
if (this.props.startingFragmentQueryParams.referrer) {
|
||||
params.referrer = this.props.startingFragmentQueryParams.referrer;
|
||||
|
@ -1195,9 +1372,10 @@ module.exports = React.createClass({
|
|||
const LoggedInView = sdk.getComponent('structures.LoggedInView');
|
||||
return (
|
||||
<LoggedInView ref="loggedInView" matrixClient={MatrixClientPeg.get()}
|
||||
onRoomIdResolved={this.onRoomIdResolved}
|
||||
onRoomCreated={this.onRoomCreated}
|
||||
onUserSettingsClose={this.onUserSettingsClose}
|
||||
onRegistered={this.onRegistered}
|
||||
currentRoomId={this.state.currentRoomId}
|
||||
teamToken={this._teamToken}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
|
|
|
@ -15,9 +15,8 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { _t } from '../../languageHandler';
|
||||
import { _t, _tJsx } from '../../languageHandler';
|
||||
import sdk from '../../index';
|
||||
import dis from '../../dispatcher';
|
||||
import WhoIsTyping from '../../WhoIsTyping';
|
||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||
import MemberAvatar from '../views/avatars/MemberAvatar';
|
||||
|
@ -282,14 +281,13 @@ module.exports = React.createClass({
|
|||
{ this.props.unsentMessageError }
|
||||
</div>
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_desc">
|
||||
<a className="mx_RoomStatusBar_resend_link"
|
||||
onClick={ this.props.onResendAllClick }>
|
||||
{_t('Resend all')}
|
||||
</a> {_t('or')} <a
|
||||
className="mx_RoomStatusBar_resend_link"
|
||||
onClick={ this.props.onCancelAllClick }>
|
||||
{_t('cancel all')}
|
||||
</a> {_t('now. You can also select individual messages to resend or cancel.')}
|
||||
{_tJsx("<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.",
|
||||
[/<a>(.*?)<\/a>/, /<a>(.*?)<\/a>/],
|
||||
[
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={ this.props.onResendAllClick }>{sub}</a>,
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="cancel" onClick={ this.props.onCancelAllClick }>{sub}</a>,
|
||||
]
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -298,8 +296,8 @@ module.exports = React.createClass({
|
|||
// unread count trumps who is typing since the unread count is only
|
||||
// set when you've scrolled up
|
||||
if (this.props.numUnreadMessages) {
|
||||
var unreadMsgs = this.props.numUnreadMessages + " new message" +
|
||||
(this.props.numUnreadMessages > 1 ? "s" : "");
|
||||
// MUST use var name "count" for pluralization to kick in
|
||||
var unreadMsgs = _t("%(count)s new messages", {count: this.props.numUnreadMessages});
|
||||
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_unreadMessagesBar"
|
||||
|
|
|
@ -45,7 +45,9 @@ import KeyCode from '../../KeyCode';
|
|||
|
||||
import UserProvider from '../../autocomplete/UserProvider';
|
||||
|
||||
const DEBUG = false;
|
||||
import RoomViewStore from '../../stores/RoomViewStore';
|
||||
|
||||
var DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
// using bind means that we get to keep useful line numbers in the console
|
||||
|
@ -59,16 +61,9 @@ module.exports = React.createClass({
|
|||
propTypes: {
|
||||
ConferenceHandler: React.PropTypes.any,
|
||||
|
||||
// Either a room ID or room alias for the room to display.
|
||||
// If the room is being displayed as a result of the user clicking
|
||||
// on a room alias, the alias should be supplied. Otherwise, a room
|
||||
// ID should be supplied.
|
||||
roomAddress: React.PropTypes.string.isRequired,
|
||||
|
||||
// If a room alias is passed to roomAddress, a function can be
|
||||
// provided here that will be called with the ID of the room
|
||||
// once it has been resolved.
|
||||
onRoomIdResolved: React.PropTypes.func,
|
||||
// Called with the credentials of a registered user (if they were a ROU that
|
||||
// transitioned to PWLU)
|
||||
onRegistered: React.PropTypes.func,
|
||||
|
||||
// An object representing a third party invite to join this room
|
||||
// Fields:
|
||||
|
@ -88,36 +83,8 @@ module.exports = React.createClass({
|
|||
// * invited us tovthe room
|
||||
oobData: React.PropTypes.object,
|
||||
|
||||
// id of an event to jump to. If not given, will go to the end of the
|
||||
// live timeline.
|
||||
eventId: React.PropTypes.string,
|
||||
|
||||
// where to position the event given by eventId, in pixels from the
|
||||
// bottom of the viewport. If not given, will try to put the event
|
||||
// 1/3 of the way down the viewport.
|
||||
eventPixelOffset: React.PropTypes.number,
|
||||
|
||||
// ID of an event to highlight. If undefined, no event will be highlighted.
|
||||
// Typically this will either be the same as 'eventId', or undefined.
|
||||
highlightedEventId: React.PropTypes.string,
|
||||
|
||||
// is the RightPanel collapsed?
|
||||
collapsedRhs: React.PropTypes.bool,
|
||||
|
||||
// a map from room id to scroll state, which will be updated on unmount.
|
||||
//
|
||||
// If there is no special scroll state (ie, we are following the live
|
||||
// timeline), the scroll state is null. Otherwise, it is an object with
|
||||
// the following properties:
|
||||
//
|
||||
// focussedEvent: the ID of the 'focussed' event. Typically this is
|
||||
// the last event fully visible in the viewport, though if we
|
||||
// have done an explicit scroll to an explicit event, it will be
|
||||
// that event.
|
||||
//
|
||||
// pixelOffset: the number of pixels the window is scrolled down
|
||||
// from the focussedEvent.
|
||||
scrollStateMap: React.PropTypes.object,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -126,6 +93,14 @@ module.exports = React.createClass({
|
|||
roomId: null,
|
||||
userId: null,
|
||||
roomLoading: true,
|
||||
peekLoading: false,
|
||||
|
||||
// The event to be scrolled to initially
|
||||
initialEventId: null,
|
||||
// The offset in pixels from the event with which to scroll vertically
|
||||
initialEventPixelOffset: null,
|
||||
// Whether to highlight the event scrolled to
|
||||
isInitialEventHighlighted: null,
|
||||
|
||||
forwardingEvent: null,
|
||||
editingRoomSettings: false,
|
||||
|
@ -177,39 +152,44 @@ module.exports = React.createClass({
|
|||
},
|
||||
});
|
||||
|
||||
if (this.props.roomAddress[0] == '#') {
|
||||
// we always look up the alias from the directory server:
|
||||
// we want the room that the given alias is pointing to
|
||||
// right now. We may have joined that alias before but there's
|
||||
// no guarantee the alias hasn't subsequently been remapped.
|
||||
MatrixClientPeg.get().getRoomIdForAlias(this.props.roomAddress).done((result) => {
|
||||
if (this.props.onRoomIdResolved) {
|
||||
this.props.onRoomIdResolved(result.room_id);
|
||||
}
|
||||
var room = MatrixClientPeg.get().getRoom(result.room_id);
|
||||
this.setState({
|
||||
room: room,
|
||||
roomId: result.room_id,
|
||||
userId: MatrixClientPeg.get().credentials.userId,
|
||||
roomLoading: !room,
|
||||
unsentMessageError: this._getUnsentMessageError(room),
|
||||
}, this._onHaveRoom);
|
||||
}, (err) => {
|
||||
this.setState({
|
||||
roomLoading: false,
|
||||
roomLoadError: err,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
var room = MatrixClientPeg.get().getRoom(this.props.roomAddress);
|
||||
this.setState({
|
||||
roomId: this.props.roomAddress,
|
||||
userId: MatrixClientPeg.get().credentials.userId,
|
||||
room: room,
|
||||
roomLoading: !room,
|
||||
unsentMessageError: this._getUnsentMessageError(room),
|
||||
}, this._onHaveRoom);
|
||||
// Start listening for RoomViewStore updates
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._onRoomViewStoreUpdate(true);
|
||||
},
|
||||
|
||||
_onRoomViewStoreUpdate: function(initial) {
|
||||
if (this.unmounted) {
|
||||
return;
|
||||
}
|
||||
const newState = {
|
||||
roomId: RoomViewStore.getRoomId(),
|
||||
roomAlias: RoomViewStore.getRoomAlias(),
|
||||
roomLoading: RoomViewStore.isRoomLoading(),
|
||||
roomLoadError: RoomViewStore.getRoomLoadError(),
|
||||
joining: RoomViewStore.isJoining(),
|
||||
initialEventId: RoomViewStore.getInitialEventId(),
|
||||
initialEventPixelOffset: RoomViewStore.getInitialEventPixelOffset(),
|
||||
isInitialEventHighlighted: RoomViewStore.isInitialEventHighlighted(),
|
||||
};
|
||||
|
||||
// Clear the search results when clicking a search result (which changes the
|
||||
// currently scrolled to event, this.state.initialEventId).
|
||||
if (this.state.initialEventId !== newState.initialEventId) {
|
||||
newState.searchResults = null;
|
||||
}
|
||||
|
||||
// Store the scroll state for the previous room so that we can return to this
|
||||
// position when viewing this room in future.
|
||||
if (this.state.roomId !== newState.roomId) {
|
||||
this._updateScrollMap(this.state.roomId);
|
||||
}
|
||||
|
||||
this.setState(newState, () => {
|
||||
// At this point, this.state.roomId could be null (e.g. the alias might not
|
||||
// have been resolved yet) so anything called here must handle this case.
|
||||
this._onHaveRoom();
|
||||
this.onRoom(MatrixClientPeg.get().getRoom(this.state.roomId));
|
||||
});
|
||||
},
|
||||
|
||||
_onHaveRoom: function() {
|
||||
|
@ -227,26 +207,29 @@ module.exports = React.createClass({
|
|||
// NB. We peek if we are not in the room, although if we try to peek into
|
||||
// a room in which we have a member event (ie. we've left) synapse will just
|
||||
// send us the same data as we get in the sync (ie. the last events we saw).
|
||||
var user_is_in_room = null;
|
||||
if (this.state.room) {
|
||||
user_is_in_room = this.state.room.hasMembershipState(
|
||||
MatrixClientPeg.get().credentials.userId, 'join'
|
||||
const room = MatrixClientPeg.get().getRoom(this.state.roomId);
|
||||
let isUserJoined = null;
|
||||
if (room) {
|
||||
isUserJoined = room.hasMembershipState(
|
||||
MatrixClientPeg.get().credentials.userId, 'join',
|
||||
);
|
||||
|
||||
this._updateAutoComplete();
|
||||
this.tabComplete.loadEntries(this.state.room);
|
||||
this._updateAutoComplete(room);
|
||||
this.tabComplete.loadEntries(room);
|
||||
}
|
||||
|
||||
if (!user_is_in_room && this.state.roomId) {
|
||||
if (!isUserJoined && !this.state.joining && this.state.roomId) {
|
||||
if (this.props.autoJoin) {
|
||||
this.onJoinButtonClicked();
|
||||
} else if (this.state.roomId) {
|
||||
console.log("Attempting to peek into room %s", this.state.roomId);
|
||||
|
||||
this.setState({
|
||||
peekLoading: true,
|
||||
});
|
||||
MatrixClientPeg.get().peekInRoom(this.state.roomId).then((room) => {
|
||||
this.setState({
|
||||
room: room,
|
||||
roomLoading: false,
|
||||
peekLoading: false,
|
||||
});
|
||||
this._onRoomLoaded(room);
|
||||
}, (err) => {
|
||||
|
@ -256,16 +239,19 @@ module.exports = React.createClass({
|
|||
if (err.errcode == "M_GUEST_ACCESS_FORBIDDEN") {
|
||||
// This is fine: the room just isn't peekable (we assume).
|
||||
this.setState({
|
||||
roomLoading: false,
|
||||
peekLoading: false,
|
||||
});
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}).done();
|
||||
}
|
||||
} else if (user_is_in_room) {
|
||||
} else if (isUserJoined) {
|
||||
MatrixClientPeg.get().stopPeeking();
|
||||
this._onRoomLoaded(this.state.room);
|
||||
this.setState({
|
||||
unsentMessageError: this._getUnsentMessageError(room),
|
||||
});
|
||||
this._onRoomLoaded(room);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -301,17 +287,6 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
if (newProps.roomAddress != this.props.roomAddress) {
|
||||
throw new Error(_t("changing room on a RoomView is not supported"));
|
||||
}
|
||||
|
||||
if (newProps.eventId != this.props.eventId) {
|
||||
// when we change focussed event id, hide the search results.
|
||||
this.setState({searchResults: null});
|
||||
}
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
return (!ObjectUtils.shallowEqual(this.props, nextProps) ||
|
||||
!ObjectUtils.shallowEqual(this.state, nextState));
|
||||
|
@ -337,7 +312,7 @@ module.exports = React.createClass({
|
|||
this.unmounted = true;
|
||||
|
||||
// update the scroll map before we get unmounted
|
||||
this._updateScrollMap();
|
||||
this._updateScrollMap(this.state.roomId);
|
||||
|
||||
if (this.refs.roomView) {
|
||||
// disconnect the D&D event listeners from the room view. This
|
||||
|
@ -366,6 +341,11 @@ module.exports = React.createClass({
|
|||
|
||||
document.removeEventListener("keydown", this.onKeyDown);
|
||||
|
||||
// Remove RoomStore listener
|
||||
if (this._roomStoreToken) {
|
||||
this._roomStoreToken.remove();
|
||||
}
|
||||
|
||||
// cancel any pending calls to the rate_limited_funcs
|
||||
this._updateRoomMembers.cancelPendingCall();
|
||||
|
||||
|
@ -536,7 +516,7 @@ module.exports = React.createClass({
|
|||
this._updatePreviewUrlVisibility(room);
|
||||
},
|
||||
|
||||
_warnAboutEncryption: function (room) {
|
||||
_warnAboutEncryption: function(room) {
|
||||
if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) {
|
||||
return;
|
||||
}
|
||||
|
@ -616,21 +596,27 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
onRoom: function(room) {
|
||||
// This event is fired when the room is 'stored' by the JS SDK, which
|
||||
// means it's now a fully-fledged room object ready to be used, so
|
||||
// set it in our state and start using it (ie. init the timeline)
|
||||
// This will happen if we start off viewing a room we're not joined,
|
||||
// then join it whilst RoomView is looking at that room.
|
||||
if (!this.state.room && room.roomId == this._joiningRoomId) {
|
||||
this._joiningRoomId = undefined;
|
||||
this.setState({
|
||||
room: room,
|
||||
joining: false,
|
||||
});
|
||||
|
||||
this._onRoomLoaded(room);
|
||||
_updateScrollMap(roomId) {
|
||||
// No point updating scroll state if the room ID hasn't been resolved yet
|
||||
if (!roomId) {
|
||||
return;
|
||||
}
|
||||
dis.dispatch({
|
||||
action: 'update_scroll_state',
|
||||
room_id: roomId,
|
||||
scroll_state: this._getScrollState(),
|
||||
});
|
||||
},
|
||||
|
||||
onRoom: function(room) {
|
||||
if (!room || room.roomId !== this.state.roomId) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
room: room,
|
||||
}, () => {
|
||||
this._onRoomLoaded(room);
|
||||
});
|
||||
},
|
||||
|
||||
updateTint: function() {
|
||||
|
@ -696,7 +682,7 @@ module.exports = React.createClass({
|
|||
|
||||
// refresh the tab complete list
|
||||
this.tabComplete.loadEntries(this.state.room);
|
||||
this._updateAutoComplete();
|
||||
this._updateAutoComplete(this.state.room);
|
||||
|
||||
// if we are now a member of the room, where we were not before, that
|
||||
// means we have finished joining a room we were previously peeking
|
||||
|
@ -713,10 +699,6 @@ module.exports = React.createClass({
|
|||
// compatability workaround, let's not bother.
|
||||
Rooms.setDMRoom(this.state.room.roomId, me.events.member.getSender()).done();
|
||||
}
|
||||
|
||||
this.setState({
|
||||
joining: false
|
||||
});
|
||||
}
|
||||
}, 500),
|
||||
|
||||
|
@ -725,7 +707,7 @@ module.exports = React.createClass({
|
|||
if (!unsentMessages.length) return "";
|
||||
for (const event of unsentMessages) {
|
||||
if (!event.error || event.error.name !== "UnknownDeviceError") {
|
||||
return _t("Some of your messages have not been sent") + ".";
|
||||
return _t("Some of your messages have not been sent.");
|
||||
}
|
||||
}
|
||||
return _t("Message not sent due to unknown devices being present");
|
||||
|
@ -791,41 +773,62 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onJoinButtonClicked: function(ev) {
|
||||
var self = this;
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
var cli = MatrixClientPeg.get();
|
||||
var display_name_promise = q();
|
||||
// if this is the first room we're joining, check the user has a display name
|
||||
// and if they don't, prompt them to set one.
|
||||
// NB. This unfortunately does not re-use the ChangeDisplayName component because
|
||||
// it doesn't behave quite as desired here (we want an input field here rather than
|
||||
// content-editable, and we want a default).
|
||||
if (cli.getRooms().filter((r) => {
|
||||
return r.hasMembershipState(cli.credentials.userId, "join");
|
||||
})) {
|
||||
display_name_promise = cli.getProfileInfo(cli.credentials.userId).then((result) => {
|
||||
if (!result.displayname) {
|
||||
var SetDisplayNameDialog = sdk.getComponent('views.dialogs.SetDisplayNameDialog');
|
||||
var dialog_defer = q.defer();
|
||||
Modal.createDialog(SetDisplayNameDialog, {
|
||||
currentDisplayName: result.displayname,
|
||||
onFinished: (submitted, newDisplayName) => {
|
||||
if (submitted) {
|
||||
cli.setDisplayName(newDisplayName).done(() => {
|
||||
dialog_defer.resolve();
|
||||
});
|
||||
}
|
||||
else {
|
||||
dialog_defer.reject();
|
||||
}
|
||||
}
|
||||
});
|
||||
return dialog_defer.promise;
|
||||
}
|
||||
// If the user is a ROU, allow them to transition to a PWLU
|
||||
if (cli && cli.isGuest()) {
|
||||
// Join this room once the user has registered and logged in
|
||||
const signUrl = this.props.thirdPartyInvite ?
|
||||
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
deferred_action: {
|
||||
action: 'join_room',
|
||||
opts: { inviteSignUrl: signUrl },
|
||||
},
|
||||
});
|
||||
|
||||
// Don't peek whilst registering otherwise getPendingEventList complains
|
||||
// Do this by indicating our intention to join
|
||||
dis.dispatch({
|
||||
action: 'will_join',
|
||||
});
|
||||
|
||||
const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog');
|
||||
const close = Modal.createDialog(SetMxIdDialog, {
|
||||
homeserverUrl: cli.getHomeserverUrl(),
|
||||
onFinished: (submitted, credentials) => {
|
||||
if (submitted) {
|
||||
this.props.onRegistered(credentials);
|
||||
} else {
|
||||
dis.dispatch({
|
||||
action: 'cancel_after_sync_prepared',
|
||||
});
|
||||
dis.dispatch({
|
||||
action: 'cancel_join',
|
||||
});
|
||||
}
|
||||
},
|
||||
onDifferentServerClicked: (ev) => {
|
||||
dis.dispatch({action: 'start_registration'});
|
||||
close();
|
||||
},
|
||||
onLoginClick: (ev) => {
|
||||
dis.dispatch({action: 'start_login'});
|
||||
close();
|
||||
},
|
||||
}).close;
|
||||
return;
|
||||
}
|
||||
|
||||
display_name_promise.then(() => {
|
||||
q().then(() => {
|
||||
const signUrl = this.props.thirdPartyInvite ?
|
||||
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||
dis.dispatch({
|
||||
action: 'join_room',
|
||||
opts: { inviteSignUrl: signUrl },
|
||||
});
|
||||
|
||||
// if this is an invite and has the 'direct' hint set, mark it as a DM room now.
|
||||
if (this.state.room) {
|
||||
const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||
|
@ -837,72 +840,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return q();
|
||||
}).then(() => {
|
||||
var sign_url = this.props.thirdPartyInvite ? this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||
return MatrixClientPeg.get().joinRoom(this.props.roomAddress,
|
||||
{ inviteSignUrl: sign_url } );
|
||||
}).then(function(resp) {
|
||||
var roomId = resp.roomId;
|
||||
|
||||
// It is possible that there is no Room yet if state hasn't come down
|
||||
// from /sync - joinRoom will resolve when the HTTP request to join succeeds,
|
||||
// NOT when it comes down /sync. If there is no room, we'll keep the
|
||||
// joining flag set until we see it.
|
||||
|
||||
// We'll need to initialise the timeline when joining, but due to
|
||||
// the above, we can't do it here: we do it in onRoom instead,
|
||||
// once we have a useable room object.
|
||||
var room = MatrixClientPeg.get().getRoom(roomId);
|
||||
if (!room) {
|
||||
// wait for the room to turn up in onRoom.
|
||||
self._joiningRoomId = roomId;
|
||||
} else {
|
||||
// we've got a valid room, but that might also just mean that
|
||||
// it was peekable (so we had one before anyway). If we are
|
||||
// not yet a member of the room, we will need to wait for that
|
||||
// to happen, in onRoomStateMember.
|
||||
var me = MatrixClientPeg.get().credentials.userId;
|
||||
self.setState({
|
||||
joining: !room.hasMembershipState(me, "join"),
|
||||
room: room
|
||||
});
|
||||
}
|
||||
}).catch(function(error) {
|
||||
self.setState({
|
||||
joining: false,
|
||||
joinError: error
|
||||
});
|
||||
|
||||
if (!error) return;
|
||||
|
||||
// https://matrix.org/jira/browse/SYN-659
|
||||
// Need specific error message if joining a room is refused because the user is a guest and guest access is not allowed
|
||||
if (
|
||||
error.errcode == 'M_GUEST_ACCESS_FORBIDDEN' ||
|
||||
(
|
||||
error.errcode == 'M_FORBIDDEN' &&
|
||||
MatrixClientPeg.get().isGuest()
|
||||
)
|
||||
) {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Failed to join the room"),
|
||||
description: _t("This room is private or inaccessible to guests. You may be able to join if you register") + "."
|
||||
});
|
||||
} else {
|
||||
var msg = error.message ? error.message : JSON.stringify(error);
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Failed to join room"),
|
||||
description: msg,
|
||||
});
|
||||
}
|
||||
}).done();
|
||||
|
||||
this.setState({
|
||||
joining: true
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -954,11 +892,7 @@ module.exports = React.createClass({
|
|||
|
||||
uploadFile: function(file) {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Please Register"),
|
||||
description: _t("Guest users can't upload files. Please register to upload") + "."
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1316,21 +1250,6 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
// update scrollStateMap on unmount
|
||||
_updateScrollMap: function() {
|
||||
if (!this.state.room) {
|
||||
// we were instantiated on a room alias and haven't yet joined the room.
|
||||
return;
|
||||
}
|
||||
if (!this.props.scrollStateMap) return;
|
||||
|
||||
var roomId = this.state.room.roomId;
|
||||
|
||||
var state = this._getScrollState();
|
||||
this.props.scrollStateMap[roomId] = state;
|
||||
},
|
||||
|
||||
|
||||
// get the current scroll position of the room, so that it can be
|
||||
// restored when we switch back to it.
|
||||
//
|
||||
|
@ -1483,9 +1402,9 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_updateAutoComplete: function() {
|
||||
_updateAutoComplete: function(room) {
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const members = this.state.room.getJoinedMembers().filter(function(member) {
|
||||
const members = room.getJoinedMembers().filter(function(member) {
|
||||
if (member.userId !== myUserId) return true;
|
||||
});
|
||||
UserProvider.getInstance().setUserList(members);
|
||||
|
@ -1505,7 +1424,7 @@ module.exports = React.createClass({
|
|||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
|
||||
if (!this.state.room) {
|
||||
if (this.state.roomLoading) {
|
||||
if (this.state.roomLoading || this.state.peekLoading) {
|
||||
return (
|
||||
<div className="mx_RoomView">
|
||||
<Loader />
|
||||
|
@ -1523,7 +1442,7 @@ module.exports = React.createClass({
|
|||
|
||||
// We have no room object for this room, only the ID.
|
||||
// We've got to this room by following a link, possibly a third party invite.
|
||||
var room_alias = this.props.roomAddress[0] == '#' ? this.props.roomAddress : null;
|
||||
var room_alias = this.state.room_alias;
|
||||
return (
|
||||
<div className="mx_RoomView">
|
||||
<RoomHeader ref="header"
|
||||
|
@ -1761,6 +1680,14 @@ module.exports = React.createClass({
|
|||
hideMessagePanel = true;
|
||||
}
|
||||
|
||||
const shouldHighlight = this.state.isInitialEventHighlighted;
|
||||
let highlightedEventId = null;
|
||||
if (this.state.forwardingEvent) {
|
||||
highlightedEventId = this.state.forwardingEvent.getId();
|
||||
} else if (shouldHighlight) {
|
||||
highlightedEventId = this.state.initialEventId;
|
||||
}
|
||||
|
||||
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
||||
var messagePanel = (
|
||||
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
||||
|
@ -1768,9 +1695,9 @@ module.exports = React.createClass({
|
|||
manageReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||
manageReadMarkers={true}
|
||||
hidden={hideMessagePanel}
|
||||
highlightedEventId={this.state.forwardingEvent ? this.state.forwardingEvent.getId() : this.props.highlightedEventId}
|
||||
eventId={this.props.eventId}
|
||||
eventPixelOffset={this.props.eventPixelOffset}
|
||||
highlightedEventId={highlightedEventId}
|
||||
eventId={this.state.initialEventId}
|
||||
eventPixelOffset={this.state.initialEventPixelOffset}
|
||||
onScroll={ this.onMessageListScroll }
|
||||
onReadMarkerUpdated={ this._updateTopUnreadMessagesBar }
|
||||
showUrlPreview = { this.state.showUrlPreview }
|
||||
|
|
|
@ -902,6 +902,9 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
var onError = (error) => {
|
||||
this.setState({timelineLoading: false});
|
||||
console.error(
|
||||
`Error loading timeline panel at ${eventId}: ${error}`,
|
||||
);
|
||||
var msg = error.message ? error.message : JSON.stringify(error);
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
|
||||
|
@ -921,8 +924,8 @@ var TimelinePanel = React.createClass({
|
|||
};
|
||||
}
|
||||
var message = (error.errcode == 'M_FORBIDDEN')
|
||||
? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question") + "."
|
||||
: _t("Tried to load a specific point in this room's timeline, but was unable to find it") + ".";
|
||||
? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.")
|
||||
: _t("Tried to load a specific point in this room's timeline, but was unable to find it.");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Failed to load timeline position"),
|
||||
description: message,
|
||||
|
|
|
@ -18,6 +18,7 @@ var React = require('react');
|
|||
var ContentMessages = require('../../ContentMessages');
|
||||
var dis = require('../../dispatcher');
|
||||
var filesize = require('filesize');
|
||||
import { _t } from '../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({displayName: 'UploadBar',
|
||||
propTypes: {
|
||||
|
@ -81,10 +82,8 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
|||
uploadedSize = uploadedSize.replace(/ .*/, '');
|
||||
}
|
||||
|
||||
var others;
|
||||
if (uploads.length > 1) {
|
||||
others = ' and ' + (uploads.length - 1) + ' other' + (uploads.length > 2 ? 's' : '');
|
||||
}
|
||||
// MUST use var name 'count' for pluralization to kick in
|
||||
var uploadText = _t("Uploading %(filename)s and %(count)s others", {filename: upload.fileName, count: (uploads.length - 1)});
|
||||
|
||||
return (
|
||||
<div className="mx_UploadBar">
|
||||
|
@ -98,7 +97,7 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
|||
<div className="mx_UploadBar_uploadBytes">
|
||||
{ uploadedSize } / { totalSize }
|
||||
</div>
|
||||
<div className="mx_UploadBar_uploadFilename">Uploading {upload.fileName}{others}</div>
|
||||
<div className="mx_UploadBar_uploadFilename">{uploadText}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -88,6 +88,10 @@ const SETTINGS_LABELS = [
|
|||
id: 'hideRedactions',
|
||||
label: 'Hide removed messages',
|
||||
},
|
||||
{
|
||||
id: 'disableMarkdown',
|
||||
label: 'Disable markdown formatting',
|
||||
},
|
||||
/*
|
||||
{
|
||||
id: 'useFixedWidthFont',
|
||||
|
@ -307,11 +311,7 @@ module.exports = React.createClass({
|
|||
|
||||
onAvatarPickerClick: function(ev) {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Please Register"),
|
||||
description: _t("Guests can't set avatars. Please register."),
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -391,6 +391,7 @@ module.exports = React.createClass({
|
|||
title: _t("Success"),
|
||||
description: _t("Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them") + ".",
|
||||
});
|
||||
dis.dispatch({action: 'password_changed'});
|
||||
},
|
||||
|
||||
onUpgradeClicked: function() {
|
||||
|
@ -753,7 +754,7 @@ module.exports = React.createClass({
|
|||
const DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
||||
return (
|
||||
<div>
|
||||
<h3>Devices</h3>
|
||||
<h3>{_t("Devices")}</h3>
|
||||
<DevicesPanel className="mx_UserSettings_section"/>
|
||||
</div>
|
||||
);
|
||||
|
@ -803,11 +804,7 @@ module.exports = React.createClass({
|
|||
onChange={(e) => {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
e.target.checked = false;
|
||||
const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Please Register"),
|
||||
description: _t("Guests can't use labs features. Please register."),
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1098,7 +1095,7 @@ module.exports = React.createClass({
|
|||
onValueChanged={ this._onAddEmailEditFinished } />
|
||||
</div>
|
||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||
<img src="img/plus.svg" width="14" height="14" alt="Add" onClick={this._addEmail} />
|
||||
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,6 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
import ReactDOM from 'react-dom';
|
||||
import sdk from '../../../index';
|
||||
import Login from '../../../Login';
|
||||
|
||||
|
@ -88,7 +87,27 @@ module.exports = React.createClass({
|
|||
).then((data) => {
|
||||
this.props.onLoggedIn(data);
|
||||
}, (error) => {
|
||||
this._setStateFromError(error, true);
|
||||
let errorText;
|
||||
|
||||
// Some error strings only apply for logging in
|
||||
const usingEmail = username.indexOf("@") > 0;
|
||||
if (error.httpStatus == 400 && usingEmail) {
|
||||
errorText = _t('This Home Server does not support login using email address.');
|
||||
} else if (error.httpStatus === 401 || error.httpStatus === 403) {
|
||||
errorText = _t('Incorrect username and/or password.');
|
||||
} else {
|
||||
// other errors, not specific to doing a password login
|
||||
errorText = this._errorTextFromError(error);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
errorText: errorText,
|
||||
// 401 would be the sensible status code for 'incorrect password'
|
||||
// but the login API gives a 403 https://matrix.org/jira/browse/SYN-744
|
||||
// mentions this (although the bug is for UI auth which is not this)
|
||||
// We treat both as an incorrect password
|
||||
loginIncorrect: error.httpStatus === 401 || error.httpStatus == 403,
|
||||
});
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
busy: false
|
||||
|
@ -111,7 +130,16 @@ module.exports = React.createClass({
|
|||
this._loginLogic.loginAsGuest().then(function(data) {
|
||||
self.props.onLoggedIn(data);
|
||||
}, function(error) {
|
||||
self._setStateFromError(error, true);
|
||||
let errorText;
|
||||
if (error.httpStatus === 403) {
|
||||
errorText = _t("Guest access is disabled on this Home Server.");
|
||||
} else {
|
||||
errorText = self._errorTextFromError(error);
|
||||
}
|
||||
self.setState({
|
||||
errorText: errorText,
|
||||
loginIncorrect: false,
|
||||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
busy: false
|
||||
|
@ -130,7 +158,7 @@ module.exports = React.createClass({
|
|||
onPhoneNumberChanged: function(phoneNumber) {
|
||||
// Validate the phone number entered
|
||||
if (!PHONE_NUMBER_REGEX.test(phoneNumber)) {
|
||||
this.setState({ errorText: 'The phone number entered looks invalid' });
|
||||
this.setState({ errorText: _t('The phone number entered looks invalid') });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -184,44 +212,35 @@ module.exports = React.createClass({
|
|||
currentFlow: self._getCurrentFlowStep(),
|
||||
});
|
||||
}, function(err) {
|
||||
self._setStateFromError(err, false);
|
||||
self.setState({
|
||||
errorText: self._errorTextFromError(err),
|
||||
loginIncorrect: false,
|
||||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
busy: false,
|
||||
});
|
||||
});
|
||||
}).done();
|
||||
},
|
||||
|
||||
_getCurrentFlowStep: function() {
|
||||
return this._loginLogic ? this._loginLogic.getCurrentFlowStep() : null;
|
||||
},
|
||||
|
||||
_setStateFromError: function(err, isLoginAttempt) {
|
||||
this.setState({
|
||||
errorText: this._errorTextFromError(err),
|
||||
// https://matrix.org/jira/browse/SYN-744
|
||||
loginIncorrect: isLoginAttempt && (err.httpStatus == 401 || err.httpStatus == 403)
|
||||
});
|
||||
},
|
||||
|
||||
_errorTextFromError(err) {
|
||||
if (err.friendlyText) {
|
||||
return err.friendlyText;
|
||||
}
|
||||
|
||||
let errCode = err.errcode;
|
||||
if (!errCode && err.httpStatus) {
|
||||
errCode = "HTTP " + err.httpStatus;
|
||||
}
|
||||
|
||||
let errorText = "Error: Problem communicating with the given homeserver " +
|
||||
(errCode ? "(" + errCode + ")" : "");
|
||||
let errorText = _t("Error: Problem communicating with the given homeserver.") +
|
||||
(errCode ? " (" + errCode + ")" : "");
|
||||
|
||||
if (err.cors === 'rejected') {
|
||||
if (window.location.protocol === 'https:' &&
|
||||
(this.state.enteredHomeserverUrl.startsWith("http:") ||
|
||||
!this.state.enteredHomeserverUrl.startsWith("http")))
|
||||
{
|
||||
!this.state.enteredHomeserverUrl.startsWith("http"))
|
||||
) {
|
||||
errorText = <span>
|
||||
{ _tJsx("Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " +
|
||||
"Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||
|
@ -229,10 +248,9 @@ module.exports = React.createClass({
|
|||
(sub) => { return <a href="https://www.google.com/search?&q=enable%20unsafe%20scripts">{ sub }</a>; }
|
||||
)}
|
||||
</span>;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
errorText = <span>
|
||||
{ _tJsx("Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.",
|
||||
{ _tJsx("Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return <a href={this.state.enteredHomeserverUrl}>{ sub }</a>; }
|
||||
)}
|
||||
|
|
|
@ -50,7 +50,7 @@ module.exports = React.createClass({
|
|||
});
|
||||
}, function(error) {
|
||||
self.setState({
|
||||
errorString: "Failed to fetch avatar URL",
|
||||
errorString: _t("Failed to fetch avatar URL"),
|
||||
busy: false
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,11 +21,9 @@ import q from 'q';
|
|||
import React from 'react';
|
||||
|
||||
import sdk from '../../../index';
|
||||
import dis from '../../../dispatcher';
|
||||
import ServerConfig from '../../views/login/ServerConfig';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import RegistrationForm from '../../views/login/RegistrationForm';
|
||||
import CaptchaForm from '../../views/login/CaptchaForm';
|
||||
import RtsClient from '../../../RtsClient';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
@ -99,7 +97,7 @@ module.exports = React.createClass({
|
|||
this.props.teamServerConfig.teamServerURL &&
|
||||
!this._rtsClient
|
||||
) {
|
||||
this._rtsClient = new RtsClient(this.props.teamServerConfig.teamServerURL);
|
||||
this._rtsClient = this.props.rtsClient || new RtsClient(this.props.teamServerConfig.teamServerURL);
|
||||
|
||||
this.setState({
|
||||
teamServerBusy: true,
|
||||
|
@ -222,7 +220,6 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
trackPromise.then((teamToken) => {
|
||||
console.info('Team token promise',teamToken);
|
||||
this.props.onLoggedIn({
|
||||
userId: response.user_id,
|
||||
deviceId: response.device_id,
|
||||
|
|
|
@ -32,6 +32,7 @@ module.exports = React.createClass({
|
|||
urls: React.PropTypes.array, // [highest_priority, ... , lowest_priority]
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
// XXX resizeMethod not actually used.
|
||||
resizeMethod: React.PropTypes.string,
|
||||
defaultToInitialLetter: React.PropTypes.bool // true to add default url
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
var Presets = {
|
||||
PrivateChat: "private_chat",
|
||||
|
@ -46,9 +47,9 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<select className="mx_Presets" onChange={this.onValueChanged} value={this.props.preset}>
|
||||
<option value={this.Presets.PrivateChat}>Private Chat</option>
|
||||
<option value={this.Presets.PublicChat}>Public Chat</option>
|
||||
<option value={this.Presets.Custom}>Custom</option>
|
||||
<option value={this.Presets.PrivateChat}>{_t("Private Chat")}</option>
|
||||
<option value={this.Presets.PublicChat}>{_t("Public Chat")}</option>
|
||||
<option value={this.Presets.Custom}>{_t("Custom")}</option>
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
var React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomAlias',
|
||||
|
@ -94,7 +95,7 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
<input type="text" className="mx_RoomAlias" placeholder="Alias (optional)"
|
||||
<input type="text" className="mx_RoomAlias" placeholder={_t("Alias (optional)")}
|
||||
onChange={this.onValueChanged} onFocus={this.onFocus} onBlur={this.onBlur}
|
||||
value={this.props.alias}/>
|
||||
);
|
||||
|
|
|
@ -16,37 +16,30 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import dis from '../../../dispatcher';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import Unread from '../../../Unread';
|
||||
import classNames from 'classnames';
|
||||
import createRoom from '../../../createRoom';
|
||||
|
||||
export default class ChatCreateOrReuseDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onNewDMClick = this.onNewDMClick.bind(this);
|
||||
this.onRoomTileClick = this.onRoomTileClick.bind(this);
|
||||
|
||||
this.state = {
|
||||
tiles: [],
|
||||
profile: {
|
||||
displayName: null,
|
||||
avatarUrl: null,
|
||||
},
|
||||
profileError: null,
|
||||
};
|
||||
}
|
||||
|
||||
onNewDMClick() {
|
||||
createRoom({dmUserId: this.props.userId});
|
||||
this.props.onFinished(true);
|
||||
}
|
||||
|
||||
onRoomTileClick(roomId) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
});
|
||||
this.props.onFinished(true);
|
||||
}
|
||||
|
||||
render() {
|
||||
componentWillMount() {
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
const dmRoomMap = new DMRoomMap(client);
|
||||
|
@ -71,40 +64,123 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
|||
highlight={highlight}
|
||||
isInvite={me.membership == "invite"}
|
||||
onClick={this.onRoomTileClick}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const labelClasses = classNames({
|
||||
mx_MemberInfo_createRoom_label: true,
|
||||
mx_RoomTile_name: true,
|
||||
this.setState({
|
||||
tiles: tiles,
|
||||
});
|
||||
const startNewChat = <AccessibleButton
|
||||
className="mx_MemberInfo_createRoom"
|
||||
onClick={this.onNewDMClick}
|
||||
>
|
||||
<div className="mx_RoomTile_avatar">
|
||||
<img src="img/create-big.svg" width="26" height="26" />
|
||||
</div>
|
||||
<div className={labelClasses}><i>{_t("Start new chat")}</i></div>
|
||||
</AccessibleButton>;
|
||||
|
||||
if (tiles.length === 0) {
|
||||
this.setState({
|
||||
busyProfile: true,
|
||||
});
|
||||
MatrixClientPeg.get().getProfileInfo(this.props.userId).done((resp) => {
|
||||
const profile = {
|
||||
displayName: resp.displayname,
|
||||
avatarUrl: null,
|
||||
};
|
||||
if (resp.avatar_url) {
|
||||
profile.avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(
|
||||
resp.avatar_url, 48, 48, "crop",
|
||||
);
|
||||
}
|
||||
this.setState({
|
||||
busyProfile: false,
|
||||
profile: profile,
|
||||
});
|
||||
}, (err) => {
|
||||
console.error(
|
||||
'Unable to get profile for user ' + this.props.userId + ':',
|
||||
err,
|
||||
);
|
||||
this.setState({
|
||||
busyProfile: false,
|
||||
profileError: err,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onRoomTileClick(roomId) {
|
||||
this.props.onExistingRoomSelected(roomId);
|
||||
}
|
||||
|
||||
render() {
|
||||
let title = '';
|
||||
let content = null;
|
||||
if (this.state.tiles.length > 0) {
|
||||
// Show the existing rooms with a "+" to add a new dm
|
||||
title = _t('Create a new chat or reuse an existing one');
|
||||
const labelClasses = classNames({
|
||||
mx_MemberInfo_createRoom_label: true,
|
||||
mx_RoomTile_name: true,
|
||||
});
|
||||
const startNewChat = <AccessibleButton
|
||||
className="mx_MemberInfo_createRoom"
|
||||
onClick={this.props.onNewDMClick}
|
||||
>
|
||||
<div className="mx_RoomTile_avatar">
|
||||
<img src="img/create-big.svg" width="26" height="26" />
|
||||
</div>
|
||||
<div className={labelClasses}><i>{ _t("Start new chat") }</i></div>
|
||||
</AccessibleButton>;
|
||||
content = <div className="mx_Dialog_content">
|
||||
{ _t('You already have existing direct chats with this user:') }
|
||||
<div className="mx_ChatCreateOrReuseDialog_tiles">
|
||||
{ this.state.tiles }
|
||||
{ startNewChat }
|
||||
</div>
|
||||
</div>;
|
||||
} else {
|
||||
// Show the avatar, name and a button to confirm that a new chat is requested
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
const Spinner = sdk.getComponent('elements.Spinner');
|
||||
title = _t('Start chatting');
|
||||
|
||||
let profile = null;
|
||||
if (this.state.busyProfile) {
|
||||
profile = <Spinner />;
|
||||
} else if (this.state.profileError) {
|
||||
profile = <div className="error">
|
||||
Unable to load profile information for { this.props.userId }
|
||||
</div>;
|
||||
} else {
|
||||
profile = <div className="mx_ChatCreateOrReuseDialog_profile">
|
||||
<BaseAvatar
|
||||
name={this.state.profile.displayName || this.props.userId}
|
||||
url={this.state.profile.avatarUrl}
|
||||
width={48} height={48}
|
||||
/>
|
||||
<div className="mx_ChatCreateOrReuseDialog_profile_name">
|
||||
{this.state.profile.displayName || this.props.userId}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
content = <div>
|
||||
<div className="mx_Dialog_content">
|
||||
<p>
|
||||
{ _t('Click on the button below to start chatting!') }
|
||||
</p>
|
||||
{ profile }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this.props.onNewDMClick}>
|
||||
{ _t('Start Chatting') }
|
||||
</button>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
<BaseDialog className='mx_ChatCreateOrReuseDialog'
|
||||
onFinished={() => {
|
||||
this.props.onFinished(false)
|
||||
}}
|
||||
title='Create a new chat or reuse an existing one'
|
||||
onFinished={ this.props.onFinished.bind(false) }
|
||||
title={title}
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
You already have existing direct chats with this user:
|
||||
<div className="mx_ChatCreateOrReuseDialog_tiles">
|
||||
{tiles}
|
||||
{startNewChat}
|
||||
</div>
|
||||
</div>
|
||||
{ content }
|
||||
</BaseDialog>
|
||||
);
|
||||
}
|
||||
|
@ -112,5 +188,8 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
|||
|
||||
ChatCreateOrReuseDialog.propTyps = {
|
||||
userId: React.PropTypes.string.isRequired,
|
||||
// Called when clicking outside of the dialog
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
onNewDMClick: React.PropTypes.func.isRequired,
|
||||
onExistingRoomSelected: React.PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -15,20 +15,18 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import sdk from '../../../index';
|
||||
import { getAddressType, inviteMultipleToRoom } from '../../../Invite';
|
||||
import createRoom from '../../../createRoom';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||
import rate_limited_func from '../../../ratelimitedfunc';
|
||||
import dis from '../../../dispatcher';
|
||||
import Modal from '../../../Modal';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import q from 'q';
|
||||
|
||||
const TRUNCATE_QUERY_LIST = 40;
|
||||
const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200;
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: "ChatInviteDialog",
|
||||
|
@ -43,13 +41,13 @@ module.exports = React.createClass({
|
|||
roomId: React.PropTypes.string,
|
||||
button: React.PropTypes.string,
|
||||
focus: React.PropTypes.bool,
|
||||
onFinished: React.PropTypes.func.isRequired
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
value: "",
|
||||
focus: true
|
||||
focus: true,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -57,12 +55,20 @@ module.exports = React.createClass({
|
|||
return {
|
||||
error: false,
|
||||
|
||||
// List of AddressTile.InviteAddressType objects represeting
|
||||
// List of AddressTile.InviteAddressType objects representing
|
||||
// the list of addresses we're going to invite
|
||||
inviteList: [],
|
||||
|
||||
// List of AddressTile.InviteAddressType objects represeting
|
||||
// the set of autocompletion results for the current search
|
||||
// Whether a search is ongoing
|
||||
busy: false,
|
||||
// An error message generated during the user directory search
|
||||
searchError: null,
|
||||
// Whether the server supports the user_directory API
|
||||
serverSupportsUserDirectory: true,
|
||||
// The query being searched for
|
||||
query: "",
|
||||
// List of AddressTile.InviteAddressType objects representing
|
||||
// the set of auto-completion results for the current search
|
||||
// query.
|
||||
queryList: [],
|
||||
};
|
||||
|
@ -73,7 +79,6 @@ module.exports = React.createClass({
|
|||
// Set the cursor at the end of the text input
|
||||
this.refs.textinput.value = this.props.value;
|
||||
}
|
||||
this._updateUserList();
|
||||
},
|
||||
|
||||
onButtonClick: function() {
|
||||
|
@ -95,16 +100,25 @@ module.exports = React.createClass({
|
|||
// A Direct Message room already exists for this user, so select a
|
||||
// room from a list that is similar to the one in MemberInfo panel
|
||||
const ChatCreateOrReuseDialog = sdk.getComponent(
|
||||
"views.dialogs.ChatCreateOrReuseDialog"
|
||||
"views.dialogs.ChatCreateOrReuseDialog",
|
||||
);
|
||||
Modal.createDialog(ChatCreateOrReuseDialog, {
|
||||
userId: userId,
|
||||
onFinished: (success) => {
|
||||
if (success) {
|
||||
this.props.onFinished(true, inviteList[0]);
|
||||
}
|
||||
// else show this ChatInviteDialog again
|
||||
}
|
||||
this.props.onFinished(success);
|
||||
},
|
||||
onNewDMClick: () => {
|
||||
dis.dispatch({
|
||||
action: 'start_chat',
|
||||
user_id: userId,
|
||||
});
|
||||
},
|
||||
onExistingRoomSelected: (roomId) => {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
user_id: roomId,
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this._startChat(inviteList);
|
||||
|
@ -131,15 +145,15 @@ module.exports = React.createClass({
|
|||
} else if (e.keyCode === 38) { // up arrow
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.addressSelector.moveSelectionUp();
|
||||
if (this.addressSelector) this.addressSelector.moveSelectionUp();
|
||||
} else if (e.keyCode === 40) { // down arrow
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.addressSelector.moveSelectionDown();
|
||||
if (this.addressSelector) this.addressSelector.moveSelectionDown();
|
||||
} else if (this.state.queryList.length > 0 && (e.keyCode === 188 || e.keyCode === 13 || e.keyCode === 9)) { // comma or enter or tab
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.addressSelector.chooseSelection();
|
||||
if (this.addressSelector) this.addressSelector.chooseSelection();
|
||||
} else if (this.refs.textinput.value.length === 0 && this.state.inviteList.length && e.keyCode === 8) { // backspace
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
@ -162,74 +176,36 @@ module.exports = React.createClass({
|
|||
|
||||
onQueryChanged: function(ev) {
|
||||
const query = ev.target.value.toLowerCase();
|
||||
let queryList = [];
|
||||
|
||||
if (query.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.queryChangedDebouncer) {
|
||||
clearTimeout(this.queryChangedDebouncer);
|
||||
}
|
||||
this.queryChangedDebouncer = setTimeout(() => {
|
||||
// Only do search if there is something to search
|
||||
if (query.length > 0 && query != '@') {
|
||||
this._userList.forEach((user) => {
|
||||
if (user.userId.toLowerCase().indexOf(query) === -1 &&
|
||||
user.displayName.toLowerCase().indexOf(query) === -1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Return objects, structure of which is defined
|
||||
// by InviteAddressType
|
||||
queryList.push({
|
||||
addressType: 'mx',
|
||||
address: user.userId,
|
||||
displayName: user.displayName,
|
||||
avatarMxc: user.avatarUrl,
|
||||
isKnown: true,
|
||||
order: user.getLastActiveTs(),
|
||||
});
|
||||
});
|
||||
|
||||
queryList = queryList.sort((a,b) => {
|
||||
return a.order < b.order;
|
||||
});
|
||||
|
||||
// If the query is a valid address, add an entry for that
|
||||
// This is important, otherwise there's no way to invite
|
||||
// a perfectly valid address if there are close matches.
|
||||
const addrType = getAddressType(query);
|
||||
if (addrType !== null) {
|
||||
queryList.unshift({
|
||||
addressType: addrType,
|
||||
address: query,
|
||||
isKnown: false,
|
||||
});
|
||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||
if (addrType == 'email') {
|
||||
this._lookupThreepid(addrType, query).done();
|
||||
}
|
||||
// Only do search if there is something to search
|
||||
if (query.length > 0 && query != '@' && query.length >= 2) {
|
||||
this.queryChangedDebouncer = setTimeout(() => {
|
||||
if (this.state.serverSupportsUserDirectory) {
|
||||
this._doUserDirectorySearch(query);
|
||||
} else {
|
||||
this._doLocalSearch(query);
|
||||
}
|
||||
}
|
||||
}, QUERY_USER_DIRECTORY_DEBOUNCE_MS);
|
||||
} else {
|
||||
this.setState({
|
||||
queryList: queryList,
|
||||
error: false,
|
||||
}, () => {
|
||||
this.addressSelector.moveSelectionTop();
|
||||
queryList: [],
|
||||
query: "",
|
||||
searchError: null,
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
|
||||
onDismissed: function(index) {
|
||||
var self = this;
|
||||
return function() {
|
||||
return () => {
|
||||
var inviteList = self.state.inviteList.slice();
|
||||
inviteList.splice(index, 1);
|
||||
self.setState({
|
||||
inviteList: inviteList,
|
||||
queryList: [],
|
||||
query: "",
|
||||
});
|
||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||
};
|
||||
|
@ -248,10 +224,103 @@ module.exports = React.createClass({
|
|||
this.setState({
|
||||
inviteList: inviteList,
|
||||
queryList: [],
|
||||
query: "",
|
||||
});
|
||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||
},
|
||||
|
||||
_doUserDirectorySearch: function(query) {
|
||||
this.setState({
|
||||
busy: true,
|
||||
query,
|
||||
searchError: null,
|
||||
});
|
||||
MatrixClientPeg.get().searchUserDirectory({
|
||||
term: query,
|
||||
}).then((resp) => {
|
||||
this._processResults(resp.results, query);
|
||||
}).catch((err) => {
|
||||
console.error('Error whilst searching user directory: ', err);
|
||||
this.setState({
|
||||
searchError: err.errcode ? err.message : _t('Something went wrong!'),
|
||||
});
|
||||
if (err.errcode === 'M_UNRECOGNIZED') {
|
||||
this.setState({
|
||||
serverSupportsUserDirectory: false,
|
||||
});
|
||||
// Do a local search immediately
|
||||
this._doLocalSearch(query);
|
||||
}
|
||||
}).done(() => {
|
||||
this.setState({
|
||||
busy: false,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_doLocalSearch: function(query) {
|
||||
this.setState({
|
||||
query,
|
||||
searchError: null,
|
||||
});
|
||||
const results = [];
|
||||
MatrixClientPeg.get().getUsers().forEach((user) => {
|
||||
if (user.userId.toLowerCase().indexOf(query) === -1 &&
|
||||
user.displayName.toLowerCase().indexOf(query) === -1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Put results in the format of the new API
|
||||
results.push({
|
||||
user_id: user.userId,
|
||||
display_name: user.displayName,
|
||||
avatar_url: user.avatarUrl,
|
||||
});
|
||||
});
|
||||
this._processResults(results, query);
|
||||
},
|
||||
|
||||
_processResults: function(results, query) {
|
||||
const queryList = [];
|
||||
results.forEach((user) => {
|
||||
if (user.user_id === MatrixClientPeg.get().credentials.userId) {
|
||||
return;
|
||||
}
|
||||
// Return objects, structure of which is defined
|
||||
// by InviteAddressType
|
||||
queryList.push({
|
||||
addressType: 'mx',
|
||||
address: user.user_id,
|
||||
displayName: user.display_name,
|
||||
avatarMxc: user.avatar_url,
|
||||
isKnown: true,
|
||||
});
|
||||
});
|
||||
|
||||
// If the query is a valid address, add an entry for that
|
||||
// This is important, otherwise there's no way to invite
|
||||
// a perfectly valid address if there are close matches.
|
||||
const addrType = getAddressType(query);
|
||||
if (addrType !== null) {
|
||||
queryList.unshift({
|
||||
addressType: addrType,
|
||||
address: query,
|
||||
isKnown: false,
|
||||
});
|
||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||
if (addrType == 'email') {
|
||||
this._lookupThreepid(addrType, query).done();
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
queryList,
|
||||
error: false,
|
||||
}, () => {
|
||||
if (this.addressSelector) this.addressSelector.moveSelectionTop();
|
||||
});
|
||||
},
|
||||
|
||||
_getDirectMessageRooms: function(addr) {
|
||||
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
||||
const dmRooms = dmRoomMap.getDMRoomsForUserId(addr);
|
||||
|
@ -270,11 +339,7 @@ module.exports = React.createClass({
|
|||
|
||||
_startChat: function(addrs) {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Please Register"),
|
||||
description: _t("Guest users can't invite users. Please register."),
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -340,16 +405,6 @@ module.exports = React.createClass({
|
|||
this.props.onFinished(true, addrTexts);
|
||||
},
|
||||
|
||||
_updateUserList: function() {
|
||||
// Get all the users
|
||||
this._userList = MatrixClientPeg.get().getUsers();
|
||||
// Remove current user
|
||||
const meIx = this._userList.findIndex((u) => {
|
||||
return u.userId === MatrixClientPeg.get().credentials.userId;
|
||||
});
|
||||
this._userList.splice(meIx, 1);
|
||||
},
|
||||
|
||||
_isOnInviteList: function(uid) {
|
||||
for (let i = 0; i < this.state.inviteList.length; i++) {
|
||||
if (
|
||||
|
@ -417,6 +472,7 @@ module.exports = React.createClass({
|
|||
this.setState({
|
||||
inviteList: inviteList,
|
||||
queryList: [],
|
||||
query: "",
|
||||
});
|
||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||
return inviteList;
|
||||
|
@ -452,7 +508,7 @@ module.exports = React.createClass({
|
|||
displayName: res.displayname,
|
||||
avatarMxc: res.avatar_url,
|
||||
isKnown: true,
|
||||
}]
|
||||
}],
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -484,23 +540,27 @@ module.exports = React.createClass({
|
|||
placeholder={this.props.placeholder}
|
||||
defaultValue={this.props.value}
|
||||
autoFocus={this.props.focus}>
|
||||
</textarea>
|
||||
</textarea>,
|
||||
);
|
||||
|
||||
var error;
|
||||
var addressSelector;
|
||||
let error;
|
||||
let addressSelector;
|
||||
if (this.state.error) {
|
||||
error = <div className="mx_ChatInviteDialog_error">{_t("You have entered an invalid contact. Try using their Matrix ID or email address.")}</div>;
|
||||
} else if (this.state.searchError) {
|
||||
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>;
|
||||
} else {
|
||||
const addressSelectorHeader = <div className="mx_ChatInviteDialog_addressSelectHeader">
|
||||
Searching known users
|
||||
</div>;
|
||||
addressSelector = (
|
||||
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
||||
addressList={ this.state.queryList }
|
||||
onSelected={ this.onSelected }
|
||||
truncateAt={ TRUNCATE_QUERY_LIST }
|
||||
header={ addressSelectorHeader }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ export default class DeactivateAccountDialog extends React.Component {
|
|||
passwordBoxClass = 'error';
|
||||
}
|
||||
|
||||
const okLabel = this.state.busy ? <Loader /> : 'Deactivate Account';
|
||||
const okLabel = this.state.busy ? <Loader /> : _t('Deactivate Account');
|
||||
const okEnabled = this.state.confirmButtonEnabled && !this.state.busy;
|
||||
|
||||
let cancelButton = null;
|
||||
|
|
|
@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import sdk from '../../../index';
|
||||
|
@ -80,7 +78,7 @@ export default React.createClass({
|
|||
<AccessibleButton onClick={this._onDismissClick}
|
||||
className="mx_UserSettings_button"
|
||||
>
|
||||
Dismiss
|
||||
{_t("Dismiss")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ import React from 'react';
|
|||
import sdk from '../../../index';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import Modal from '../../../Modal';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
|
||||
export default React.createClass({
|
||||
|
@ -44,8 +44,11 @@ export default React.createClass({
|
|||
|
||||
if (SdkConfig.get().bug_report_endpoint_url) {
|
||||
bugreport = (
|
||||
<p>Otherwise, <a onClick={this._sendBugReport} href='#'>
|
||||
click here</a> to send a bug report.
|
||||
<p>
|
||||
{_tJsx(
|
||||
"Otherwise, <a>click here</a> to send a bug report.",
|
||||
/<a>(.*?)<\/a>/, (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{sub}</a>,
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
/**
|
||||
* Prompt the user to set a display name.
|
||||
*
|
||||
* On success, `onFinished(true, newDisplayName)` is called.
|
||||
*/
|
||||
export default React.createClass({
|
||||
displayName: 'SetDisplayNameDialog',
|
||||
propTypes: {
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
currentDisplayName: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
if (this.props.currentDisplayName) {
|
||||
return { value: this.props.currentDisplayName };
|
||||
}
|
||||
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
return { value : "Guest " + MatrixClientPeg.get().getUserIdLocalpart() };
|
||||
}
|
||||
else {
|
||||
return { value : MatrixClientPeg.get().getUserIdLocalpart() };
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.refs.input_value.select();
|
||||
},
|
||||
|
||||
onValueChange: function(ev) {
|
||||
this.setState({
|
||||
value: ev.target.value
|
||||
});
|
||||
},
|
||||
|
||||
onFormSubmit: function(ev) {
|
||||
ev.preventDefault();
|
||||
this.props.onFinished(true, this.state.value);
|
||||
return false;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
<BaseDialog className="mx_SetDisplayNameDialog"
|
||||
onFinished={this.props.onFinished}
|
||||
title={_t("Set a Display Name")}
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
{_t("Your display name is how you'll appear to others when you speak in rooms. " +
|
||||
"What would you like it to be?")}
|
||||
</div>
|
||||
<form onSubmit={this.onFormSubmit}>
|
||||
<div className="mx_Dialog_content">
|
||||
<input type="text" ref="input_value" value={this.state.value}
|
||||
autoFocus={true} onChange={this.onValueChange} size="30"
|
||||
className="mx_SetDisplayNameDialog_input"
|
||||
/>
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<input className="mx_Dialog_primary" type="submit" value="Set" />
|
||||
</div>
|
||||
</form>
|
||||
</BaseDialog>
|
||||
);
|
||||
},
|
||||
});
|
294
src/components/views/dialogs/SetMxIdDialog.js
Normal file
294
src/components/views/dialogs/SetMxIdDialog.js
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import q from 'q';
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import classnames from 'classnames';
|
||||
import KeyCode from '../../../KeyCode';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
// The amount of time to wait for further changes to the input username before
|
||||
// sending a request to the server
|
||||
const USERNAME_CHECK_DEBOUNCE_MS = 250;
|
||||
|
||||
/**
|
||||
* Prompt the user to set a display name.
|
||||
*
|
||||
* On success, `onFinished(true, newDisplayName)` is called.
|
||||
*/
|
||||
export default React.createClass({
|
||||
displayName: 'SetMxIdDialog',
|
||||
propTypes: {
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
// Called when the user requests to register with a different homeserver
|
||||
onDifferentServerClicked: React.PropTypes.func.isRequired,
|
||||
// Called if the user wants to switch to login instead
|
||||
onLoginClick: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
// The entered username
|
||||
username: '',
|
||||
// Indicate ongoing work on the username
|
||||
usernameBusy: false,
|
||||
// Indicate error with username
|
||||
usernameError: '',
|
||||
// Assume the homeserver supports username checking until "M_UNRECOGNIZED"
|
||||
usernameCheckSupport: true,
|
||||
|
||||
// Whether the auth UI is currently being used
|
||||
doingUIAuth: false,
|
||||
// Indicate error with auth
|
||||
authError: '',
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.refs.input_value.select();
|
||||
|
||||
this._matrixClient = MatrixClientPeg.get();
|
||||
},
|
||||
|
||||
onValueChange: function(ev) {
|
||||
this.setState({
|
||||
username: ev.target.value,
|
||||
usernameBusy: true,
|
||||
usernameError: '',
|
||||
}, () => {
|
||||
if (!this.state.username || !this.state.usernameCheckSupport) {
|
||||
this.setState({
|
||||
usernameBusy: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Debounce the username check to limit number of requests sent
|
||||
if (this._usernameCheckTimeout) {
|
||||
clearTimeout(this._usernameCheckTimeout);
|
||||
}
|
||||
this._usernameCheckTimeout = setTimeout(() => {
|
||||
this._doUsernameCheck().finally(() => {
|
||||
this.setState({
|
||||
usernameBusy: false,
|
||||
});
|
||||
});
|
||||
}, USERNAME_CHECK_DEBOUNCE_MS);
|
||||
});
|
||||
},
|
||||
|
||||
onKeyUp: function(ev) {
|
||||
if (ev.keyCode === KeyCode.ENTER) {
|
||||
this.onSubmit();
|
||||
}
|
||||
},
|
||||
|
||||
onSubmit: function(ev) {
|
||||
this.setState({
|
||||
doingUIAuth: true,
|
||||
});
|
||||
},
|
||||
|
||||
_doUsernameCheck: function() {
|
||||
// Check if username is available
|
||||
return this._matrixClient.isUsernameAvailable(this.state.username).then(
|
||||
(isAvailable) => {
|
||||
if (isAvailable) {
|
||||
this.setState({usernameError: ''});
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
// Indicate whether the homeserver supports username checking
|
||||
const newState = {
|
||||
usernameCheckSupport: err.errcode !== "M_UNRECOGNIZED",
|
||||
};
|
||||
console.error('Error whilst checking username availability: ', err);
|
||||
switch (err.errcode) {
|
||||
case "M_USER_IN_USE":
|
||||
newState.usernameError = _t('Username not available');
|
||||
break;
|
||||
case "M_INVALID_USERNAME":
|
||||
newState.usernameError = _t(
|
||||
'Username invalid: %(errMessage)s',
|
||||
{ errMessage: err.message},
|
||||
);
|
||||
break;
|
||||
case "M_UNRECOGNIZED":
|
||||
// This homeserver doesn't support username checking, assume it's
|
||||
// fine and rely on the error appearing in registration step.
|
||||
newState.usernameError = '';
|
||||
break;
|
||||
case undefined:
|
||||
newState.usernameError = _t('Something went wrong!');
|
||||
break;
|
||||
default:
|
||||
newState.usernameError = _t(
|
||||
'An error occurred: %(error_string)s',
|
||||
{ error_string: err.message },
|
||||
);
|
||||
break;
|
||||
}
|
||||
this.setState(newState);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
_generatePassword: function() {
|
||||
return Math.random().toString(36).slice(2);
|
||||
},
|
||||
|
||||
_makeRegisterRequest: function(auth) {
|
||||
// Not upgrading - changing mxids
|
||||
const guestAccessToken = null;
|
||||
if (!this._generatedPassword) {
|
||||
this._generatedPassword = this._generatePassword();
|
||||
}
|
||||
return this._matrixClient.register(
|
||||
this.state.username,
|
||||
this._generatedPassword,
|
||||
undefined, // session id: included in the auth dict already
|
||||
auth,
|
||||
{},
|
||||
guestAccessToken,
|
||||
);
|
||||
},
|
||||
|
||||
_onUIAuthFinished: function(success, response) {
|
||||
this.setState({
|
||||
doingUIAuth: false,
|
||||
});
|
||||
|
||||
if (!success) {
|
||||
this.setState({ authError: response.message });
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX Implement RTS /register here
|
||||
const teamToken = null;
|
||||
|
||||
this.props.onFinished(true, {
|
||||
userId: response.user_id,
|
||||
deviceId: response.device_id,
|
||||
homeserverUrl: this._matrixClient.getHomeserverUrl(),
|
||||
identityServerUrl: this._matrixClient.getIdentityServerUrl(),
|
||||
accessToken: response.access_token,
|
||||
password: this._generatedPassword,
|
||||
teamToken: teamToken,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth');
|
||||
const Spinner = sdk.getComponent('elements.Spinner');
|
||||
|
||||
let auth;
|
||||
if (this.state.doingUIAuth) {
|
||||
auth = <InteractiveAuth
|
||||
matrixClient={this._matrixClient}
|
||||
makeRequest={this._makeRegisterRequest}
|
||||
onAuthFinished={this._onUIAuthFinished}
|
||||
inputs={{}}
|
||||
poll={true}
|
||||
/>;
|
||||
}
|
||||
const inputClasses = classnames({
|
||||
"mx_SetMxIdDialog_input": true,
|
||||
"error": Boolean(this.state.usernameError),
|
||||
});
|
||||
|
||||
let usernameIndicator = null;
|
||||
let usernameBusyIndicator = null;
|
||||
if (this.state.usernameBusy) {
|
||||
usernameBusyIndicator = <Spinner w="24" h="24"/>;
|
||||
} else {
|
||||
const usernameAvailable = this.state.username &&
|
||||
this.state.usernameCheckSupport && !this.state.usernameError;
|
||||
const usernameIndicatorClasses = classnames({
|
||||
"error": Boolean(this.state.usernameError),
|
||||
"success": usernameAvailable,
|
||||
});
|
||||
usernameIndicator = <div className={usernameIndicatorClasses}>
|
||||
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
|
||||
</div>;
|
||||
}
|
||||
|
||||
let authErrorIndicator = null;
|
||||
if (this.state.authError) {
|
||||
authErrorIndicator = <div className="error">
|
||||
{ this.state.authError }
|
||||
</div>;
|
||||
}
|
||||
const canContinue = this.state.username &&
|
||||
!this.state.usernameError &&
|
||||
!this.state.usernameBusy;
|
||||
|
||||
return (
|
||||
<BaseDialog className="mx_SetMxIdDialog"
|
||||
onFinished={this.props.onFinished}
|
||||
title="To get started, please pick a username!"
|
||||
>
|
||||
<div className="mx_Dialog_content">
|
||||
<div className="mx_SetMxIdDialog_input_group">
|
||||
<input type="text" ref="input_value" value={this.state.username}
|
||||
autoFocus={true}
|
||||
onChange={this.onValueChange}
|
||||
onKeyUp={this.onKeyUp}
|
||||
size="30"
|
||||
className={inputClasses}
|
||||
/>
|
||||
{ usernameBusyIndicator }
|
||||
</div>
|
||||
{ usernameIndicator }
|
||||
<p>
|
||||
{ _tJsx(
|
||||
'This will be your account name on the <span></span> ' +
|
||||
'homeserver, or you can pick a <a>different server</a>.',
|
||||
[
|
||||
/<span><\/span>/,
|
||||
/<a>(.*?)<\/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>],
|
||||
)}
|
||||
</p>
|
||||
{ auth }
|
||||
{ authErrorIndicator }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<input className="mx_Dialog_primary"
|
||||
type="submit"
|
||||
value={_t("Continue")}
|
||||
onClick={this.onSubmit}
|
||||
disabled={!canContinue}
|
||||
/>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import dis from '../../../dispatcher';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||
import Resend from '../../../Resend';
|
||||
|
@ -146,7 +145,7 @@ export default React.createClass({
|
|||
console.log("UnknownDeviceDialog closed by escape");
|
||||
this.props.onFinished();
|
||||
}}
|
||||
title='Room contains unknown devices'
|
||||
title={_t('Room contains unknown devices')}
|
||||
>
|
||||
<GeminiScrollbar autoshow={false} className="mx_Dialog_content">
|
||||
<h4>
|
||||
|
@ -163,7 +162,7 @@ export default React.createClass({
|
|||
this.props.onFinished();
|
||||
Resend.resendUnsentEvents(this.props.room);
|
||||
}}>
|
||||
Send anyway
|
||||
{_t("Send anyway")}
|
||||
</button>
|
||||
<button className="mx_Dialog_primary" autoFocus={ true }
|
||||
onClick={() => {
|
||||
|
|
84
src/components/views/elements/ActionButton.js
Normal file
84
src/components/views/elements/ActionButton.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import AccessibleButton from './AccessibleButton';
|
||||
import dis from '../../../dispatcher';
|
||||
import sdk from '../../../index';
|
||||
|
||||
export default React.createClass({
|
||||
displayName: 'RoleButton',
|
||||
|
||||
propTypes: {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
action: PropTypes.string.isRequired,
|
||||
mouseOverAction: PropTypes.string,
|
||||
label: PropTypes.string.isRequired,
|
||||
iconPath: PropTypes.string.isRequired,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
size: "25",
|
||||
tooltip: false,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showTooltip: false,
|
||||
};
|
||||
},
|
||||
|
||||
_onClick: function(ev) {
|
||||
ev.stopPropagation();
|
||||
dis.dispatch({action: this.props.action});
|
||||
},
|
||||
|
||||
_onMouseEnter: function() {
|
||||
if (this.props.tooltip) this.setState({showTooltip: true});
|
||||
if (this.props.mouseOverAction) {
|
||||
dis.dispatch({action: this.props.mouseOverAction});
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseLeave: function() {
|
||||
this.setState({showTooltip: false});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
|
||||
let tooltip;
|
||||
if (this.state.showTooltip) {
|
||||
const RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||
tooltip = <RoomTooltip className="mx_RoleButton_tooltip" label={this.props.label} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<AccessibleButton className="mx_RoleButton"
|
||||
onClick={this._onClick}
|
||||
onMouseEnter={this._onMouseEnter}
|
||||
onMouseLeave={this._onMouseLeave}
|
||||
>
|
||||
<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />
|
||||
{tooltip}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -19,9 +19,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import sdk from "../../../index";
|
||||
import Invite from "../../../Invite";
|
||||
import MatrixClientPeg from "../../../MatrixClientPeg";
|
||||
import Avatar from '../../../Avatar';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
// React PropType definition for an object describing
|
||||
|
|
40
src/components/views/elements/CreateRoomButton.js
Normal file
40
src/components/views/elements/CreateRoomButton.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
const CreateRoomButton = function(props) {
|
||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_create_room"
|
||||
mouseOverAction={props.callout ? "callout_create_room" : null}
|
||||
label={ _t("Create new room") }
|
||||
iconPath="img/icons-create-room.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
CreateRoomButton.propTypes = {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default CreateRoomButton;
|
39
src/components/views/elements/HomeButton.js
Normal file
39
src/components/views/elements/HomeButton.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
const HomeButton = function(props) {
|
||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_home_page"
|
||||
label={ _t("Home") }
|
||||
iconPath="img/icons-home.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
HomeButton.propTypes = {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default HomeButton;
|
|
@ -19,7 +19,6 @@ import React from 'react';
|
|||
|
||||
import sdk from '../../../index';
|
||||
import UserSettingsStore from '../../../UserSettingsStore';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import * as languageHandler from '../../../languageHandler';
|
||||
|
||||
function languageMatchesSearchQuery(query, language) {
|
||||
|
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
const MemberAvatar = require('../avatars/MemberAvatar.js');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
@ -111,9 +112,13 @@ module.exports = React.createClass({
|
|||
return null;
|
||||
}
|
||||
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
|
||||
return (
|
||||
<span className="mx_TextualEvent mx_MemberEventListSummary_summary">
|
||||
{summaries.join(", ")}
|
||||
<EmojiText>
|
||||
{summaries.join(", ")}
|
||||
</EmojiText>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
@ -222,8 +227,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)sjoined", { severalUsers: "" })
|
||||
: _t("%(oneUser)sjoined", { oneUser: "" });
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
case "left":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -233,7 +237,8 @@ module.exports = React.createClass({
|
|||
res = (plural)
|
||||
? _t("%(severalUsers)sleft", { severalUsers: "" })
|
||||
: _t("%(oneUser)sleft", { oneUser: "" });
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
case "joined_and_left":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -244,7 +249,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)sjoined and left", { severalUsers: "" })
|
||||
: _t("%(oneUser)sjoined and left", { oneUser: "" });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "left_and_joined":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -254,8 +259,8 @@ module.exports = React.createClass({
|
|||
res = (plural)
|
||||
? _t("%(severalUsers)sleft and rejoined", { severalUsers: "" })
|
||||
: _t("%(oneUser)sleft and rejoined", { oneUser: "" });
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "invite_reject":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -266,7 +271,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)srejected their invitations", { severalUsers: "" })
|
||||
: _t("%(oneUser)srejected their invitation", { oneUser: "" });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "invite_withdrawal":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -277,7 +282,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)shad their invitations withdrawn", { severalUsers: "" })
|
||||
: _t("%(oneUser)shad their invitation withdrawn", { oneUser: "" });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "invited":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -288,7 +293,7 @@ module.exports = React.createClass({
|
|||
? _t("were invited")
|
||||
: _t("was invited");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "banned":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -299,7 +304,7 @@ module.exports = React.createClass({
|
|||
? _t("were banned")
|
||||
: _t("was banned");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "unbanned":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -310,7 +315,7 @@ module.exports = React.createClass({
|
|||
? _t("were unbanned")
|
||||
: _t("was unbanned");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "kicked":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -321,7 +326,7 @@ module.exports = React.createClass({
|
|||
? _t("were kicked")
|
||||
: _t("was kicked");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "changed_name":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -332,7 +337,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)schanged their name", { severalUsers: "" })
|
||||
: _t("%(oneUser)schanged their name", { oneUser: "" });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "changed_avatar":
|
||||
if (repeats > 1) {
|
||||
res = (plural)
|
||||
|
@ -343,7 +348,7 @@ module.exports = React.createClass({
|
|||
? _t("%(severalUsers)schanged their avatar", { severalUsers: "" })
|
||||
: _t("%(oneUser)schanged their avatar", { oneUser: "" });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
40
src/components/views/elements/RoomDirectoryButton.js
Normal file
40
src/components/views/elements/RoomDirectoryButton.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
const RoomDirectoryButton = function(props) {
|
||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_room_directory"
|
||||
mouseOverAction={props.callout ? "callout_room_directory" : null}
|
||||
label={ _t("Room directory") }
|
||||
iconPath="img/icons-directory.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
RoomDirectoryButton.propTypes = {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default RoomDirectoryButton;
|
39
src/components/views/elements/SettingsButton.js
Normal file
39
src/components/views/elements/SettingsButton.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
const SettingsButton = function(props) {
|
||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_user_settings"
|
||||
label={ _t("Settings") }
|
||||
iconPath="img/icons-settings.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
SettingsButton.propTypes = {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default SettingsButton;
|
40
src/components/views/elements/StartChatButton.js
Normal file
40
src/components/views/elements/StartChatButton.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
const StartChatButton = function(props) {
|
||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_create_chat"
|
||||
mouseOverAction={props.callout ? "callout_start_chat" : null}
|
||||
label={ _t("Start chat") }
|
||||
iconPath="img/icons-people.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
StartChatButton.propTypes = {
|
||||
size: PropTypes.string,
|
||||
tooltip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default StartChatButton;
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
var React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'TruncatedList',
|
||||
|
@ -33,7 +34,7 @@ module.exports = React.createClass({
|
|||
truncateAt: 2,
|
||||
createOverflowElement: function(overflowCount, totalCount) {
|
||||
return (
|
||||
<div>And {overflowCount} more...</div>
|
||||
<div>{_t("And %(count)s more...", {count: overflowCount})}</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -440,7 +440,7 @@ export const FallbackAuthEntry = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<a onClick={this._onShowFallbackClick}>Start authentication</a>
|
||||
<a onClick={this._onShowFallbackClick}>{_t("Start authentication")}</a>
|
||||
<div className="error">
|
||||
{this.props.errorText}
|
||||
</div>
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
import { _t } from '../../../languageHandler';
|
||||
import React from 'react';
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -27,5 +28,5 @@ module.exports = React.createClass({
|
|||
<a href="https://matrix.org">{_t("powered by Matrix")}</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import classNames from 'classnames';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
|
|
@ -101,7 +101,7 @@ module.exports = React.createClass({
|
|||
if (this.refs.email.value == '') {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Warning!",
|
||||
title: _t("Warning!"),
|
||||
description:
|
||||
<div>
|
||||
{_t("If you don't specify an email address, you won't be able to reset your password. " +
|
||||
|
@ -110,18 +110,17 @@ module.exports = React.createClass({
|
|||
button: _t("Continue"),
|
||||
onFinished: function(confirmed) {
|
||||
if (confirmed) {
|
||||
self._doSubmit();
|
||||
self._doSubmit(ev);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
self._doSubmit();
|
||||
} else {
|
||||
self._doSubmit(ev);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_doSubmit: function() {
|
||||
_doSubmit: function(ev) {
|
||||
let email = this.refs.email.value.trim();
|
||||
var promise = this.props.onRegisterClick({
|
||||
username: this.refs.username.value.trim() || this.props.guestUsername,
|
||||
|
@ -336,7 +335,7 @@ module.exports = React.createClass({
|
|||
);
|
||||
|
||||
const registerButton = (
|
||||
<input className="mx_Login_submit" type="submit" value="Register" />
|
||||
<input className="mx_Login_submit" type="submit" value={_t("Register")} />
|
||||
);
|
||||
|
||||
let placeholderUserName = _t("User name");
|
||||
|
|
|
@ -20,7 +20,6 @@ import React from 'react';
|
|||
import MFileBody from './MFileBody';
|
||||
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import sdk from '../../../index';
|
||||
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import { _t } from '../../../languageHandler';
|
|||
import {decryptFile} from '../../../utils/DecryptFile';
|
||||
import Tinter from '../../../Tinter';
|
||||
import request from 'browser-request';
|
||||
import q from 'q';
|
||||
import Modal from '../../../Modal';
|
||||
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import MFileBody from './MFileBody';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import Model from '../../../Modal';
|
||||
import sdk from '../../../index';
|
||||
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
||||
import q from 'q';
|
||||
import UserSettingsStore from '../../../UserSettingsStore';
|
||||
|
|
|
@ -30,7 +30,7 @@ export default function SenderProfile(props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<EmojiText className="mx_SenderProfile"
|
||||
<EmojiText className="mx_SenderProfile" dir="auto"
|
||||
onClick={props.onClick}>{`${name || ''} ${props.aux || ''}`}</EmojiText>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,19 @@ module.exports = React.createClass({
|
|||
};
|
||||
},
|
||||
|
||||
copyToClipboard: function(text) {
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.select();
|
||||
try {
|
||||
const successful = document.execCommand('copy');
|
||||
} catch (err) {
|
||||
console.log('Unable to copy');
|
||||
}
|
||||
document.body.removeChild(textArea);
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this._unmounted = false;
|
||||
|
||||
|
@ -81,6 +94,14 @@ module.exports = React.createClass({
|
|||
}
|
||||
}, 10);
|
||||
}
|
||||
// add event handlers to the 'copy code' buttons
|
||||
const buttons = ReactDOM.findDOMNode(this).getElementsByClassName("mx_EventTile_copyButton");
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
buttons[i].onclick = (e) => {
|
||||
const copyCode = buttons[i].parentNode.getElementsByTagName("code")[0];
|
||||
this.copyToClipboard(copyCode.textContent);
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ var Tinter = require('../../../Tinter');
|
|||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
var Modal = require("../../../Modal");
|
||||
|
||||
import dis from '../../../dispatcher';
|
||||
|
||||
var ROOM_COLORS = [
|
||||
// magic room default values courtesy of Ribot
|
||||
["#76cfa6", "#eaf5f0"],
|
||||
|
@ -86,11 +88,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
).catch(function(err) {
|
||||
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: "Please Register",
|
||||
description: "Saving room color settings is only available to registered users"
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import classNames from 'classnames';
|
|||
import flatMap from 'lodash/flatMap';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import sdk from '../../../index';
|
||||
import type {Completion, SelectionRange} from '../../../autocomplete/Autocompleter';
|
||||
import type {Completion} from '../../../autocomplete/Autocompleter';
|
||||
import Q from 'q';
|
||||
|
||||
import {getCompletions} from '../../../autocomplete/Autocompleter';
|
||||
|
|
|
@ -20,7 +20,7 @@ import sdk from '../../../index';
|
|||
import dis from "../../../dispatcher";
|
||||
import ObjectUtils from '../../../ObjectUtils';
|
||||
import AppsDrawer from './AppsDrawer';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { _t, _tJsx} from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'AuxPanel',
|
||||
|
@ -78,7 +78,7 @@ module.exports = React.createClass({
|
|||
fileDropTarget = (
|
||||
<div className="mx_RoomView_fileDropTarget">
|
||||
<div className="mx_RoomView_fileDropTargetLabel"
|
||||
title="Drop File Here">
|
||||
title={_t("Drop File Here")}>
|
||||
<TintableSvg src="img/upload-big.svg" width="45" height="59"/>
|
||||
<br/>
|
||||
{_t("Drop file here to upload")}
|
||||
|
@ -89,20 +89,29 @@ module.exports = React.createClass({
|
|||
|
||||
let conferenceCallNotification = null;
|
||||
if (this.props.displayConfCallNotification) {
|
||||
let supportedText;
|
||||
let joinText;
|
||||
let supportedText = '';
|
||||
let joinNode;
|
||||
if (!MatrixClientPeg.get().supportsVoip()) {
|
||||
supportedText = _t(" (unsupported)");
|
||||
} else {
|
||||
joinText = (<span>
|
||||
Join as <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}}
|
||||
href="#">voice</a> or <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video'); }}
|
||||
href="#">video</a>.
|
||||
joinNode = (<span>
|
||||
{_tJsx(
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.",
|
||||
[/<voiceText>(.*?)<\/voiceText>/, /<videoText>(.*?)<\/videoText>/],
|
||||
[
|
||||
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}} href="#">{sub}</a>,
|
||||
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video');}} href="#">{sub}</a>,
|
||||
]
|
||||
)}
|
||||
</span>);
|
||||
}
|
||||
// XXX: the translation here isn't great: appending ' (unsupported)' is likely to not make sense in many languages,
|
||||
// but there are translations for this in the languages we do have so I'm leaving it for now.
|
||||
conferenceCallNotification = (
|
||||
<div className="mx_RoomView_ongoingConfCallNotification">
|
||||
{_t("Ongoing conference call%(supportedText)s. %(joinText)s", {supportedText: supportedText, joinText: joinText})}
|
||||
{_t("Ongoing conference call%(supportedText)s.", {supportedText: supportedText})}
|
||||
|
||||
{joinNode}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ var React = require('react');
|
|||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require('../../../index');
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
||||
var PRESENCE_CLASS = {
|
||||
|
@ -115,7 +116,7 @@ module.exports = React.createClass({
|
|||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
||||
<EmojiText element="div" className="mx_EntityTile_name_hover">{name}</EmojiText>
|
||||
<EmojiText element="div" className="mx_EntityTile_name_hover" dir="auto">{name}</EmojiText>
|
||||
<PresenceLabel activeAgo={ activeAgo }
|
||||
currentlyActive={this.props.presenceCurrentlyActive}
|
||||
presenceState={this.props.presenceState} />
|
||||
|
@ -124,7 +125,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
else {
|
||||
nameEl = (
|
||||
<EmojiText element="div" className="mx_EntityTile_name">{name}</EmojiText>
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">{name}</EmojiText>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -140,10 +141,10 @@ module.exports = React.createClass({
|
|||
var power;
|
||||
var powerLevel = this.props.powerLevel;
|
||||
if (powerLevel >= 50 && powerLevel < 99) {
|
||||
power = <img src="img/mod.svg" className="mx_EntityTile_power" width="16" height="17" alt="Mod"/>;
|
||||
power = <img src="img/mod.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Moderator")}/>;
|
||||
}
|
||||
if (powerLevel >= 99) {
|
||||
power = <img src="img/admin.svg" className="mx_EntityTile_power" width="16" height="17" alt="Admin"/>;
|
||||
power = <img src="img/admin.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Admin")}/>;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
event_id: this.props.mxEvent.getId(),
|
||||
highlighted: true,
|
||||
room_id: this.props.mxEvent.getRoomId(),
|
||||
});
|
||||
},
|
||||
|
@ -487,22 +488,22 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
let e2e;
|
||||
// cosmetic padlocks:
|
||||
if ((e2eEnabled && this.props.eventSendStatus) || this.props.mxEvent.getType() === 'm.room.encryption') {
|
||||
e2e = <img style={{ cursor: 'initial', marginLeft: '-1px' }} className="mx_EventTile_e2eIcon" alt="Encrypted by verified device" src="img/e2e-verified.svg" width="10" height="12" />;
|
||||
e2e = <img style={{ cursor: 'initial', marginLeft: '-1px' }} className="mx_EventTile_e2eIcon" alt={_t("Encrypted by a verified device")} src="img/e2e-verified.svg" width="10" height="12" />;
|
||||
}
|
||||
// real padlocks
|
||||
else if (this.props.mxEvent.isEncrypted() || (e2eEnabled && this.props.eventSendStatus)) {
|
||||
if (this.props.mxEvent.getContent().msgtype === 'm.bad.encrypted') {
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt="Undecryptable" src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} />;
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt={_t("Undecryptable")} src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} />;
|
||||
}
|
||||
else if (this.state.verified == true || (e2eEnabled && this.props.eventSendStatus)) {
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt="Encrypted by verified device" src="img/e2e-verified.svg" width="10" height="12"/>;
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt={_t("Encrypted by a verified device")} src="img/e2e-verified.svg" width="10" height="12"/>;
|
||||
}
|
||||
else {
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt="Encrypted by unverified device" src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }}/>;
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt={_t("Encrypted by an unverified device")} src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }}/>;
|
||||
}
|
||||
}
|
||||
else if (e2eEnabled) {
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt="Unencrypted message" src="img/e2e-unencrypted.svg" width="12" height="12"/>;
|
||||
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" alt={_t("Unencrypted message")} src="img/e2e-unencrypted.svg" width="12" height="12"/>;
|
||||
}
|
||||
const timestamp = this.props.mxEvent.getTs() ?
|
||||
<MessageTimestamp showTwelveHour={this.props.isTwelveHour} ts={this.props.mxEvent.getTs()} /> : null;
|
||||
|
|
|
@ -26,19 +26,19 @@ export default class MemberDeviceInfo extends React.Component {
|
|||
if (this.props.device.isBlocked()) {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_blacklisted">
|
||||
<img src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} alt="Blacklisted"/>
|
||||
<img src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} alt={_t("Blacklisted")}/>
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.device.isVerified()) {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_verified">
|
||||
<img src="img/e2e-verified.svg" width="10" height="12" alt="Verified"/>
|
||||
<img src="img/e2e-verified.svg" width="10" height="12" alt={_t("Verified")}/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_unverified">
|
||||
<img src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }} alt="Unverified"/>
|
||||
<img src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }} alt={_t("Unverified")}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ import Unread from '../../../Unread';
|
|||
import { findReadReceiptFromUserId } from '../../../utils/Receipt';
|
||||
import WithMatrixClient from '../../../wrappers/WithMatrixClient';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||
|
||||
|
||||
module.exports = WithMatrixClient(React.createClass({
|
||||
displayName: 'MemberInfo',
|
||||
|
@ -375,11 +377,7 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
console.log("Mod toggle success");
|
||||
}, function(err) {
|
||||
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t("Please Register"),
|
||||
description: _t("This action cannot be performed by a guest user. Please register to be able to do this") + ".",
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
} else {
|
||||
console.error("Toggle moderator error:" + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
|
@ -436,7 +434,7 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
title: _t("Warning!"),
|
||||
description:
|
||||
<div>
|
||||
{ _t("You will not be able to undo this change as you are promoting the user to have the same power level as yourself") }.<br/>
|
||||
{ _t("You will not be able to undo this change as you are promoting the user to have the same power level as yourself.") }<br/>
|
||||
{ _t("Are you sure?") }
|
||||
</div>,
|
||||
button: _t("Continue"),
|
||||
|
@ -705,7 +703,7 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
if (kickButton || banButton || muteButton || giveModButton) {
|
||||
adminTools =
|
||||
<div>
|
||||
<h3>Admin tools</h3>
|
||||
<h3>{_t("Admin tools")}</h3>
|
||||
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
{muteButton}
|
||||
|
@ -731,34 +729,36 @@ module.exports = WithMatrixClient(React.createClass({
|
|||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}> <img src="img/cancel.svg" width="18" height="18"/></AccessibleButton>
|
||||
<div className="mx_MemberInfo_avatar">
|
||||
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
|
||||
</div>
|
||||
|
||||
<EmojiText element="h2">{memberName}</EmojiText>
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ this.props.member.userId }
|
||||
<GeminiScrollbar autoshow={true}>
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}> <img src="img/cancel.svg" width="18" height="18"/></AccessibleButton>
|
||||
<div className="mx_MemberInfo_avatar">
|
||||
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ _t("Level") }: <b><PowerSelector controlled={true} value={ parseInt(this.props.member.powerLevel) } disabled={ !this.state.can.modifyLevel } onChange={ this.onPowerChange }/></b>
|
||||
|
||||
<EmojiText element="h2">{memberName}</EmojiText>
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ this.props.member.userId }
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ _t("Level:") } <b><PowerSelector controlled={true} value={ parseInt(this.props.member.powerLevel) } disabled={ !this.state.can.modifyLevel } onChange={ this.onPowerChange }/></b>
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
<PresenceLabel activeAgo={ presenceLastActiveAgo }
|
||||
currentlyActive={ presenceCurrentlyActive }
|
||||
presenceState={ presenceState } />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
<PresenceLabel activeAgo={ presenceLastActiveAgo }
|
||||
currentlyActive={ presenceCurrentlyActive }
|
||||
presenceState={ presenceState } />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{ adminTools }
|
||||
{ adminTools }
|
||||
|
||||
{ startChat }
|
||||
{ startChat }
|
||||
|
||||
{ this._renderDevices() }
|
||||
{ this._renderDevices() }
|
||||
|
||||
{ spinner }
|
||||
{ spinner }
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ var MatrixClientPeg = require('../../../MatrixClientPeg');
|
|||
var sdk = require('../../../index');
|
||||
var dis = require('../../../dispatcher');
|
||||
var Modal = require("../../../Modal");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MemberTile',
|
||||
|
@ -63,7 +64,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getPowerLabel: function() {
|
||||
return this.props.member.userId + " (power " + this.props.member.powerLevel + ")";
|
||||
return _t("%(userName)s (power %(powerLevelNumber)s)", {userName: this.props.member.userId, powerLevelNumber: this.props.member.powerLevel});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
|
|
@ -91,11 +91,7 @@ export default class MessageComposer extends React.Component {
|
|||
|
||||
onUploadClick(ev) {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t('Please Register'),
|
||||
description: _t('Guest users can\'t upload files. Please register to upload') + '.',
|
||||
});
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -113,7 +109,7 @@ export default class MessageComposer extends React.Component {
|
|||
let fileList = [];
|
||||
for (let i=0; i<files.length; i++) {
|
||||
fileList.push(<li key={i}>
|
||||
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> {files[i].name || 'Attachment'}
|
||||
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> {files[i].name || _t('Attachment')}
|
||||
</li>);
|
||||
}
|
||||
|
||||
|
@ -318,7 +314,7 @@ export default class MessageComposer extends React.Component {
|
|||
|
||||
const formattingButton = (
|
||||
<img className="mx_MessageComposer_formatting"
|
||||
title="Show Text Formatting Toolbar"
|
||||
title={_t("Show Text Formatting Toolbar")}
|
||||
src="img/button-text-formatting.svg"
|
||||
onClick={this.onToggleFormattingClicked}
|
||||
style={{visibility: this.state.showFormatting ||
|
||||
|
|
|
@ -28,12 +28,12 @@ import Q from 'q';
|
|||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import type {MatrixClient} from 'matrix-js-sdk/lib/matrix';
|
||||
import SlashCommands from '../../../SlashCommands';
|
||||
import KeyCode from '../../../KeyCode';
|
||||
import Modal from '../../../Modal';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
import dis from '../../../dispatcher';
|
||||
import KeyCode from '../../../KeyCode';
|
||||
import UserSettingsStore from '../../../UserSettingsStore';
|
||||
|
||||
import * as RichText from '../../../RichText';
|
||||
|
@ -45,8 +45,6 @@ import {onSendMessageFailed} from './MessageComposerInputOld';
|
|||
|
||||
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
|
||||
|
||||
const KEY_M = 77;
|
||||
|
||||
const ZWS_CODE = 8203;
|
||||
const ZWS = String.fromCharCode(ZWS_CODE); // zero width space
|
||||
function stateToMarkdown(state) {
|
||||
|
@ -62,7 +60,7 @@ function stateToMarkdown(state) {
|
|||
export default class MessageComposerInput extends React.Component {
|
||||
static getKeyBinding(e: SyntheticKeyboardEvent): string {
|
||||
// C-m => Toggles between rich text and markdown modes
|
||||
if (e.keyCode === KEY_M && KeyBindingUtil.isCtrlKeyCommand(e)) {
|
||||
if (e.keyCode === KeyCode.KEY_M && KeyBindingUtil.isCtrlKeyCommand(e)) {
|
||||
return 'toggle-mode';
|
||||
}
|
||||
|
||||
|
@ -723,6 +721,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
title={ this.state.isRichtextEnabled ? _t("Markdown is disabled") : _t("Markdown is enabled")}
|
||||
src={`img/button-md-${!this.state.isRichtextEnabled}.png`} />
|
||||
<Editor ref="editor"
|
||||
dir="auto"
|
||||
placeholder={this.props.placeholder}
|
||||
editorState={this.state.editorState}
|
||||
onChange={this.onEditorContentChanged}
|
||||
|
|
|
@ -29,7 +29,6 @@ var Markdown = require("../../../Markdown");
|
|||
|
||||
var TYPING_USER_TIMEOUT = 10000;
|
||||
var TYPING_SERVER_TIMEOUT = 30000;
|
||||
var MARKDOWN_ENABLED = true;
|
||||
|
||||
export function onSendMessageFailed(err, room) {
|
||||
// XXX: temporary logging to try to diagnose
|
||||
|
@ -77,7 +76,8 @@ export default React.createClass({
|
|||
|
||||
componentWillMount: function() {
|
||||
this.oldScrollHeight = 0;
|
||||
this.markdownEnabled = MARKDOWN_ENABLED;
|
||||
this.markdownEnabled = !UserSettingsStore.getSyncedSetting('disableMarkdown', false);
|
||||
|
||||
var self = this;
|
||||
this.sentHistory = {
|
||||
// The list of typed messages. Index 0 is more recent
|
||||
|
@ -461,7 +461,7 @@ export default React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<div className="mx_MessageComposer_input" onClick={ this.onInputClick }>
|
||||
<textarea autoFocus ref="textarea" rows="1" onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp} placeholder={this.props.placeholder}
|
||||
<textarea dir="auto" autoFocus ref="textarea" rows="1" onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp} placeholder={this.props.placeholder}
|
||||
onPaste={this._onPaste}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -18,8 +18,6 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ var sdk = require('../../../index');
|
|||
|
||||
var Velociraptor = require('../../../Velociraptor');
|
||||
require('../../../VelocityBounce');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
import DateUtils from '../../../DateUtils';
|
||||
|
||||
|
@ -169,8 +170,10 @@ module.exports = React.createClass({
|
|||
|
||||
let title;
|
||||
if (this.props.timestamp) {
|
||||
title = "Seen by " + this.props.member.userId + " at " +
|
||||
DateUtils.formatDate(new Date(this.props.timestamp));
|
||||
title = _t(
|
||||
"Seen by %(userName)s at %(dateTime)s",
|
||||
{userName: this.props.member.userId, dateTime: DateUtils.formatDate(new Date(this.props.timestamp))}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -213,7 +213,7 @@ module.exports = React.createClass({
|
|||
// don't display the search count until the search completes and
|
||||
// gives us a valid (possibly zero) searchCount.
|
||||
if (this.props.searchInfo && this.props.searchInfo.searchCount !== undefined && this.props.searchInfo.searchCount !== null) {
|
||||
searchStatus = <div className="mx_RoomHeader_searchStatus"> { _t("(~%(searchCount)s results)", { searchCount: this.props.searchInfo.searchCount }) }</div>;
|
||||
searchStatus = <div className="mx_RoomHeader_searchStatus"> { _t("(~%(count)s results)", { count: this.props.searchInfo.searchCount }) }</div>;
|
||||
}
|
||||
|
||||
// XXX: this is a bit inefficient - we could just compare room.name for 'Empty room'...
|
||||
|
@ -238,7 +238,7 @@ module.exports = React.createClass({
|
|||
const emojiTextClasses = classNames('mx_RoomHeader_nametext', { mx_RoomHeader_settingsHint: settingsHint });
|
||||
name =
|
||||
<div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}>
|
||||
<EmojiText element="div" className={emojiTextClasses} title={roomName}>{ roomName }</EmojiText>
|
||||
<EmojiText dir="auto" element="div" className={emojiTextClasses} title={roomName}>{ roomName }</EmojiText>
|
||||
{ searchStatus }
|
||||
</div>;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
if (topic) {
|
||||
topic_el = <div className="mx_RoomHeader_topic" ref="topic" title={ topic }>{ topic }</div>;
|
||||
topic_el = <div className="mx_RoomHeader_topic" ref="topic" title={ topic } dir="auto">{ topic }</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,7 @@ module.exports = React.createClass({
|
|||
var settings_button;
|
||||
if (this.props.onSettingsClick) {
|
||||
settings_button =
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title="Settings">
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
|
||||
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -30,7 +31,14 @@ var Rooms = require('../../../Rooms');
|
|||
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||
var Receipt = require('../../../utils/Receipt');
|
||||
|
||||
var HIDE_CONFERENCE_CHANS = true;
|
||||
const HIDE_CONFERENCE_CHANS = true;
|
||||
|
||||
const VERBS = {
|
||||
'm.favourite': 'favourite',
|
||||
'im.vector.fake.direct': 'tag direct chat',
|
||||
'im.vector.fake.recent': 'restore',
|
||||
'm.lowpriority': 'demote',
|
||||
};
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomList',
|
||||
|
@ -45,6 +53,7 @@ module.exports = React.createClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
isLoadingLeftRooms: false,
|
||||
totalRoomCount: null,
|
||||
lists: {},
|
||||
incomingCall: null,
|
||||
};
|
||||
|
@ -64,8 +73,14 @@ module.exports = React.createClass({
|
|||
cli.on("RoomMember.name", this.onRoomMemberName);
|
||||
cli.on("accountData", this.onAccountData);
|
||||
|
||||
var s = this.getRoomLists();
|
||||
this.setState(s);
|
||||
this.refreshRoomList();
|
||||
|
||||
// order of the sublists
|
||||
//this.listOrder = [];
|
||||
|
||||
// loop count to stop a stack overflow if the user keeps waggling the
|
||||
// mouse for >30s in a row, or if running under mocha
|
||||
this._delayedRefreshRoomListLoopCount = 0
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
|
@ -203,31 +218,33 @@ module.exports = React.createClass({
|
|||
}, 500),
|
||||
|
||||
refreshRoomList: function() {
|
||||
// console.log("DEBUG: Refresh room list delta=%s ms",
|
||||
// (!this._lastRefreshRoomListTs ? "-" : (Date.now() - this._lastRefreshRoomListTs))
|
||||
// );
|
||||
|
||||
// TODO: rather than bluntly regenerating and re-sorting everything
|
||||
// every time we see any kind of room change from the JS SDK
|
||||
// we could do incremental updates on our copy of the state
|
||||
// based on the room which has actually changed. This would stop
|
||||
// us re-rendering all the sublists every time anything changes anywhere
|
||||
// in the state of the client.
|
||||
this.setState(this.getRoomLists());
|
||||
// TODO: ideally we'd calculate this once at start, and then maintain
|
||||
// any changes to it incrementally, updating the appropriate sublists
|
||||
// as needed.
|
||||
// Alternatively we'd do something magical with Immutable.js or similar.
|
||||
const lists = this.getRoomLists();
|
||||
let totalRooms = 0;
|
||||
for (const l of Object.values(lists)) {
|
||||
totalRooms += l.length;
|
||||
}
|
||||
this.setState({
|
||||
lists: this.getRoomLists(),
|
||||
totalRoomCount: totalRooms,
|
||||
});
|
||||
|
||||
// this._lastRefreshRoomListTs = Date.now();
|
||||
},
|
||||
|
||||
getRoomLists: function() {
|
||||
var self = this;
|
||||
var s = { lists: {} };
|
||||
const lists = {};
|
||||
|
||||
s.lists["im.vector.fake.invite"] = [];
|
||||
s.lists["m.favourite"] = [];
|
||||
s.lists["im.vector.fake.recent"] = [];
|
||||
s.lists["im.vector.fake.direct"] = [];
|
||||
s.lists["m.lowpriority"] = [];
|
||||
s.lists["im.vector.fake.archived"] = [];
|
||||
lists["im.vector.fake.invite"] = [];
|
||||
lists["m.favourite"] = [];
|
||||
lists["im.vector.fake.recent"] = [];
|
||||
lists["im.vector.fake.direct"] = [];
|
||||
lists["m.lowpriority"] = [];
|
||||
lists["im.vector.fake.archived"] = [];
|
||||
|
||||
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
||||
|
||||
|
@ -241,7 +258,7 @@ module.exports = React.createClass({
|
|||
// ", prevMembership = " + me.events.member.getPrevContent().membership);
|
||||
|
||||
if (me.membership == "invite") {
|
||||
s.lists["im.vector.fake.invite"].push(room);
|
||||
lists["im.vector.fake.invite"].push(room);
|
||||
}
|
||||
else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) {
|
||||
// skip past this room & don't put it in any lists
|
||||
|
@ -255,66 +272,44 @@ module.exports = React.createClass({
|
|||
if (tagNames.length) {
|
||||
for (var i = 0; i < tagNames.length; i++) {
|
||||
var tagName = tagNames[i];
|
||||
s.lists[tagName] = s.lists[tagName] || [];
|
||||
s.lists[tagNames[i]].push(room);
|
||||
lists[tagName] = lists[tagName] || [];
|
||||
lists[tagName].push(room);
|
||||
}
|
||||
}
|
||||
else if (dmRoomMap.getUserIdForRoomId(room.roomId)) {
|
||||
// "Direct Message" rooms (that we're still in and that aren't otherwise tagged)
|
||||
s.lists["im.vector.fake.direct"].push(room);
|
||||
lists["im.vector.fake.direct"].push(room);
|
||||
}
|
||||
else {
|
||||
s.lists["im.vector.fake.recent"].push(room);
|
||||
lists["im.vector.fake.recent"].push(room);
|
||||
}
|
||||
}
|
||||
else if (me.membership === "leave") {
|
||||
s.lists["im.vector.fake.archived"].push(room);
|
||||
lists["im.vector.fake.archived"].push(room);
|
||||
}
|
||||
else {
|
||||
console.error("unrecognised membership: " + me.membership + " - this should never happen");
|
||||
}
|
||||
});
|
||||
|
||||
if (s.lists["im.vector.fake.direct"].length == 0 &&
|
||||
MatrixClientPeg.get().getAccountData('m.direct') === undefined &&
|
||||
!MatrixClientPeg.get().isGuest())
|
||||
{
|
||||
// scan through the 'recents' list for any rooms which look like DM rooms
|
||||
// and make them DM rooms
|
||||
const oldRecents = s.lists["im.vector.fake.recent"];
|
||||
s.lists["im.vector.fake.recent"] = [];
|
||||
|
||||
for (const room of oldRecents) {
|
||||
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||
|
||||
if (me && Rooms.looksLikeDirectMessageRoom(room, me)) {
|
||||
s.lists["im.vector.fake.direct"].push(room);
|
||||
} else {
|
||||
s.lists["im.vector.fake.recent"].push(room);
|
||||
}
|
||||
}
|
||||
|
||||
// save these new guessed DM rooms into the account data
|
||||
const newMDirectEvent = {};
|
||||
for (const room of s.lists["im.vector.fake.direct"]) {
|
||||
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||
const otherPerson = Rooms.getOnlyOtherMember(room, me);
|
||||
if (!otherPerson) continue;
|
||||
|
||||
const roomList = newMDirectEvent[otherPerson.userId] || [];
|
||||
roomList.push(room.roomId);
|
||||
newMDirectEvent[otherPerson.userId] = roomList;
|
||||
}
|
||||
|
||||
// if this fails, fine, we'll just do the same thing next time we get the room lists
|
||||
MatrixClientPeg.get().setAccountData('m.direct', newMDirectEvent).done();
|
||||
}
|
||||
|
||||
//console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]);
|
||||
|
||||
// we actually apply the sorting to this when receiving the prop in RoomSubLists.
|
||||
|
||||
return s;
|
||||
// we'll need this when we get to iterating through lists programatically - e.g. ctrl-shift-up/down
|
||||
/*
|
||||
this.listOrder = [
|
||||
"im.vector.fake.invite",
|
||||
"m.favourite",
|
||||
"im.vector.fake.recent",
|
||||
"im.vector.fake.direct",
|
||||
Object.keys(otherTagNames).filter(tagName=>{
|
||||
return (!tagName.match(/^m\.(favourite|lowpriority)$/));
|
||||
}).sort(),
|
||||
"m.lowpriority",
|
||||
"im.vector.fake.archived"
|
||||
];
|
||||
*/
|
||||
|
||||
return lists;
|
||||
},
|
||||
|
||||
_getScrollNode: function() {
|
||||
|
@ -468,6 +463,62 @@ module.exports = React.createClass({
|
|||
this.refs.gemscroll.forceUpdate();
|
||||
},
|
||||
|
||||
_getEmptyContent: function(section) {
|
||||
const RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
|
||||
|
||||
if (this.props.collapsed) {
|
||||
return <RoomDropTarget label="" />;
|
||||
}
|
||||
|
||||
const StartChatButton = sdk.getComponent('elements.StartChatButton');
|
||||
const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
|
||||
const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
|
||||
|
||||
const TintableSvg = sdk.getComponent('elements.TintableSvg');
|
||||
switch (section) {
|
||||
case 'im.vector.fake.direct':
|
||||
return <div className="mx_RoomList_emptySubListTip">
|
||||
Press
|
||||
<StartChatButton size="16" callout={true}/>
|
||||
to start a chat with someone
|
||||
</div>;
|
||||
case 'im.vector.fake.recent':
|
||||
return <div className="mx_RoomList_emptySubListTip">
|
||||
You're not in any rooms yet! Press
|
||||
<CreateRoomButton size="16" callout={true}/>
|
||||
to make a room or
|
||||
<RoomDirectoryButton size="16" callout={true}/>
|
||||
to browse the directory
|
||||
</div>;
|
||||
}
|
||||
|
||||
// We don't want to display drop targets if there are no room tiles to drag'n'drop
|
||||
if (this.state.totalRoomCount === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section);
|
||||
|
||||
return <RoomDropTarget label={labelText} />;
|
||||
},
|
||||
|
||||
_getHeaderItems: function(section) {
|
||||
const StartChatButton = sdk.getComponent('elements.StartChatButton');
|
||||
const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
|
||||
const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
|
||||
switch (section) {
|
||||
case 'im.vector.fake.direct':
|
||||
return <span className="mx_RoomList_headerButtons">
|
||||
<StartChatButton size="16" />
|
||||
</span>;
|
||||
case 'im.vector.fake.recent':
|
||||
return <span className="mx_RoomList_headerButtons">
|
||||
<RoomDirectoryButton size="16" />
|
||||
<CreateRoomButton size="16" />
|
||||
</span>;
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var RoomSubList = sdk.getComponent('structures.RoomSubList');
|
||||
var self = this;
|
||||
|
@ -489,7 +540,7 @@ module.exports = React.createClass({
|
|||
<RoomSubList list={ self.state.lists['m.favourite'] }
|
||||
label={ _t('Favourites') }
|
||||
tagName="m.favourite"
|
||||
verb={ _t('to favourite') }
|
||||
emptyContent={this._getEmptyContent('m.favourite')}
|
||||
editable={ true }
|
||||
order="manual"
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
|
@ -502,7 +553,8 @@ module.exports = React.createClass({
|
|||
<RoomSubList list={ self.state.lists['im.vector.fake.direct'] }
|
||||
label={ _t('People') }
|
||||
tagName="im.vector.fake.direct"
|
||||
verb={ _t('to tag direct chat') }
|
||||
emptyContent={this._getEmptyContent('im.vector.fake.direct')}
|
||||
headerItems={this._getHeaderItems('im.vector.fake.direct')}
|
||||
editable={ true }
|
||||
order="recent"
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
|
@ -516,7 +568,8 @@ module.exports = React.createClass({
|
|||
<RoomSubList list={ self.state.lists['im.vector.fake.recent'] }
|
||||
label={ _t('Rooms') }
|
||||
editable={ true }
|
||||
verb={ _t('to restore') }
|
||||
emptyContent={this._getEmptyContent('im.vector.fake.recent')}
|
||||
headerItems={this._getHeaderItems('im.vector.fake.recent')}
|
||||
order="recent"
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
incomingCall={ self.state.incomingCall }
|
||||
|
@ -525,13 +578,13 @@ module.exports = React.createClass({
|
|||
onHeaderClick={ self.onSubListHeaderClick }
|
||||
onShowMoreRooms={ self.onShowMoreRooms } />
|
||||
|
||||
{ Object.keys(self.state.lists).map(function(tagName) {
|
||||
{ Object.keys(self.state.lists).map((tagName) => {
|
||||
if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) {
|
||||
return <RoomSubList list={ self.state.lists[tagName] }
|
||||
key={ tagName }
|
||||
label={ tagName }
|
||||
tagName={ tagName }
|
||||
verb={ _t('to tag as %(tagName)s', {tagName: tagName}) }
|
||||
emptyContent={this._getEmptyContent(tagName)}
|
||||
editable={ true }
|
||||
order="manual"
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
|
@ -547,7 +600,7 @@ module.exports = React.createClass({
|
|||
<RoomSubList list={ self.state.lists['m.lowpriority'] }
|
||||
label={ _t('Low priority') }
|
||||
tagName="m.lowpriority"
|
||||
verb={ _t('to demote') }
|
||||
emptyContent={this._getEmptyContent('m.lowpriority')}
|
||||
editable={ true }
|
||||
order="recent"
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
|
|
|
@ -19,6 +19,7 @@ limitations under the License.
|
|||
var React = require('react');
|
||||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomNameEditor',
|
||||
|
@ -35,8 +36,8 @@ module.exports = React.createClass({
|
|||
|
||||
this._initialName = name ? name.getContent().name : '';
|
||||
|
||||
this._placeholderName = "Unnamed Room";
|
||||
if (defaultName && defaultName !== 'Empty room') {
|
||||
this._placeholderName = _t("Unnamed Room");
|
||||
if (defaultName && defaultName !== 'Empty room') { // default name from JS SDK, needs no translation as we don't ever show it.
|
||||
this._placeholderName += " (" + defaultName + ")";
|
||||
}
|
||||
},
|
||||
|
@ -55,9 +56,9 @@ module.exports = React.createClass({
|
|||
placeholderClassName="mx_RoomHeader_placeholder"
|
||||
placeholder={ this._placeholderName }
|
||||
blurToCancel={ false }
|
||||
initialValue={ this._initialName }/>
|
||||
initialValue={ this._initialName }
|
||||
dir="auto" />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ var React = require('react');
|
|||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomPreviewBar',
|
||||
|
@ -84,7 +84,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_roomNameElement: function(fallback) {
|
||||
fallback = fallback || 'a room';
|
||||
fallback = fallback || _t('a room');
|
||||
const name = this.props.room ? this.props.room.name : (this.props.room_alias || "");
|
||||
return name ? name : fallback;
|
||||
},
|
||||
|
@ -114,8 +114,7 @@ module.exports = React.createClass({
|
|||
if (this.props.invitedEmail) {
|
||||
if (this.state.threePidFetchError) {
|
||||
emailMatchBlock = <div className="error">
|
||||
Unable to ascertain that the address this invite was
|
||||
sent to matches one associated with your account.
|
||||
{_t("Unable to ascertain that the address this invite was sent to matches one associated with your account.")}
|
||||
</div>;
|
||||
} else if (this.state.invitedEmailMxid != MatrixClientPeg.get().credentials.userId) {
|
||||
emailMatchBlock =
|
||||
|
@ -124,28 +123,35 @@ module.exports = React.createClass({
|
|||
<img src="img/warning.svg" width="24" height="23" title= "/!\\" alt="/!\\" />
|
||||
</div>
|
||||
<div className="mx_RoomPreviewBar_warningText">
|
||||
This invitation was sent to <b><span className="email">{this.props.invitedEmail}</span></b>, which is not associated with this account.<br/>
|
||||
You may wish to login with a different account, or add this email to this account.
|
||||
{_t("This invitation was sent to an email address which is not associated with this account:")}
|
||||
<b><span className="email">{this.props.invitedEmail}</span></b>
|
||||
<br/>
|
||||
{_t("You may wish to login with a different account, or add this email to this account.")}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
// TODO: find a way to respect HTML in counterpart!
|
||||
joinBlock = (
|
||||
<div>
|
||||
<div className="mx_RoomPreviewBar_invite_text">
|
||||
{ _t('You have been invited to join this room by %(inviterName)s', {inviterName: this.props.inviterName}) }
|
||||
</div>
|
||||
<div className="mx_RoomPreviewBar_join_text">
|
||||
{ _t('Would you like to') } <a onClick={ this.props.onJoinClick }>{ _t('accept') }</a> { _t('or') } <a onClick={ this.props.onRejectClick }>{ _t('decline') }</a> { _t('this invitation?') }
|
||||
{ _tJsx(
|
||||
'Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?',
|
||||
[/<acceptText>(.*?)<\/acceptText>/, /<declineText>(.*?)<\/declineText>/],
|
||||
[
|
||||
(sub) => <a onClick={ this.props.onJoinClick }>{sub}</a>,
|
||||
(sub) => <a onClick={ this.props.onRejectClick }>{sub}</a>
|
||||
]
|
||||
)}
|
||||
</div>
|
||||
{emailMatchBlock}
|
||||
</div>
|
||||
);
|
||||
|
||||
} else if (kicked || banned) {
|
||||
const verb = kicked ? 'kicked' : 'banned';
|
||||
const roomName = this._roomNameElement('this room');
|
||||
const roomName = this._roomNameElement(_t('This room'));
|
||||
const kickerMember = this.props.room.currentState.getMember(
|
||||
myMember.events.member.getSender()
|
||||
);
|
||||
|
@ -153,29 +159,39 @@ module.exports = React.createClass({
|
|||
kickerMember.name : myMember.events.member.getSender();
|
||||
let reason;
|
||||
if (myMember.events.member.getContent().reason) {
|
||||
reason = <div>Reason: {myMember.events.member.getContent().reason}</div>
|
||||
reason = <div>{_t("Reason: %(reasonText)s", {reasonText: myMember.events.member.getContent().reason})}</div>
|
||||
}
|
||||
let rejoinBlock;
|
||||
if (!banned) {
|
||||
rejoinBlock = <div><a onClick={ this.props.onJoinClick }><b>Rejoin</b></a></div>;
|
||||
rejoinBlock = <div><a onClick={ this.props.onJoinClick }><b>{_t("Rejoin")}</b></a></div>;
|
||||
}
|
||||
|
||||
let actionText;
|
||||
if (kicked) {
|
||||
actionText = _t("You have been kicked from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
||||
}
|
||||
else if (banned) {
|
||||
actionText = _t("You have been banned from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
||||
} // no other options possible due to the kicked || banned check above.
|
||||
|
||||
joinBlock = (
|
||||
<div>
|
||||
<div className="mx_RoomPreviewBar_join_text">
|
||||
You have been {verb} from {roomName} by {kickerName}.<br />
|
||||
{actionText}
|
||||
<br />
|
||||
{reason}
|
||||
{rejoinBlock}
|
||||
<a onClick={ this.props.onForgetClick }><b>Forget</b></a>
|
||||
<a onClick={ this.props.onForgetClick }><b>{_t("Forget room")}</b></a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.error) {
|
||||
var name = this.props.roomAlias || "This room";
|
||||
var name = this.props.roomAlias || _t("This room");
|
||||
var error;
|
||||
if (this.props.error.errcode == 'M_NOT_FOUND') {
|
||||
error = name + " does not exist";
|
||||
error = _t("%(roomName)s does not exist.", {roomName: name});
|
||||
} else {
|
||||
error = name + " is not accessible at this time";
|
||||
error = _t("%(roomName)s is not accessible at this time.", {roomName: name});
|
||||
}
|
||||
joinBlock = (
|
||||
<div>
|
||||
|
@ -189,8 +205,12 @@ module.exports = React.createClass({
|
|||
joinBlock = (
|
||||
<div>
|
||||
<div className="mx_RoomPreviewBar_join_text">
|
||||
{ _t('You are trying to access %(roomName)s', {roomName: name}) }.<br/>
|
||||
<a onClick={ this.props.onJoinClick }><b>{ _t('Click here') }</b></a> { _t('to join the discussion') }!
|
||||
{ _t('You are trying to access %(roomName)s.', {roomName: name}) }
|
||||
<br/>
|
||||
{ _tJsx("<a>Click here</a> to join the discussion!",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => <a onClick={ this.props.onJoinClick }><b>{sub}</b></a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
|
||||
import q from 'q';
|
||||
import React from 'react';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import sdk from '../../../index';
|
||||
|
@ -46,7 +46,7 @@ const BannedUser = React.createClass({
|
|||
const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog");
|
||||
Modal.createDialog(ConfirmUserActionDialog, {
|
||||
member: this.props.member,
|
||||
action: 'Unban',
|
||||
action: _t('Unban'),
|
||||
danger: false,
|
||||
onFinished: (proceed) => {
|
||||
if (!proceed) return;
|
||||
|
@ -597,7 +597,7 @@ module.exports = React.createClass({
|
|||
? <img className="mx_RoomSettings_e2eIcon" src="img/e2e-verified.svg" width="10" height="12" />
|
||||
: <img className="mx_RoomSettings_e2eIcon" src="img/e2e-unencrypted.svg" width="12" height="12" />
|
||||
}
|
||||
{ isEncrypted ? "Encryption is enabled in this room" : "Encryption is not enabled in this room" }.
|
||||
{ isEncrypted ? _t("Encryption is enabled in this room") : _t("Encryption is not enabled in this room") }.
|
||||
</label>
|
||||
{ settings }
|
||||
</div>
|
||||
|
@ -653,7 +653,7 @@ module.exports = React.createClass({
|
|||
{Object.keys(user_levels).map(function(user, i) {
|
||||
return (
|
||||
<li className="mx_RoomSettings_userLevel" key={user}>
|
||||
{ user } { _t('is a') } <PowerSelector value={ user_levels[user] } disabled={true}/>
|
||||
{ _t("%(user)s is a", {user: user}) } <PowerSelector value={ user_levels[user] } disabled={true}/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
@ -754,7 +754,11 @@ module.exports = React.createClass({
|
|||
if (this.state.join_rule === "public" && aliasCount == 0) {
|
||||
addressWarning =
|
||||
<div className="mx_RoomSettings_warning">
|
||||
{ _t('To link to a room it must have') } <a href="#addresses"> { _t('an address') }</a>.
|
||||
{ _tJsx(
|
||||
'To link to a room it must have <a>an address</a>.',
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => <a href="#addresses">{sub}</a>
|
||||
)}
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
|
|
@ -224,13 +224,13 @@ module.exports = React.createClass({
|
|||
if (this.props.selected) {
|
||||
let nameSelected = <EmojiText>{name}</EmojiText>;
|
||||
|
||||
label = <div title={ name } className={ nameClasses }>{ nameSelected }</div>;
|
||||
label = <div title={ name } className={ nameClasses } dir="auto">{ nameSelected }</div>;
|
||||
} else {
|
||||
label = <EmojiText element="div" title={ name } className={ nameClasses }>{name}</EmojiText>;
|
||||
label = <EmojiText element="div" title={ name } className={ nameClasses } dir="auto">{name}</EmojiText>;
|
||||
}
|
||||
} else if (this.state.hover) {
|
||||
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||
tooltip = <RoomTooltip className="mx_RoomTile_tooltip" room={this.props.room} />;
|
||||
tooltip = <RoomTooltip className="mx_RoomTile_tooltip" room={this.props.room} dir="auto" />;
|
||||
}
|
||||
|
||||
//var incomingCallBox;
|
||||
|
|
|
@ -46,7 +46,8 @@ module.exports = React.createClass({
|
|||
placeholderClassName="mx_RoomHeader_placeholder"
|
||||
placeholder={_t("Add a topic")}
|
||||
blurToCancel={ false }
|
||||
initialValue={ this._initialTopic }/>
|
||||
initialValue={ this._initialTopic }
|
||||
dir="auto" />
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -20,6 +20,7 @@ import React from 'react';
|
|||
import dis from '../../../dispatcher';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
// cancel button which is shared between room header and simple room header
|
||||
export function CancelButton(props) {
|
||||
|
@ -28,7 +29,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="Cancel"/>
|
||||
width="18" height="18" alt={_t("Cancel")}/>
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
<img className="mx_TopUnreadMessagesBar_close mx_filterFlipColor"
|
||||
src="img/cancel.svg" width="18" height="18"
|
||||
alt="Close" title="Close"
|
||||
alt={_t("Close")} title={_t("Close")}
|
||||
onClick={this.props.onCloseClick} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -165,7 +165,7 @@ export default WithMatrixClient(React.createClass({
|
|||
</div>
|
||||
</div>
|
||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||
<input type="image" value="Add" src="img/plus.svg" width="14" height="14" />
|
||||
<input type="image" value={_t("Add")} src="img/plus.svg" width="14" height="14" />
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
var React = require('react');
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
var sdk = require('../../../index');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ChangeAvatar',
|
||||
|
@ -105,7 +106,7 @@ module.exports = React.createClass({
|
|||
|
||||
onError: function(error) {
|
||||
this.setState({
|
||||
errorText: "Failed to upload profile picture!"
|
||||
errorText: _t("Failed to upload profile picture!")
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -127,7 +128,7 @@ module.exports = React.createClass({
|
|||
if (this.props.showUploadSection) {
|
||||
uploadSection = (
|
||||
<div className={this.props.className}>
|
||||
Upload new:
|
||||
{_t("Upload new:")}
|
||||
<input type="file" accept="image/*" onChange={this.onFileSelected}/>
|
||||
{this.state.errorText}
|
||||
</div>
|
||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||
var React = require('react');
|
||||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ChangeDisplayName',
|
||||
|
@ -52,7 +53,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<EditableTextContainer
|
||||
getInitialValue={this._getDisplayName}
|
||||
placeholder="No display name"
|
||||
placeholder={_t("No display name")}
|
||||
blurToSubmit={true}
|
||||
onSubmit={this._changeDisplayName} />
|
||||
);
|
||||
|
|
|
@ -23,6 +23,8 @@ var sdk = require("../../../index");
|
|||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
import sessionStore from '../../../stores/SessionStore';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ChangePassword',
|
||||
propTypes: {
|
||||
|
@ -32,7 +34,10 @@ module.exports = React.createClass({
|
|||
rowClassName: React.PropTypes.string,
|
||||
rowLabelClassName: React.PropTypes.string,
|
||||
rowInputClassName: React.PropTypes.string,
|
||||
buttonClassName: React.PropTypes.string
|
||||
buttonClassName: React.PropTypes.string,
|
||||
confirm: React.PropTypes.bool,
|
||||
// Whether to autoFocus the new password input
|
||||
autoFocusNewPasswordInput: React.PropTypes.bool,
|
||||
},
|
||||
|
||||
Phases: {
|
||||
|
@ -48,27 +53,55 @@ module.exports = React.createClass({
|
|||
onCheckPassword: function(oldPass, newPass, confirmPass) {
|
||||
if (newPass !== confirmPass) {
|
||||
return {
|
||||
error: _t("New passwords don't match") + "."
|
||||
error: _t("New passwords don't match")
|
||||
};
|
||||
} else if (!newPass || newPass.length === 0) {
|
||||
return {
|
||||
error: _t("Passwords can't be empty")
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
confirm: true,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
phase: this.Phases.Edit
|
||||
phase: this.Phases.Edit,
|
||||
cachedPassword: null,
|
||||
};
|
||||
},
|
||||
|
||||
changePassword: function(old_password, new_password) {
|
||||
var cli = MatrixClientPeg.get();
|
||||
componentWillMount: function() {
|
||||
this._sessionStore = sessionStore;
|
||||
this._sessionStoreToken = this._sessionStore.addListener(
|
||||
this._setStateFromSessionStore,
|
||||
);
|
||||
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
this._setStateFromSessionStore();
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
if (this._sessionStoreToken) {
|
||||
this._sessionStoreToken.remove();
|
||||
}
|
||||
},
|
||||
|
||||
_setStateFromSessionStore: function() {
|
||||
this.setState({
|
||||
cachedPassword: this._sessionStore.getCachedPassword(),
|
||||
});
|
||||
},
|
||||
|
||||
changePassword: function(oldPassword, newPassword) {
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
if (!this.props.confirm) {
|
||||
this._changePassword(cli, oldPassword, newPassword);
|
||||
return;
|
||||
}
|
||||
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: _t("Warning!"),
|
||||
description:
|
||||
|
@ -89,31 +122,34 @@ module.exports = React.createClass({
|
|||
],
|
||||
onFinished: (confirmed) => {
|
||||
if (confirmed) {
|
||||
var authDict = {
|
||||
type: 'm.login.password',
|
||||
user: cli.credentials.userId,
|
||||
password: old_password
|
||||
};
|
||||
|
||||
this.setState({
|
||||
phase: this.Phases.Uploading
|
||||
});
|
||||
|
||||
var self = this;
|
||||
cli.setPassword(authDict, new_password).then(function() {
|
||||
self.props.onFinished();
|
||||
}, function(err) {
|
||||
self.props.onError(err);
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
phase: self.Phases.Edit
|
||||
});
|
||||
}).done();
|
||||
this._changePassword(cli, oldPassword, newPassword);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
_changePassword: function(cli, oldPassword, newPassword) {
|
||||
const authDict = {
|
||||
type: 'm.login.password',
|
||||
user: cli.credentials.userId,
|
||||
password: oldPassword,
|
||||
};
|
||||
|
||||
this.setState({
|
||||
phase: this.Phases.Uploading,
|
||||
});
|
||||
|
||||
cli.setPassword(authDict, newPassword).then(() => {
|
||||
this.props.onFinished();
|
||||
}, (err) => {
|
||||
this.props.onError(err);
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
phase: this.Phases.Edit,
|
||||
});
|
||||
}).done();
|
||||
},
|
||||
|
||||
_onExportE2eKeysClicked: function() {
|
||||
Modal.createDialogAsync(
|
||||
(cb) => {
|
||||
|
@ -124,47 +160,53 @@ module.exports = React.createClass({
|
|||
matrixClient: MatrixClientPeg.get(),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
onClickChange: function() {
|
||||
var old_password = this.refs.old_input.value;
|
||||
var new_password = this.refs.new_input.value;
|
||||
var confirm_password = this.refs.confirm_input.value;
|
||||
var err = this.props.onCheckPassword(
|
||||
old_password, new_password, confirm_password
|
||||
const oldPassword = this.state.cachedPassword || this.refs.old_input.value;
|
||||
const newPassword = this.refs.new_input.value;
|
||||
const confirmPassword = this.refs.confirm_input.value;
|
||||
const err = this.props.onCheckPassword(
|
||||
oldPassword, newPassword, confirmPassword,
|
||||
);
|
||||
if (err) {
|
||||
this.props.onError(err);
|
||||
}
|
||||
else {
|
||||
this.changePassword(old_password, new_password);
|
||||
} else {
|
||||
this.changePassword(oldPassword, newPassword);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var rowClassName = this.props.rowClassName;
|
||||
var rowLabelClassName = this.props.rowLabelClassName;
|
||||
var rowInputClassName = this.props.rowInputClassName;
|
||||
var buttonClassName = this.props.buttonClassName;
|
||||
const rowClassName = this.props.rowClassName;
|
||||
const rowLabelClassName = this.props.rowLabelClassName;
|
||||
const rowInputClassName = this.props.rowInputClassName;
|
||||
const buttonClassName = this.props.buttonClassName;
|
||||
|
||||
let currentPassword = null;
|
||||
if (!this.state.cachedPassword) {
|
||||
currentPassword = <div className={rowClassName}>
|
||||
<div className={rowLabelClassName}>
|
||||
<label htmlFor="passwordold">Current password</label>
|
||||
</div>
|
||||
<div className={rowInputClassName}>
|
||||
<input id="passwordold" type="password" ref="old_input" />
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
switch (this.state.phase) {
|
||||
case this.Phases.Edit:
|
||||
const passwordLabel = this.state.cachedPassword ?
|
||||
_t('Password') : _t('New Password');
|
||||
return (
|
||||
<div className={this.props.className}>
|
||||
{ currentPassword }
|
||||
<div className={rowClassName}>
|
||||
<div className={rowLabelClassName}>
|
||||
<label htmlFor="passwordold">{ _t('Current password') }</label>
|
||||
<label htmlFor="password1">{ passwordLabel }</label>
|
||||
</div>
|
||||
<div className={rowInputClassName}>
|
||||
<input id="passwordold" type="password" ref="old_input" />
|
||||
</div>
|
||||
</div>
|
||||
<div className={rowClassName}>
|
||||
<div className={rowLabelClassName}>
|
||||
<label htmlFor="password1">{ _t('New password') }</label>
|
||||
</div>
|
||||
<div className={rowInputClassName}>
|
||||
<input id="password1" type="password" ref="new_input" />
|
||||
<input id="password1" type="password" ref="new_input" autoFocus={this.props.autoFocusNewPasswordInput} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={rowClassName}>
|
||||
|
@ -176,7 +218,8 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
</div>
|
||||
<AccessibleButton className={buttonClassName}
|
||||
onClick={this.onClickChange}>
|
||||
onClick={this.onClickChange}
|
||||
element="button">
|
||||
{ _t('Change Password') }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
|
|
|
@ -19,6 +19,7 @@ import classNames from 'classnames';
|
|||
|
||||
import sdk from '../../../index';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
||||
export default class DevicesPanel extends React.Component {
|
||||
|
@ -54,10 +55,10 @@ export default class DevicesPanel extends React.Component {
|
|||
var errtxt;
|
||||
if (error.httpStatus == 404) {
|
||||
// 404 probably means the HS doesn't yet support the API.
|
||||
errtxt = "Your home server does not support device management.";
|
||||
errtxt = _t("Your home server does not support device management.");
|
||||
} else {
|
||||
console.error("Error loading devices:", error);
|
||||
errtxt = "Unable to load device list.";
|
||||
errtxt = _t("Unable to load device list");
|
||||
}
|
||||
this.setState({deviceLoadError: errtxt});
|
||||
}
|
||||
|
@ -127,9 +128,9 @@ export default class DevicesPanel extends React.Component {
|
|||
return (
|
||||
<div className={classes}>
|
||||
<div className="mx_DevicesPanel_header">
|
||||
<div className="mx_DevicesPanel_deviceId">ID</div>
|
||||
<div className="mx_DevicesPanel_deviceName">Name</div>
|
||||
<div className="mx_DevicesPanel_deviceLastSeen">Last seen</div>
|
||||
<div className="mx_DevicesPanel_deviceId">{_t("Device ID")}</div>
|
||||
<div className="mx_DevicesPanel_deviceName">{_t("Device Name")}</div>
|
||||
<div className="mx_DevicesPanel_deviceLastSeen">{_t("Last seen")}</div>
|
||||
<div className="mx_DevicesPanel_deviceButtons"></div>
|
||||
</div>
|
||||
{devices.map(this._renderDevice)}
|
||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||
var React = require("react");
|
||||
var Notifier = require("../../../Notifier");
|
||||
var dis = require("../../../dispatcher");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'EnableNotificationsButton',
|
||||
|
@ -60,13 +61,13 @@ module.exports = React.createClass({
|
|||
if (this.enabled()) {
|
||||
return (
|
||||
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>
|
||||
Disable Notifications
|
||||
{_t("Disable Notifications")}
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>
|
||||
Enable Notifications
|
||||
{_t("Enable Notifications")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ var dis = require("../../../dispatcher");
|
|||
var CallHandler = require("../../../CallHandler");
|
||||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'CallView',
|
||||
|
@ -130,7 +131,11 @@ module.exports = React.createClass({
|
|||
var voice;
|
||||
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
||||
var callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
||||
voice = <div className="mx_CallView_voice" onClick={ this.props.onClick }>Active call ({ callRoom.name })</div>;
|
||||
voice = (
|
||||
<div className="mx_CallView_voice" onClick={ this.props.onClick }>
|
||||
{_t("Active call (%(roomName)s)", {roomName: callRoom.name})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -17,6 +17,7 @@ var React = require('react');
|
|||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var dis = require("../../../dispatcher");
|
||||
var CallHandler = require("../../../CallHandler");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'IncomingCallBox',
|
||||
|
@ -45,23 +46,36 @@ module.exports = React.createClass({
|
|||
room = MatrixClientPeg.get().getRoom(this.props.incomingCall.roomId);
|
||||
}
|
||||
|
||||
var caller = room ? room.name : "unknown";
|
||||
var caller = room ? room.name : _t("unknown caller");
|
||||
|
||||
let incomingCallText = null;
|
||||
if (this.props.incomingCall) {
|
||||
if (this.props.incomingCall.type === "voice") {
|
||||
incomingCallText = _t("Incoming voice call from %(name)s", {name: caller});
|
||||
}
|
||||
else if (this.props.incomingCall.type === "video") {
|
||||
incomingCallText = _t("Incoming video call from %(name)s", {name: caller});
|
||||
}
|
||||
else {
|
||||
incomingCallText = _t("Incoming call from %(name)s", {name: caller});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<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">
|
||||
Incoming { this.props.incomingCall ? this.props.incomingCall.type : '' } call from { caller }
|
||||
{incomingCallText}
|
||||
</div>
|
||||
<div className="mx_IncomingCallBox_buttons">
|
||||
<div className="mx_IncomingCallBox_buttons_cell">
|
||||
<div className="mx_IncomingCallBox_buttons_decline" onClick={this.onRejectClick}>
|
||||
Decline
|
||||
{_t("Decline")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_IncomingCallBox_buttons_cell">
|
||||
<div className="mx_IncomingCallBox_buttons_accept" onClick={this.onAnswerClick}>
|
||||
Accept
|
||||
{_t("Accept")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -37,17 +37,11 @@ function createRoom(opts) {
|
|||
opts = opts || {};
|
||||
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
if (client.isGuest()) {
|
||||
setTimeout(()=>{
|
||||
Modal.createDialog(NeedToRegisterDialog, {
|
||||
title: _t('Please Register'),
|
||||
description: _t('Guest users can\'t create new rooms. Please register to create room and start a chat.')
|
||||
});
|
||||
}, 0);
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
return q(null);
|
||||
}
|
||||
|
||||
|
@ -64,6 +58,11 @@ function createRoom(opts) {
|
|||
createOpts.is_direct = true;
|
||||
}
|
||||
|
||||
// By default, view the room after creating it
|
||||
if (opts.andView === undefined) {
|
||||
opts.andView = true;
|
||||
}
|
||||
|
||||
// Allow guests by default since the room is private and they'd
|
||||
// need an invite. This means clicking on a 3pid invite email can
|
||||
// actually drop you right in to a chat.
|
||||
|
@ -97,10 +96,12 @@ function createRoom(opts) {
|
|||
// room has been created, so we race here with the client knowing that
|
||||
// the room exists, causing things like
|
||||
// https://github.com/vector-im/vector-web/issues/1813
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId
|
||||
});
|
||||
if (opts.andView) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
});
|
||||
}
|
||||
return roomId;
|
||||
}, function(err) {
|
||||
console.error("Failed to create room " + roomId + " " + err);
|
||||
|
|
7
src/i18n/strings/ar.json
Normal file
7
src/i18n/strings/ar.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"ar-iq": "العربية",
|
||||
"Continue": "استمر",
|
||||
"Username available": "اسم المستخدم متاح",
|
||||
"Username not available": "الإسم المستخدم غير موجود",
|
||||
"Something went wrong!": "هناك خطأ ما!"
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"Filter room members": "Raum Benutzer filtern",
|
||||
"Filter room members": "Raum-Mitglieder filtern",
|
||||
"You have no visible notifications": "Du hast keine sichtbaren Benachrichtigungen",
|
||||
"Invites": "Einladungen",
|
||||
"Favourites": "Favoriten",
|
||||
"People": "Direkt-Chats",
|
||||
"Rooms": "Räume",
|
||||
"Low priority": "Niedrige Priorität",
|
||||
"Historical": "Historisch",
|
||||
"Historical": "Archiv",
|
||||
"New passwords must match each other.": "Die neuen Passwörter müssen identisch sein.",
|
||||
"A new password must be entered.": "Es muss ein neues Passwort eingegeben werden.",
|
||||
"The email address linked to your account must be entered.": "Es muss die Email-Adresse eingeben werden, welche zum Account gehört.",
|
||||
|
@ -42,12 +42,12 @@
|
|||
"Commands": "Kommandos",
|
||||
"Emoji": "Emoji",
|
||||
"Sorry, this homeserver is using a login which is not recognised ": "Entschuldigung, dieser Homeserver nutzt eine Anmeldetechnik, die nicht bekannt ist ",
|
||||
"Login as guest": "Anmelden als Gast",
|
||||
"Login as guest": "Als Gast anmelden",
|
||||
"Return to app": "Zurück zur Anwendung",
|
||||
"Sign in": "Anmelden",
|
||||
"Create a new account": "Erstelle einen neuen Benutzer",
|
||||
"Send an encrypted message": "Eine verschlüsselte Nachricht senden",
|
||||
"Send a message (unencrypted)": "Sende eine Nachricht (unverschlüsselt)",
|
||||
"Send an encrypted message": "Verschlüsselte Nachricht senden",
|
||||
"Send a message (unencrypted)": "Nachricht senden (unverschlüsselt)",
|
||||
"Warning!": "Warnung!",
|
||||
"Direct Chat": "Privater Chat",
|
||||
"Error": "Fehler",
|
||||
|
@ -56,7 +56,7 @@
|
|||
"accepted the invitation for": "Akzeptierte die Einladung für",
|
||||
"Add email address": "E-Mail-Adresse hinzufügen",
|
||||
"Advanced": "Erweitert",
|
||||
"all room members, from the point they joined": "Alle Raum-Mitglieder - seitdem sie beigetreten sind",
|
||||
"all room members, from the point they joined": "Alle Raum-Mitglieder, ab dem Zeitpunkt, an dem sie beigetreten sind",
|
||||
"and": "und",
|
||||
"An email has been sent to": "Eine E-Mail wurde gesendet an",
|
||||
"anyone": "Jeder",
|
||||
|
@ -73,22 +73,22 @@
|
|||
"changed their profile picture": "änderte sein Profilbild",
|
||||
"changed the room name to": "änderte den Raumnamen zu",
|
||||
"changed the topic to": "änderte das Thema zu",
|
||||
"Changes to who can read history will only apply to future messages in this room": "Änderungen bzgl. wer die Historie lesen kann betrifft nur zukünftige Nachrichten in diesem Raum",
|
||||
"Clear Cache and Reload": "Leere Cache und lade neu",
|
||||
"Click here": "Klicke hier",
|
||||
"Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum",
|
||||
"Clear Cache and Reload": "Cache leeren und neu laden",
|
||||
"Click here": "Hier klicken,",
|
||||
"Confirm your new password": "Neues Passwort bestätigen",
|
||||
"Continue": "Fortfahren",
|
||||
"Create an account": "Erstelle einen Account",
|
||||
"Create Room": "Raum erstellen",
|
||||
"Cryptography": "Kryptografie",
|
||||
"Cryptography": "Verschlüsselung",
|
||||
"Deactivate Account": "Account deaktivieren",
|
||||
"Deactivate my account": "Deaktiviere meinen Account",
|
||||
"Deactivate my account": "Meinen Account deaktivieren",
|
||||
"decline": "Ablehnen",
|
||||
"Devices will not yet be able to decrypt history from before they joined the room": "Geräte werden nicht in der Lage sein, den Chatverlauf vor dem Betreten des Raumes zu entschlüsseln",
|
||||
"Display name": "Anzeigename",
|
||||
"Email Address": "E-Mail-Adresse",
|
||||
"Email, name or matrix ID": "E-Mail, Name oder Matrix-ID",
|
||||
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Verschlüsselte Nachrichten werden an Clients nicht sichtbar sein, die Verschlüsselung noch nicht implementiert haben",
|
||||
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Verschlüsselte Nachrichten werden nicht in Matrix-Clients sichtbar sein, die die Verschlüsselung noch nicht implementiert haben",
|
||||
"Encrypted room": "Verschlüsselter Raum",
|
||||
"Encryption is enabled in this room": "Verschlüsselung ist in diesem Raum aktiviert",
|
||||
"Encryption is not enabled in this room": "Verschlüsselung ist in diesem Raum nicht aktiviert",
|
||||
|
@ -96,7 +96,7 @@
|
|||
"End-to-end encryption is in beta and may not be reliable": "Die Ende-zu-Ende-Verschlüsselung befindet sich aktuell im Beta-Stadium und ist eventuell noch nicht hundertprozentig zuverlässig",
|
||||
"Failed to send email": "Fehler beim Senden der E-Mail",
|
||||
"Account": "Konto",
|
||||
"Add phone number": "Füge Telefonnummer hinzu",
|
||||
"Add phone number": "Telefonnummer hinzufügen",
|
||||
"an address": "an Adresse",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Dein Passwort wurde erfolgreich geändert. Du wirst erst Benachrichtigungen auf anderen Geräten empfangen können, wenn du dich dort erneut anmeldest",
|
||||
"all room members": "Alle Raum-Mitglieder",
|
||||
|
@ -109,25 +109,25 @@
|
|||
"Click here to fix": "Zum reparieren hier klicken",
|
||||
"*️⃣ Commands": "*️⃣ Befehle",
|
||||
"Default": "Standard",
|
||||
"demote": "Zum zurückstufen",
|
||||
"demote": "Berechtigungslevel herabstufen",
|
||||
"Export E2E room keys": "E2E-Raum-Schlüssel exportieren",
|
||||
"Failed to change password. Is your password correct?": "Passwort-Änderung schlug fehl. Ist dein Passwort korrekt?",
|
||||
"Failed to change password. Is your password correct?": "Passwortänderung fehlgeschlagen. Ist dein Passwort richtig?",
|
||||
"Failed to forget room": "Vergessen des Raums schlug fehl",
|
||||
"Failed to leave room": "Verlassen des Raums fehlgeschlagen",
|
||||
"Failed to reject invitation": "Fehler beim Abweisen der Einladung",
|
||||
"Failed to set avatar.": "Fehler beim Setzen des Avatars.",
|
||||
"Failed to reject invitation": "Einladung konnte nicht abgelehnt werden",
|
||||
"Failed to set avatar.": "Fehler beim Setzen des Profilbilds.",
|
||||
"Failed to unban": "Entbannen fehlgeschlagen",
|
||||
"Failed to upload file": "Datei-Upload fehlgeschlagen",
|
||||
"Favourite": "Favorit",
|
||||
"favourite": "Favoriten",
|
||||
"favourite": "Als Favorit setzen",
|
||||
"Forget room": "Raum vergessen",
|
||||
"Forgot your password?": "Passwort vergessen?",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.",
|
||||
"For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.",
|
||||
"Found a bug?": "Fehler gefunden?",
|
||||
"Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.",
|
||||
"Guests can't set avatars. Please register.": "Gäste können keine Avatare setzen. Bitte registriere dich.",
|
||||
"Guest users can't upload files. Please register to upload.": "Gäste können keine Dateien hochladen. Bitte registrieren um hochzuladen.",
|
||||
"Guests can't set avatars. Please register.": "Gäste können kein Profilbild setzen. Bitte registrieren.",
|
||||
"Guest users can't upload files. Please register to upload.": "Gäste können keine Dateien hochladen. Bitte zunächst registrieren.",
|
||||
"had": "hatte",
|
||||
"Hangup": "Auflegen",
|
||||
"Homeserver is": "Der Homeserver ist",
|
||||
|
@ -140,12 +140,12 @@
|
|||
"is a": "ist ein",
|
||||
"is trusted": "wird vertraut",
|
||||
"Sign in with": "Ich möchte mich anmelden mit",
|
||||
"joined and left": "trat bei und ging",
|
||||
"joined": "trat bei",
|
||||
"joined and left": "hat den Raum betreten und wieder verlassen",
|
||||
"joined": "hat den Raum betreten",
|
||||
"joined the room": "trat dem Raum bei",
|
||||
"Leave room": "Verlasse Raum",
|
||||
"left and rejoined": "ging(en) und trat(en) erneut bei",
|
||||
"left": "ging",
|
||||
"left": "hat den Raum verlassen",
|
||||
"left the room": "verließ den Raum",
|
||||
"Logged in as": "Angemeldet als",
|
||||
"Logout": "Abmelden",
|
||||
|
@ -182,7 +182,7 @@
|
|||
"Once you've followed the link it contains, click below": "Nachdem du dem darin enthaltenen Link gefolgt bist, klicke unten",
|
||||
"rejected the invitation.": "lehnte die Einladung ab.",
|
||||
"Reject invitation": "Einladung ablehnen",
|
||||
"Remove Contact Information?": "Kontakt-Informationen löschen?",
|
||||
"Remove Contact Information?": "Kontakt-Informationen entfernen?",
|
||||
"removed their display name": "löschte den eigenen Anzeigenamen",
|
||||
"Remove": "Entfernen",
|
||||
"requested a VoIP conference": "hat eine VoIP-Konferenz angefordert",
|
||||
|
@ -191,20 +191,20 @@
|
|||
"Return to login screen": "Zur Anmeldemaske zurückkehren",
|
||||
"Room Colour": "Raumfarbe",
|
||||
"Room name (optional)": "Raumname (optional)",
|
||||
"Scroll to unread messages": "Scrolle zu ungelesenen Nachrichten",
|
||||
"Scroll to unread messages": "Zu den ungelesenen Nachrichten scrollen",
|
||||
"Send Invites": "Einladungen senden",
|
||||
"Send Reset Email": "E-Mail für das Zurücksetzen senden",
|
||||
"sent an image": "sandte ein Bild",
|
||||
"Send Reset Email": "E-Mail zum Zurücksetzen senden",
|
||||
"sent an image": "hat ein Bild gesendet",
|
||||
"sent an invitation to": "sandte eine Einladung an",
|
||||
"sent a video": "sandte ein Video",
|
||||
"sent a video": "hat ein Video gesendet",
|
||||
"Server may be unavailable or overloaded": "Server ist eventuell nicht verfügbar oder überlastet",
|
||||
"set a profile picture": "setzte ein Profilbild",
|
||||
"set their display name to": "setzte den Anzeigenamen auf",
|
||||
"Settings": "Einstellungen",
|
||||
"Signed Out": "Abgemeldet",
|
||||
"Sign out": "Abmelden",
|
||||
"since the point in time of selecting this option": "seitdem diese Option gewählt wird",
|
||||
"since they joined": "seitdem sie beitraten",
|
||||
"since the point in time of selecting this option": "ab dem Zeitpunkt, an dem diese Option gewählt wird",
|
||||
"since they joined": "ab dem Zeitpunkt, an dem sie beigetreten sind",
|
||||
"since they were invited": "seitdem sie eingeladen wurden",
|
||||
"Someone": "Jemand",
|
||||
"Start a chat": "Starte einen Chat",
|
||||
|
@ -219,7 +219,7 @@
|
|||
"This doesn't appear to be a valid email address": "Dies scheint keine gültige E-Mail-Adresse zu sein",
|
||||
"this invitation?": "diese Einladung?",
|
||||
"This is a preview of this room. Room interactions have been disabled": "Dies ist eine Vorschau dieses Raumes. Raum-Interaktionen wurden deaktiviert",
|
||||
"This room is not accessible by remote Matrix servers": "Dieser Raum ist über entfernte Matrix-Server nicht zugreifbar",
|
||||
"This room is not accessible by remote Matrix servers": "Andere Matrix-Server können auf diesen Raum nicht zugreifen",
|
||||
"This room's internal ID is": "Die interne ID dieses Raumes ist",
|
||||
"To ban users": "Zum Nutzer bannen",
|
||||
"To configure the room": "Um den Raum zu konfigurieren",
|
||||
|
@ -227,7 +227,7 @@
|
|||
"to join the discussion": "um an der Diskussion teilzunehmen",
|
||||
"To kick users": "Um Nutzer zu entfernen",
|
||||
"Admin": "Administrator",
|
||||
"Server may be unavailable, overloaded, or you hit a bug": "Server könnte nicht verfügbar oder überlastet sein oder du bist auf einen Fehler gestoßen",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Server ist nicht verfügbar, überlastet oder du bist auf einen Fehler gestoßen.",
|
||||
"Could not connect to the integration server": "Konnte keine Verbindung zum Integrations-Server herstellen",
|
||||
"Disable inline URL previews by default": "URL-Vorschau im Chat standardmäßig deaktivieren",
|
||||
"Guests can't use labs features. Please register.": "Gäste können keine Labor-Funktionen nutzen. Bitte registrieren.",
|
||||
|
@ -246,7 +246,7 @@
|
|||
"Unencrypted room": "Unverschlüsselter Raum",
|
||||
"unknown error code": "Unbekannter Fehlercode",
|
||||
"unknown": "unbekannt",
|
||||
"Upload avatar": "Avatar hochladen",
|
||||
"Upload avatar": "Profilbild hochladen",
|
||||
"uploaded a file": "lud eine Datei hoch",
|
||||
"Upload Files": "Dateien hochladen",
|
||||
"Upload file": "Datei hochladen",
|
||||
|
@ -255,7 +255,7 @@
|
|||
"Users": "Nutzer",
|
||||
"User": "Nutzer",
|
||||
"Verification Pending": "Verifizierung ausstehend",
|
||||
"Video call": "Videoanruf",
|
||||
"Video call": "Video-Anruf",
|
||||
"Voice call": "Sprachanruf",
|
||||
"VoIP conference finished.": "VoIP-Konferenz wurde beendet.",
|
||||
"VoIP conference started.": "VoIP-Konferenz gestartet.",
|
||||
|
@ -270,8 +270,8 @@
|
|||
"Who would you like to add to this room?": "Wen möchtest du zu diesem Raum hinzufügen?",
|
||||
"Who would you like to communicate with?": "Mit wem möchtest du kommunizieren?",
|
||||
"Would you like to": "Möchtest du",
|
||||
"You do not have permission to post to this room": "Du hast keine Berechtigung an diesen Raum etwas zu senden",
|
||||
"You have been invited to join this room by %(inviterName)s": "Du wurdest von %(inviterName)s in diesen Raum eingeladen",
|
||||
"You do not have permission to post to this room": "Du hast keine Berechtigung, in diesem Raum etwas zu senden",
|
||||
"You have been invited to join this room by %(inviterName)s": "%(inviterName)s hat dich in diesen Raum eingeladen",
|
||||
"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": "Du wurdest auf allen Geräten abgemeldet und wirst keine Push-Benachrichtigungen mehr erhalten. Um die Benachrichtigungen zu reaktivieren, musst du dich auf jedem Gerät neu anmelden",
|
||||
"you must be a": "nötige Rolle",
|
||||
"Your password has been reset": "Dein Passwort wurde zurückgesetzt",
|
||||
|
@ -280,19 +280,19 @@
|
|||
"times": "mal",
|
||||
"Bulk Options": "Bulk-Optionen",
|
||||
"Call Timeout": "Anruf-Timeout",
|
||||
"Conference call failed": "Konferenzgespräch fehlgeschlagen",
|
||||
"Conference calling is in development and may not be reliable": "Konferenzgespräche sind in Entwicklung und evtl. nicht zuverlässig",
|
||||
"Conference calls are not supported in encrypted rooms": "Konferenzgespräche sind in verschlüsselten Räumen nicht unterstützt",
|
||||
"Conference calls are not supported in this client": "Konferenzgespräche sind in diesem Client nicht unterstützt",
|
||||
"Conference call failed.": "Konferenzgespräch fehlgeschlagen.",
|
||||
"Conference calling is in development and may not be reliable.": "Konferenzgespräche befinden sich noch in der Entwicklungsphase und sind möglicherweise nicht zuverlässig nutzbar.",
|
||||
"Conference calls are not supported in encrypted rooms": "Konferenzgespräche werden in verschlüsselten Räumen nicht unterstützt",
|
||||
"Conference calls are not supported in this client": "Konferenzgespräche werden von diesem Client nicht unterstützt",
|
||||
"Existing Call": "Bereits bestehender Anruf",
|
||||
"Failed to set up conference call": "Konferenzgespräch konnte nicht gestartet werden",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "Verifizierung der E-Mail-Adresse fehlgeschlagen: Bitte stelle sicher, dass du den Link in der E-Mail angeklickt hast",
|
||||
"Failure to create room": "Raumerstellung fehlgeschlagen",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat": "Gäste können keine neuen Räume erstellen. Bitte registrieren um einen Raum zu erstellen und einen Chat zu starten",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Gastnutzer können keine neuen Räume erstellen. Bitte registriere dich um Räume zu erstellen und Chats zu starten.",
|
||||
"Riot does not have permission to send you notifications - please check your browser settings": "Riot hat keine Berechtigung Benachrichtigungen zu senden - bitte prüfe deine Browser-Einstellungen",
|
||||
"Riot was not given permission to send notifications - please try again": "Riot hat das Recht nicht bekommen Benachrichtigungen zu senden. Bitte erneut probieren",
|
||||
"This email address is already in use": "Diese E-Mail-Adresse wird bereits verwendet",
|
||||
"This email address was not found": "Diese E-Mail-Adresse wurde nicht gefunden",
|
||||
"This email address was not found": "Diese E-Mail-Adresse konnte nicht gefunden werden",
|
||||
"The file '%(fileName)s' exceeds this home server's size limit for uploads": "Die Datei '%(fileName)s' überschreitet das Größen-Limit für Uploads auf diesem Homeserver",
|
||||
"The file '%(fileName)s' failed to upload": "Das Hochladen der Datei '%(fileName)s' schlug fehl",
|
||||
"The remote side failed to pick up": "Die Gegenstelle konnte nicht abheben",
|
||||
|
@ -302,11 +302,11 @@
|
|||
"Unable to enable Notifications": "Benachrichtigungen konnten nicht aktiviert werden",
|
||||
"Upload Failed": "Upload fehlgeschlagen",
|
||||
"VoIP is unsupported": "VoIP wird nicht unterstützt",
|
||||
"You are already in a call": "Du bist bereits bei einem Anruf",
|
||||
"You cannot place a call with yourself": "Du kannst keinen Anruf mit dir selbst starten",
|
||||
"You cannot place VoIP calls in this browser": "Du kannst kein VoIP-Gespräch in diesem Browser starten",
|
||||
"You are already in a call.": "Du bist bereits in einem Gespräch.",
|
||||
"You cannot place a call with yourself.": "Du kannst keinen Anruf mit dir selbst starten.",
|
||||
"You cannot place VoIP calls in this browser.": "Du kannst keine VoIP-Gespräche in diesem Browser starten.",
|
||||
"You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "Du musst dich erneut anmelden, um Ende-zu-Ende-Verschlüsselungs-Schlüssel für dieses Gerät zu generieren und um den öffentlichen Schlüssel auf deinem Homeserver zu hinterlegen. Dies muss nur einmal durchgeführt werden, bitte entschuldige die Unannehmlichkeiten.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Homeserver verknüpft zu sein",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Heimserver verbunden zu sein.",
|
||||
"Sun": "So",
|
||||
"Mon": "Mo",
|
||||
"Tue": "Di",
|
||||
|
@ -336,23 +336,23 @@
|
|||
"Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Passwort zu kurz (min. %(MIN_PASSWORD_LENGTH)s).",
|
||||
"This doesn't look like a valid email address.": "Dies scheint keine gültige E-Mail-Adresse zu sein.",
|
||||
"This doesn't look like a valid phone number.": "Dies scheint keine gültige Telefonnummer zu sein.",
|
||||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Benutzernamen sollen nur Buchstaben, Nummern, Binde- und Unterstriche enthalten.",
|
||||
"An unknown error occurred.": "Ein unbekannter Fehler trat auf.",
|
||||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Benutzernamen dürfen nur Buchstaben, Nummern, Punkte, Binde- und Unterstriche enthalten.",
|
||||
"An unknown error occurred.": "Ein unbekannter Fehler ist aufgetreten.",
|
||||
"I already have an account": "Ich habe bereits einen Account",
|
||||
"An error occured: %(error_string)s": "Ein Fehler trat auf: %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "Ein Fehler trat auf: %(error_string)s",
|
||||
"Topic": "Thema",
|
||||
"Make this room private": "Mache diesen Raum privat",
|
||||
"Share message history with new users": "Nachrichtenhistorie mit neuen Nutzern teilen",
|
||||
"Share message history with new users": "Bisherigen Chatverlauf mit neuen Nutzern teilen",
|
||||
"Encrypt room": "Raum verschlüsseln",
|
||||
"To send events of type": "Zum Senden von Ereignissen mit Typ",
|
||||
"%(names)s and %(lastPerson)s are typing": "%(names)s und %(lastPerson)s schreiben",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s hat eine Einladung angenommen.",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s akzeptierte die Einladung für %(displayName)s.",
|
||||
"%(names)s and one other are typing": "%(names)s und eine weitere Person tippen",
|
||||
"%(names)s and %(count)s others are typing": "%(names)s und %(count)s weitere Personen tippen",
|
||||
"%(senderName)s answered the call.": "%(senderName)s beantwortete den Anruf.",
|
||||
"%(names)s and %(count)s others are typing": "%(names)s und %(count)s weitere Personen schreiben",
|
||||
"%(senderName)s answered the call.": "%(senderName)s hat den Anruf angenommen.",
|
||||
"%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s aus dem Raum verbannt.",
|
||||
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von %(oldDisplayName)s auf %(displayName)s geändert.",
|
||||
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von \"%(oldDisplayName)s\" auf \"%(displayName)s\" geändert.",
|
||||
"%(senderName)s changed their profile picture.": "%(senderName)s hat das Profilbild geändert.",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s hat das Berechtigungslevel von %(powerLevelDiffText)s geändert.",
|
||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s änderte den Raumnamen zu %(roomName)s.",
|
||||
|
@ -364,7 +364,7 @@
|
|||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s von %(fromPowerLevel)s zu %(toPowerLevel)s",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s hat %(targetName)s eingeladen.",
|
||||
"%(displayName)s is typing": "%(displayName)s schreibt",
|
||||
"%(targetName)s joined the room.": "%(targetName)s trat dem Raum bei.",
|
||||
"%(targetName)s joined the room.": "%(targetName)s hat den Raum betreten.",
|
||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s kickte %(targetName)s.",
|
||||
"%(targetName)s left the room.": "%(targetName)s hat den Raum verlassen.",
|
||||
"%(senderName)s made future room history visible to": "%(senderName)s machte die zukünftige Raumhistorie sichtbar für",
|
||||
|
@ -377,13 +377,13 @@
|
|||
"Power level must be positive integer.": "Berechtigungslevel muss eine positive ganze Zahl sein.",
|
||||
"Reason": "Grund",
|
||||
"%(targetName)s rejected the invitation.": "%(targetName)s hat die Einladung abgelehnt.",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s löschte den Anzeigenamen (%(oldDisplayName)s).",
|
||||
"%(senderName)s removed their profile picture.": "%(senderName)s löschte das Profilbild.",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s hat den Anzeigenamen entfernt (%(oldDisplayName)s).",
|
||||
"%(senderName)s removed their profile picture.": "%(senderName)s hat das Profilbild gelöscht.",
|
||||
"%(senderName)s requested a VoIP conference.": "%(senderName)s möchte eine VoIP-Konferenz beginnen.",
|
||||
"Room %(roomId)s not visible": "Raum %(roomId)s ist nicht sichtbar",
|
||||
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s hat ein Bild gesendet.",
|
||||
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s hat %(targetDisplayName)s in diesen Raum eingeladen.",
|
||||
"%(senderName)s set a profile picture.": "%(senderName)s setzte ein Profilbild.",
|
||||
"%(senderName)s set a profile picture.": "%(senderName)s hat ein Profilbild gesetzt.",
|
||||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s hat den Anzeigenamen geändert in %(displayName)s.",
|
||||
"This room is not recognised.": "Dieser Raum wurde nicht erkannt.",
|
||||
"These are experimental features that may break in unexpected ways": "Dies sind experimentelle Funktionen, die in unerwarteter Weise Fehler verursachen können",
|
||||
|
@ -392,13 +392,13 @@
|
|||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s zog Bann für %(targetName)s zurück.",
|
||||
"Usage": "Verwendung",
|
||||
"Use with caution": "Mit Vorsicht zu verwenden",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s zog die Einladung für %(targetName)s zurück.",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen.",
|
||||
"You need to be able to invite users to do that.": "Du musst die Berechtigung haben, Nutzer einzuladen, um diese Aktion ausführen zu können.",
|
||||
"You need to be logged in.": "Du musst angemeldet sein.",
|
||||
"There are no visible files in this room": "Es gibt keine sichtbaren Dateien in diesem Raum",
|
||||
"Error changing language": "Fehler beim Ändern der Sprache",
|
||||
"Riot was unable to find the correct Data for the selected Language.": "Riot war nicht in der Lage die korrekten Daten für die ausgewählte Sprache zu finden.",
|
||||
"Connectivity to the server has been lost.": "Verbindung zum Server untergebrochen.",
|
||||
"Connectivity to the server has been lost.": "Verbindung zum Server wurde unterbrochen.",
|
||||
"Sent messages will be stored until your connection has returned.": "Gesendete Nachrichten werden gespeichert, bis die Internetverbindung wiederhergestellt wurde.",
|
||||
"Auto-complete": "Autovervollständigung",
|
||||
"Resend all": "Alle erneut senden",
|
||||
|
@ -418,7 +418,7 @@
|
|||
"Press": "Drücke",
|
||||
"tag as %(tagName)s": "als %(tagName)s taggen",
|
||||
"to browse the directory": "um das Raum-Verzeichnis zu durchsuchen",
|
||||
"to demote": "um die Priorität herabzusetzen",
|
||||
"to demote": "um das Berechtigungslevel herabzusetzen",
|
||||
"to favourite": "zum Favorisieren",
|
||||
"to make a room or": "um einen Raum zu erstellen, oder",
|
||||
"to restore": "zum wiederherstellen",
|
||||
|
@ -427,7 +427,7 @@
|
|||
"You're not in any rooms yet! Press": "Du bist noch keinem Raum beigetreten! Drücke",
|
||||
"click to reveal": "Klicke zum anzeigen",
|
||||
"To remove other users' messages": "Um Nachrichten anderer Nutzer zu verbergen",
|
||||
"You are trying to access %(roomName)s": "Du versuchst auf %(roomName)s zuzugreifen",
|
||||
"You are trying to access %(roomName)s.": "Du versuchst, auf den Raum \"%(roomName)s\" zuzugreifen.",
|
||||
"af": "Afrikaans",
|
||||
"ar-ae": "Arabisch (VAE)",
|
||||
"ar-bh": "Arabisch (Bahrain)",
|
||||
|
@ -558,13 +558,13 @@
|
|||
"Are you sure?": "Bist du sicher?",
|
||||
"Attachment": "Anhang",
|
||||
"Ban": "Verbannen",
|
||||
"Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Kann nicht zum Heimserver verbinden - bitte checke eine Verbindung und stelle sicher, dass dem <a>SSL-Zertifikat deines Heimservers</a> vertraut wird.",
|
||||
"Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Verbindungsaufbau zum Heimserver nicht möglich - bitte Internetverbindung überprüfen und sicherstellen, ob das <a>SSL-Zertifikat des Heimservers</a> vertrauenswürdig ist.",
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Kann nicht zum Heimserver via HTTP verbinden, wenn eine HTTPS-Url in deiner Adresszeile steht. Nutzer HTTPS oder <a>aktiviere unsichere Skripte</a>.",
|
||||
"changing room on a RoomView is not supported": "Das Ändern eines Raumes in einer RaumAnsicht wird nicht unterstützt",
|
||||
"Click to mute audio": "Klicke um den Ton stumm zu stellen",
|
||||
"Click to mute video": "Klicken, um das Video stummzuschalten",
|
||||
"Command error": "Befehlsfehler",
|
||||
"Decrypt %(text)s": "Entschlüssele %(text)s",
|
||||
"Decrypt %(text)s": "%(text)s entschlüsseln",
|
||||
"Delete": "Löschen",
|
||||
"Devices": "Geräte",
|
||||
"Direct chats": "Direkte Chats",
|
||||
|
@ -576,21 +576,20 @@
|
|||
"Failed to delete device": "Löschen des Geräts fehlgeschlagen",
|
||||
"Failed to join room": "Betreten des Raumes ist fehlgeschlagen",
|
||||
"Failed to kick": "Kicken fehlgeschlagen",
|
||||
"Failed to mute user": "Nutzer lautlos zu stellen fehlgeschlagen",
|
||||
"Failed to mute user": "Stummschalten des Nutzers fehlgeschlagen",
|
||||
"Failed to reject invite": "Ablehnen der Einladung ist fehlgeschlagen",
|
||||
"Failed to save settings": "Einstellungen konnten nicht gespeichert werden",
|
||||
"Failed to set display name": "Anzeigename konnte nicht gesetzt werden",
|
||||
"Fill screen": "Fülle Bildschirm",
|
||||
"Guest users can't upload files. Please register to upload": "Gäste können keine Dateien hochladen. Bitte zunächst registrieren",
|
||||
"Hide Text Formatting Toolbar": "Verberge Text-Formatierungs-Toolbar",
|
||||
"Incorrect verification code": "Falscher Verifizierungscode",
|
||||
"Invalid alias format": "Ungültiges Alias-Format",
|
||||
"Invalid address format": "Ungültiges Adressformat",
|
||||
"'%(alias)s' is not a valid format for an address": "'%(alias)s' ist kein gültiges Adressformat",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' hat kein valides Aliasformat",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' ist kein gültiges Alias-Format",
|
||||
"Join Room": "Dem Raum beitreten",
|
||||
"Kick": "Kicke",
|
||||
"Level": "Level",
|
||||
"Level": "Berechtigungslevel",
|
||||
"Local addresses for this room:": "Lokale Adressen dieses Raumes:",
|
||||
"Markdown is disabled": "Markdown ist deaktiviert",
|
||||
"Markdown is enabled": "Markdown ist aktiviert",
|
||||
|
@ -603,22 +602,22 @@
|
|||
"No results": "Keine Ergebnisse",
|
||||
"OK": "OK",
|
||||
"Revoke Moderator": "Moderator zurückziehen",
|
||||
"Search": "Suche",
|
||||
"Search failed": "Suche fehlgeschlagen",
|
||||
"Search": "Suchen",
|
||||
"Search failed": "Suche ist fehlgeschlagen",
|
||||
"Server error": "Server-Fehler",
|
||||
"Server may be unavailable, overloaded, or search timed out :(": "Der Server ist entweder nicht verfügbar, überlastet oder die Suche wurde wegen Zeitüberschreitung abgebrochen :(",
|
||||
"Server may be unavailable, overloaded, or the file too big": "Server ist entweder nicht verfügbar, überlastet oder die Datei ist zu groß",
|
||||
"Server unavailable, overloaded, or something else went wrong": "Der Server ist entweder nicht verfügbar, überlastet oder es liegt ein anderweitiger Fehler vor",
|
||||
"Some of your messages have not been sent": "Einige deiner Nachrichten wurden noch nicht gesendet",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Server ist nicht verfügbar, überlastet oder ein anderer Fehler ist aufgetreten.",
|
||||
"Some of your messages have not been sent.": "Einige deiner Nachrichten wurden nicht gesendet.",
|
||||
"Submit": "Absenden",
|
||||
"The main address for this room is: %(canonical_alias_section)s": "Die Hauptadresse für diesen Raum ist: %(canonical_alias_section)s",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "Diese Aktion kann nicht von einem Gast ausgeführt werden. Bitte registriere dich um dies zu tun",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "Diese Aktion kann nicht von einem Gast ausgeführt werden. Bitte registriere dich um dies zu tun.",
|
||||
"%(actionVerb)s this person?": "Diese Person %(actionVerb)s?",
|
||||
"This room has no local addresses": "Dieser Raum hat keine lokale Adresse",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "Dieser Raum ist privat oder für Gäste nicht zugänglich. Du kannst jedoch eventuell beitreten, wenn du dich registrierst",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question": "Versuchte einen spezifischen Punkt in der Raum-Chronik zu laden, aber du hast keine Berechtigung die angeforderte Nachricht anzuzeigen",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it": "Der Versuch, einen spezifischen Punkt im Chatverlauf zu laden, ist fehlgeschlagen. Der Punkt konnte nicht gefunden werden",
|
||||
"Turn Markdown off": "Markdown abschalten",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Versuchte einen spezifischen Punkt in der Raum-Chronik zu laden, aber du hast keine Berechtigung die angeforderte Nachricht anzuzeigen.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Der Versuch, einen spezifischen Punkt im Chatverlauf zu laden, ist fehlgeschlagen. Der Punkt konnte nicht gefunden werden.",
|
||||
"Turn Markdown off": "Markdown deaktiveren",
|
||||
"Turn Markdown on": "Markdown einschalten",
|
||||
"Unable to load device list": "Geräteliste konnte nicht geladen werden",
|
||||
"Unknown command": "Unbekannter Befehl",
|
||||
|
@ -626,8 +625,8 @@
|
|||
"Usage: /markdown on|off": "Verwendung: /markdown on|off",
|
||||
"You seem to be in a call, are you sure you want to quit?": "Du scheinst in einem Anruf zu sein. Bist du sicher schließen zu wollen?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Du scheinst Dateien hochzuladen. Bist du sicher schließen zu wollen?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself": "Du wirst diese Änderung nicht rückgängig machen können, da der Nutzer dasselbe Berechtigungslevel wie du selbst erhalten wird",
|
||||
"Make Moderator": "Zum Moderator machen",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Du wirst diese Änderung nicht rückgängig machen können, da der Nutzer dasselbe Berechtigungslevel wie du selbst erhalten wird.",
|
||||
"Make Moderator": "Zum Moderator ernennen",
|
||||
"Room": "Raum",
|
||||
"(~%(searchCount)s results)": "(~%(searchCount)s Ergebnisse)",
|
||||
"Cancel": "Abbrechen",
|
||||
|
@ -653,29 +652,29 @@
|
|||
"%(items)s and one other": "%(items)s und ein(e) weitere(r)",
|
||||
"%(items)s and %(lastItem)s": "%(items)s und %(lastItem)s",
|
||||
"%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)ssind dem Raum %(repeats)s mal beigetreten",
|
||||
"%(oneUser)sjoined %(repeats)s times": "%(oneUser)strat %(repeats)s mal bei",
|
||||
"%(severalUsers)sjoined": "%(severalUsers)straten bei",
|
||||
"%(oneUser)sjoined": "%(oneUser)strat bei",
|
||||
"%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sverließen %(repeats)s mal den Raum",
|
||||
"%(oneUser)sjoined %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal betreten",
|
||||
"%(severalUsers)sjoined": "%(severalUsers)shaben den Raum betreten",
|
||||
"%(oneUser)sjoined": "%(oneUser)shat den Raum betreten",
|
||||
"%(severalUsers)sleft %(repeats)s times": "%(severalUsers)shaben %(repeats)s mal den Raum verlassen",
|
||||
"%(oneUser)sleft %(repeats)s times": "%(oneUser)sging %(repeats)s mal",
|
||||
"%(severalUsers)sleft": "%(severalUsers)shaben den Raum verlassen",
|
||||
"%(oneUser)sleft": "%(oneUser)sging",
|
||||
"%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)straten bei und gingen %(repeats)s mal",
|
||||
"%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)strat bei und ging %(repeats)s mal",
|
||||
"%(severalUsers)sjoined and left": "%(severalUsers)straten bei und gingen",
|
||||
"%(oneUser)sjoined and left": "%(oneUser)strat bei und ging",
|
||||
"%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)shaben den Raum %(repeats)s mal betreten und wieder verlassen",
|
||||
"%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal betreten und wieder verlassen",
|
||||
"%(severalUsers)sjoined and left": "%(severalUsers)shaben den Raum betreten und wieder verlassen",
|
||||
"%(oneUser)sjoined and left": "%(oneUser)shat den Raum betreten und wieder verlassen",
|
||||
"%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)shaben den Raum verlassen und %(repeats)s mal neu betreten",
|
||||
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sging und trat %(repeats)s mal erneut bei",
|
||||
"%(severalUsers)sleft and rejoined": "%(severalUsers)s gingen und traten erneut bei",
|
||||
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)shat den Raum %(repeats)s mal verlassen und wieder neu betreten",
|
||||
"%(severalUsers)sleft and rejoined": "%(severalUsers)shaben den Raum verlassen und wieder neu betreten",
|
||||
"%(oneUser)sleft left and rejoined": "%(oneUser)sging und trat erneut bei",
|
||||
"%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)s lehnten %(repeats)s mal ihre Einladung ab",
|
||||
"%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)shaben ihre Einladung %(repeats)s mal abgelehnt",
|
||||
"%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shat die Einladung %(repeats)s mal abgelehnt",
|
||||
"%(severalUsers)srejected their invitations": "%(severalUsers)slehnten ihre Einladung ab",
|
||||
"%(oneUser)srejected their invitation": "%(oneUser)slehnte seine/ihre Einladung ab",
|
||||
"%(severalUsers)srejected their invitations": "%(severalUsers)shaben ihre Einladung abgelehnt",
|
||||
"%(oneUser)srejected their invitation": "%(oneUser)shat die Einladung abgelehnt",
|
||||
"%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)szogen ihre Einladungen %(repeats)s mal zurück",
|
||||
"%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)szog seine/ihre Einladung %(repeats)s mal zurück",
|
||||
"%(severalUsers)shad their invitations withdrawn": "%(severalUsers)szogen ihre Einladungen zurück",
|
||||
"%(oneUser)shad their invitation withdrawn": "%(oneUser)szog seine/ihre Einladung zurück",
|
||||
"%(oneUser)shad their invitation withdrawn": "%(oneUser)swurde die ursprüngliche Einladung wieder entzogen",
|
||||
"were invited %(repeats)s times": "wurden %(repeats)s mal eingeladen",
|
||||
"was invited %(repeats)s times": "wurde %(repeats)s mal eingeladen",
|
||||
"were invited": "wurden eingeladen",
|
||||
|
@ -687,17 +686,17 @@
|
|||
"were unbanned": "wurden entbannt",
|
||||
"were kicked %(repeats)s times": "wurden %(repeats)s mal gekickt",
|
||||
"was kicked %(repeats)s times": "wurde %(repeats)s mal gekickt",
|
||||
"were kicked": "wurden gekickt",
|
||||
"%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)sänderten %(repeats)s mal ihre Namen",
|
||||
"%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sänderte %(repeats)s mal seinen/ihren Namen",
|
||||
"%(severalUsers)schanged their name": "%(severalUsers)sänderten ihre Namen",
|
||||
"%(oneUser)schanged their name": "%(oneUser)sänderte seinen/ihren Namen",
|
||||
"%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)shaben %(repeats)s mal ihren Avatar geändert",
|
||||
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sänderte %(repeats)s mal seinen/ihren Avatar",
|
||||
"%(severalUsers)schanged their avatar": "%(severalUsers)sänderten ihre Avatare",
|
||||
"were kicked": "wurden aus dem Raum entfernt",
|
||||
"%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)shaben ihren Namen %(repeats)s mal geändert",
|
||||
"%(oneUser)schanged their name %(repeats)s times": "%(oneUser)shat den Namen %(repeats)s mal geändert",
|
||||
"%(severalUsers)schanged their name": "%(severalUsers)shaben ihre Namen geändert",
|
||||
"%(oneUser)schanged their name": "%(oneUser)shat den Namen geändert",
|
||||
"%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)shaben %(repeats)s mal ihr Profilbild geändert",
|
||||
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)shat %(repeats)s mal das Profilbild geändert",
|
||||
"%(severalUsers)schanged their avatar": "%(severalUsers)shaben ihr Profilbild geändert",
|
||||
"%(oneUser)schanged their avatar": "%(oneUser)shat das Profilbild geändert",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s. %(monthName)s %(fullYear)s %(time)s",
|
||||
"%(oneUser)sleft and rejoined": "%(oneUser)sverließ den Raum und trat erneut bei",
|
||||
"%(oneUser)sleft and rejoined": "%(oneUser)shat den Raum verlassen und wieder neu betreten",
|
||||
"A registered account is required for this action": "Für diese Aktion ist ein registrierter Account notwendig",
|
||||
"Access Token:": "Zugangs-Token:",
|
||||
"Always show message timestamps": "Nachrichten-Zeitstempel immer anzeigen",
|
||||
|
@ -726,9 +725,9 @@
|
|||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Eine Änderung des Passworts setzt derzeit alle Schlüssel für die E2E-Verschlüsselung auf allen verwendeten Geräten zurück. Bereits verschlüsselte Chat-Inhalte sind somit nur noch lesbar, wenn du zunächst alle Schlüssel exportierst und später wieder importierst. Wir arbeiten an einer Verbesserung dieser momentan noch notwendigen Vorgehensweise.",
|
||||
"Unmute": "Stummschalten aufheben",
|
||||
"Invalid file%(extra)s": "Ungültige Datei%(extra)s",
|
||||
"Remove %(threePid)s?": "Entferne %(threePid)s?",
|
||||
"Remove %(threePid)s?": "%(threePid)s entfernen?",
|
||||
"Please select the destination room for this message": "Bitte den Raum auswählen, an den diese Nachricht gesendet werden soll",
|
||||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s löschte den Raumnamen.",
|
||||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s hat den Raum-Namen gelöscht.",
|
||||
"Passphrases must match": "Passphrase muss übereinstimmen",
|
||||
"Passphrase must not be empty": "Passphrase darf nicht leer sein",
|
||||
"Export room keys": "Raum-Schlüssel exportieren",
|
||||
|
@ -736,9 +735,8 @@
|
|||
"Confirm passphrase": "Bestätige Passphrase",
|
||||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Die Export-Datei wird mit einer Passphrase geschützt sein. Du solltest die Passphrase hier eingeben um die Datei zu entschlüsseln.",
|
||||
"You must join the room to see its files": "Du musst dem Raum beitreten, um die Raum-Dateien sehen zu können",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Server ist nicht verfügbar, überlastet oder du bist auf einen Fehler gestoßen.",
|
||||
"Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s Einladungen ablehnen",
|
||||
"Start new chat": "Starte neuen Chat",
|
||||
"Start new Chat": "Starte neuen Chat",
|
||||
"Guest users can't invite users. Please register.": "Gäste können keine Nutzer einladen. Bitte registrieren.",
|
||||
"Failed to invite": "Einladen fehlgeschlagen",
|
||||
"Failed to invite user": "Einladen des Nutzers fehlgeschlagen",
|
||||
|
@ -753,10 +751,10 @@
|
|||
"Verify device": "Gerät verifizieren",
|
||||
"I verify that the keys match": "Ich bestätige, dass die Schlüssel passen",
|
||||
"Unable to restore session": "Sitzungswiederherstellung fehlgeschlagen",
|
||||
"Continue anyway": "Fahre trotzdem fort",
|
||||
"Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Dein Anzeigename ist der Name, der anderen Nutzern angezeigt wird, wenn du in Räumen sprichst. Welchen Anzeigenamen möchtest du wählen?",
|
||||
"Continue anyway": "Trotzdem fortfahren",
|
||||
"Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Dein Anzeigename ist der Name, der anderen Nutzern angezeigt wird, wenn du in Räumen kommunizierst. Welchen Anzeigenamen möchtest du wählen?",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Do blockst aktuell unverifizierte Geräte. Um Nachrichten an diese Geräte zu senden musst du sie verifizieren.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" enthält Geräte die du noch nicht gesehen hast.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" enthält Geräte, die du bislang noch nicht gesehen hast.",
|
||||
"Unknown devices": "Unbekannte Geräte",
|
||||
"Unknown Address": "Unbekannte Adresse",
|
||||
"Verify...": "Verifizieren...",
|
||||
|
@ -770,7 +768,7 @@
|
|||
"You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Du kannst auch einen angepassten Idantitätsserver angeben aber dies wird typischerweise Interaktionen mit anderen Nutzern auf Basis der E-Mail-Adresse verhindern.",
|
||||
"Please check your email to continue registration.": "Bitte prüfe deine E-Mail um mit der Registrierung fortzufahren.",
|
||||
"Token incorrect": "Token inkorrekt",
|
||||
"A text message has been sent to": "Eine Textnachricht wurde gesandt an",
|
||||
"A text message has been sent to": "Eine Textnachricht wurde gesendet an",
|
||||
"Please enter the code it contains:": "Bitte gebe den Code ein, den sie enthält:",
|
||||
"powered by Matrix": "betrieben mit Matrix",
|
||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Wenn du keine E-Mail-Adresse angibst, wirst du nicht in der Lage sein, dein Passwort zurückzusetzen. Bist du sicher?",
|
||||
|
@ -786,13 +784,13 @@
|
|||
"This image cannot be displayed.": "Dieses Bild kann nicht angezeigt werden.",
|
||||
"Error decrypting video": "Video-Entschlüsselung fehlgeschlagen",
|
||||
"Import room keys": "Importiere Raum-Schlüssel",
|
||||
"File to import": "Datei zum Importieren",
|
||||
"File to import": "Zu importierende Datei",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Das Einladen der folgenden Nutzer in den Raum \"%(roomName)s\" ist fehlgeschlagen:",
|
||||
"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.": "Bist du sicher, dass du dieses Ereignis löschen willst? Wenn du einen Raum-Namen- oder Themen-Änderung löscht, kann dies die Änderung rückgängig machen.",
|
||||
"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.": "Bist du sicher, dass du dieses Ereignis entfernen (löschen) möchtest? Wenn du die Änderung eines Raum-Namens oder eines Raum-Themas löscht, kann dies dazu führen, dass die ursprüngliche Änderung rückgängig gemacht wird.",
|
||||
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Dieser Prozess erlaubt es dir, die Schlüssel für in verschlüsselten Räumen empfangene Nachrichten in eine lokale Datei zu exportieren. In Zukunft wird es möglich sein, diese Datei in einen anderen Matrix-Client zu importieren, sodass dieser Client ebenfalls diese Nachrichten entschlüsseln kann.",
|
||||
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Die exportierte Datei erlaubt jedem, der diese lesen kann, jede verschlüsselte Nachricht zu entschlüsseln die du sehen kannst. Du solltest sie also sicher verwahren. Um dabei zu helfen, solltest du unten eine Passphrase eingeben, die dazu verwendet wird, die exportierten Daten zu verschlüsseln. Anschließend ist es nur möglich die Daten zu lesen, wenn dieselbe Passphrase verwendet wird.",
|
||||
"Analytics": "Analyse",
|
||||
"Opt out of analytics": "Zustimmung zur Übermittlung von Analysedaten verweigern",
|
||||
"Analytics": "Anonymisierte Analysedaten",
|
||||
"Opt out of analytics": "Zustimmung zur Übermittlung von anonymisierten Analysedaten verweigern",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot sammelt anonymisierte Analysedaten, um die Anwendung kontinuierlich verbessern zu können.",
|
||||
"Add an Integration": "Eine Integration hinzufügen",
|
||||
"Removed or unknown message type": "Gelöschte oder unbekannter Nachrichten-Typ",
|
||||
|
@ -811,14 +809,14 @@
|
|||
"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.": "Wenn du zuvor eine aktuellere Version von Riot verwendet hast, ist deine Sitzung eventuell inkompatibel mit dieser Version. Bitte schließe dieses Fenster und kehre zur aktuelleren Version zurück.",
|
||||
"Blacklist": "Blockieren",
|
||||
"Unblacklist": "Entblockieren",
|
||||
"Unverify": "Entverifizieren",
|
||||
"Unverify": "Verifizierung widerrufen",
|
||||
"This Home Server would like to make sure you are not a robot": "Dieser Heimserver möchte sicherstellen, dass du kein Roboter bist",
|
||||
"Drop file here to upload": "Datei hier loslassen zum hochladen",
|
||||
"Idle": "Untätig",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Wir empfehlen dir für jedes Gerät durch den Verifizierungsprozess zu gehen um zu bestätigen, dass sie ihrem legitimierten Besitzer gehören, aber du kannst die Nachrichten ohne Verifizierung erneut senden, wenn du es vorziehst.",
|
||||
"Ongoing conference call%(supportedText)s. %(joinText)s": "Laufendes Konferenzgespräch%(supportedText)s. %(joinText)s",
|
||||
"Ongoing conference call%(supportedText)s.": "Laufendes Konferenzgespräch%(supportedText)s.",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Du wirst jetzt auf die Website eines Drittanbieters weitergeleitet, damit du dein Konto für die Verwendung von %(integrationsUrl)s authentifizieren kannst. Möchtest du fortfahren?",
|
||||
"Disable URL previews for this room (affects only you)": "Deaktiviere die URL-Vorschau für diesen Raum (betrifft nur dich)",
|
||||
"Disable URL previews for this room (affects only you)": "URL-Vorschau für diesen Raum deaktivieren (betrifft nur dich)",
|
||||
"Start automatically after system login": "Starte automatisch nach System-Login",
|
||||
"Desktop specific": "Desktopspezifisch",
|
||||
"Jump to first unread message.": "Zur ersten ungelesenen Nachricht springen.",
|
||||
|
@ -828,32 +826,28 @@
|
|||
"Invited": "Eingeladen",
|
||||
"Set a Display Name": "Setze einen Anzeigenamen",
|
||||
"for %(amount)ss": "für %(amount)ss",
|
||||
"for %(amount)sm": "für %(amount)sm",
|
||||
"for %(amount)sm": "seit %(amount)smin",
|
||||
"for %(amount)sh": "für %(amount)sh",
|
||||
"for %(amount)sd": "für %(amount)sd",
|
||||
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s entfernte Raum-Bild.",
|
||||
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s hat das Raum-Bild entfernt.",
|
||||
"VoIP": "VoIP",
|
||||
"No Webcams detected": "Keine Webcam erkannt",
|
||||
"Missing Media Permissions, click here to request.": "Fehlende Medienberechtigungen. Klicke hier um anzufragen.",
|
||||
"No Microphones detected": "Keine Mikrophone erkannt",
|
||||
"Missing Media Permissions, click here to request.": "Fehlende Medienberechtigungen. Hier klicken, um Berechtigungen zu beantragen.",
|
||||
"No Microphones detected": "Keine Mikrofone erkannt",
|
||||
"No media permissions": "Keine Medienberechtigungen",
|
||||
"You may need to manually permit Riot to access your microphone/webcam": "Du musst anscheinend Riot manuell den Zugriff zu deinem Mikrophon/Webcam gewähren",
|
||||
"You may need to manually permit Riot to access your microphone/webcam": "Gegebenenfalls kann es notwendig sein, dass du Riot manuell den Zugriff auf dein Mikrofon bzw. deine Webcam gewähren musst",
|
||||
"Default Device": "Standard-Gerät",
|
||||
"Microphone": "Mikrophone",
|
||||
"Microphone": "Mikrofon",
|
||||
"Camera": "Kamera",
|
||||
"Conference call failed.": "Konferenzgespräch fehlgeschlagen.",
|
||||
"Conference calling is in development and may not be reliable.": "Konferenzgespräche sind in der Entwicklung und möglicherweise nicht zuverlässig.",
|
||||
"Device already verified!": "Gerät bereits verifiziert!",
|
||||
"Export": "Export",
|
||||
"Failed to register as guest:": "Registrieren als Gast schlug fehl:",
|
||||
"Failed to register as guest:": "Die Registrierung als Gast ist fehlgeschlagen:",
|
||||
"Guest access is disabled on this Home Server.": "Gastzugang ist auf diesem Heimserver deaktivert.",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Gastnutzer können keine neuen Räume erstellen. Bitte registriere dich um Räume zu erstellen und Chats zu starten.",
|
||||
"Import": "Import",
|
||||
"Incorrect username and/or password.": "Inkorrekter Nutzername und/oder Passwort.",
|
||||
"Results from DuckDuckGo": "Ergebnisse von DuckDuckGo",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Server nicht verfügbar, überlastet oder etwas anderes lief falsch.",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Den Signaturschlüssel den du bereitstellst stimmt mit dem Schlüssel den du von %(userId)s's Gerät %(deviceId)s empfangen hast überein. Gerät als verifiziert markiert.",
|
||||
"Add a topic": "Füge Thema hinzu",
|
||||
"Add a topic": "Thema hinzufügen",
|
||||
"Anyone": "Jeder",
|
||||
"Are you sure you want to leave the room '%(roomName)s'?": "Bist du sicher, dass du den Raum '%(roomName)s' verlassen willst?",
|
||||
"Custom level": "Benutzerdefiniertes Berechtigungslevel",
|
||||
|
@ -862,13 +856,13 @@
|
|||
"device id: ": "Geräte-ID: ",
|
||||
"Device key:": "Geräte-Schlüssel:",
|
||||
"Email address (optional)": "E-Mail-Adresse (optional)",
|
||||
"List this room in %(domain)s's room directory?": "Liste diesen Raum in %(domain)s's Raumverzeichnis?",
|
||||
"Mobile phone number (optional)": "Handynummer (optional)",
|
||||
"List this room in %(domain)s's room directory?": "Diesen Raum zum Raum-Verzeichnis von %(domain)s hinzufügen?",
|
||||
"Mobile phone number (optional)": "Mobilfunknummer (optional)",
|
||||
"Password:": "Passwort:",
|
||||
"Register": "Registrieren",
|
||||
"Save": "Speichern",
|
||||
"Setting a user name will create a fresh account": "Einen Nutzernamen zu setzen wird ein neues Konto erzeugen",
|
||||
"Tagged as: ": "Getaggt als: ",
|
||||
"Setting a user name will create a fresh account": "Die Eingabe eines Benutzernamens wird ein neues Konto erzeugen",
|
||||
"Tagged as: ": "Markiert als: ",
|
||||
"This Home Server does not support login using email address.": "Dieser Heimserver unterstützt den Login mittels E-Mail-Adresse nicht.",
|
||||
"There was a problem logging in.": "Es gab ein Problem beim anmelden.",
|
||||
"Unknown (user, device) pair:": "Unbekanntes (Nutzer-/Gerät-)Paar:",
|
||||
|
@ -876,17 +870,105 @@
|
|||
"Unrecognised command:": "Unbekannter Befehl:",
|
||||
"Unrecognised room alias:": "Unbekannter Raum-Alias:",
|
||||
"Use compact timeline layout": "Nutze kompaktes Zeitstrahl-Layout",
|
||||
"Verified key": "Bestätigter Schlüssel",
|
||||
"Verified key": "Verifizierter Schlüssel",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "WARNUNG: Gerät bereits verifiziert, aber Schlüssel sind NICHT GLEICH!",
|
||||
"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 Gerät %(deviceId)s ist \"%(fprint)s\" welche nicht dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmen. Dies kann bedeuten, dass deine Kommunikation abgefangen wird!",
|
||||
"You are already in a call.": "Du bist bereits in einem Gespräch.",
|
||||
"You cannot place a call with yourself.": "Du kannst keinen Anruf mit dir selbst starten.",
|
||||
"You cannot place VoIP calls in this browser.": "Du kannst keine VoIP-Gespräche in diesem Browser starten.",
|
||||
"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 invaliden Kontakt eingegeben. Versuche es mit der Matrix-ID oder E-Mail-Adresse.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Heimserver verbunden zu sein.",
|
||||
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName änderte das Raum-Bild zu <img/>",
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s änderte das Bild für %(roomName)s",
|
||||
"Hide removed messages": "Verberge gelöschte Nachrichten"
|
||||
"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-ID oder der E-Mail-Adresse.",
|
||||
"$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",
|
||||
"Start new chat": "Neuen Chat starten",
|
||||
"Disable markdown formatting": "Markdown-Formatierung deaktivieren",
|
||||
"Add": "Hinzufügen",
|
||||
"%(count)s new messages.one": "%(count)s neue Nachricht",
|
||||
"%(count)s new messages.other": "%(count)s neue Nachrichten",
|
||||
"Error: Problem communicating with the given homeserver.": "Fehler: Problem beim kommunizieren mit dem angegebenen Heimserver.",
|
||||
"Failed to fetch avatar URL": "Abrufen der Avatar-URL fehlgeschlagen",
|
||||
"The phone number entered looks invalid": "Die eingegebene Telefonnummer scheint ungültig zu sein",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register.": "Dieser Raum ist privat oder für Gäste nicht betretbar. Du kannst evtl. beitreten wenn du dich registrierst.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Es wurde versucht, einen bestimmten Punkt im Chatverlauf dieses Raumes zu laden. Dir fehlt jedoch die Berechtigung, die betreffende Nachricht zu sehen.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Es wurde versucht, einen bestimmten Punkt im Chatverlauf dieses Raumes zu laden, der Punkt konnte jedoch nicht gefunden werden.",
|
||||
"Uploading %(filename)s and %(count)s others.zero": "%(filename)s wird hochgeladen",
|
||||
"Uploading %(filename)s and %(count)s others.one": "%(filename)s und %(count)s weitere Dateien werden hochgeladen",
|
||||
"Uploading %(filename)s and %(count)s others.other": "%(filename)s und %(count)s weitere Dateien werden hochgeladen",
|
||||
"You must <a>register</a> to use this functionality": "Du musst dich <a>registrieren</a>, um diese Funktionalität nutzen zu können",
|
||||
"<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.": "<a>Alle erneut senden</a> oder <a>alle verwerfen</a>. Du kannst auch einzelne Nachrichten erneut senden oder verwerfen.",
|
||||
"Create new room": "Neuen Raum erstellen",
|
||||
"Welcome page": "Willkommensseite",
|
||||
"Room directory": "Raum-Verzeichnis",
|
||||
"Start chat": "Chat starten",
|
||||
"New Password": "Neues Passwort",
|
||||
"Start chatting": "Chat beginnen",
|
||||
"Start Chatting": "Starte Gespräche",
|
||||
"Click on the button below to start chatting!": "Unten auf den Button klicken, um einen Chat zu beginnen!",
|
||||
"Create a new chat or reuse an existing one": "Neuen Chat erstellen oder einen vorhandenen Chat fortsetzen",
|
||||
"You already have existing direct chats with this user:": "Du hast bereits direkte Chats mit diesem Nutzer:",
|
||||
"Username available": "Benutzername ist verfügbar",
|
||||
"Username not available": "Benutzername ist nicht verfügbar",
|
||||
"Something went wrong!": "Etwas ging schief!",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Dies wird dein zukünftiger Benutzername auf dem <span></span> Heimserver. Alternativ kannst du auch einen <a>anderen Server</a> auswählen.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Wenn du bereits ein Matrix-Benutzerkonto hast, kannst du dich stattdessen auch direkt <a>anmelden</a>.",
|
||||
"Home": "Start",
|
||||
"Username invalid: %(errMessage)s": "Ungültiger Benutzername: %(errMessage)s",
|
||||
"a room": "einen Raum",
|
||||
"Accept": "Akzeptieren",
|
||||
"Active call (%(roomName)s)": "Aktiver Anruf (%(roomName)s)",
|
||||
"Admin tools": "Admin-Werkzeuge",
|
||||
"And %(count)s more...": "Und %(count)s weitere...",
|
||||
"Alias (optional)": "Alias (optional)",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Verbindung zum Heimserver fehlgeschlagen - bitte prüfe deine Verbindung, stelle sicher, dass dem <a>SSL-Zertifikat deines Heimservers</a> vertraut wird und keine Browser-Erweiterung Anfragen blockiert.",
|
||||
"<a>Click here</a> to join the discussion!": "<a>Klicke hier</a> um der Diskussion beizuwohnen!",
|
||||
"Close": "Schließen",
|
||||
"Custom": "Erweitert",
|
||||
"Decline": "Ablehnen",
|
||||
"Disable Notifications": "Benachrichtigungen deaktivieren",
|
||||
"Drop File Here": "Lasse Datei hier los",
|
||||
"Enable Notifications": "Benachrichtigungen aktivieren",
|
||||
"Encrypted by a verified device": "Von einem vertrauten Gerät verschlüsselt",
|
||||
"Encrypted by an unverified device": "Von einem nicht vertrauten Gerät verschlüsselt",
|
||||
"Failed to upload profile picture!": "Hochladen des Profilbild's fehlgeschlagen!",
|
||||
"Incoming call from %(name)s": "Eingehender Anruf von %(name)s",
|
||||
"Incoming video call from %(name)s": "Eingehender Video-Anruf von %(name)s",
|
||||
"Incoming voice call from %(name)s": "Eingehender Sprach-Anruf von %(name)s",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Mit <voiceText>Sprache</voiceText> oder <videoText>Video</videoText> beitreten.",
|
||||
"Last seen": "Zuletzt gesehen",
|
||||
"Level:": "Level:",
|
||||
"No display name": "Kein Anzeigename",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Ansonsten <a>klicke hier</a> um einen Fehlerbericht zu senden.",
|
||||
"Private Chat": "Privater Chat",
|
||||
"Public Chat": "Öffentlicher Chat",
|
||||
"Reason: %(reasonText)s": "Grund: %(reasonText)s",
|
||||
"Rejoin": "Erneut beitreten",
|
||||
"Room contains unknown devices": "Raum enthält unbekannte Geräte",
|
||||
"%(roomName)s does not exist.": "%(roomName)s existert nicht.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s ist aktuell nicht zugreifbar.",
|
||||
"Searching known users": "Suche nach bekannten Nutzern",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Gesehen von %(userName)s um %(dateTime)s",
|
||||
"Send anyway": "Trotzdem senden",
|
||||
"Set": "Setze",
|
||||
"Start authentication": "Starte Authentifizierung",
|
||||
"Show Text Formatting Toolbar": "Zeige text-formatierende Werkzeugleiste",
|
||||
"This invitation was sent to an email address which is not associated with this account:": "Diese Einledung wurde an eine E-Mail-Adresse gesendet, die nicht mit diesem Konto verknüpft ist:",
|
||||
"This room": "Dieser Raum",
|
||||
"To link to a room it must have <a>an address</a>.": "Um einen Raum zu verlinken, muss er <a>eine Adresse</a> haben.",
|
||||
"Undecryptable": "Nicht entschlüsselbar",
|
||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Kann nicht feststellen, ob die Adresse an die diese Einladung gesendet wurde mit einer übereinstimmt, die zu deinem Konto gehört.",
|
||||
"Unencrypted message": "Nicht verschlüsselbare Nachricht",
|
||||
"unknown caller": "Unbekannter Anrufer",
|
||||
"Unnamed Room": "Unbenannter Raum",
|
||||
"Unverified": "Nicht verifiziert",
|
||||
"Upload new:": "Neue(s) hochladen:",
|
||||
"%(user)s is a": "%(user)s ist ein",
|
||||
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (Berechtigungslevel %(powerLevelNumber)s)",
|
||||
"Verified": "Verifiziert",
|
||||
"Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?": "Möchtest du diese Einladung <acceptText>akzeptieren</acceptText> oder <declineText>ablehnen</declineText>?",
|
||||
"You have been banned from %(roomName)s by %(userName)s.": "Du wurdest von %(userName)s aus dem Raum %(roomName)s ausgeschlossen.",
|
||||
"You have been kicked from %(roomName)s by %(userName)s.": "Du wurdest von %(userName)s aus dem Raum %(roomName)s gekickt.",
|
||||
"You may wish to login with a different account, or add this email to this account.": "Du möchtest dich evtl. mit einem anderen Konto anmelden oder diese E-Mail-Adresse diesem Konto hinzufügen.",
|
||||
"Your home server does not support device management.": "Dein Heimserver unterstützt kein Geräte-Management.",
|
||||
"(~%(count)s results).one": "(~%(count)s Ergebnis)",
|
||||
"(~%(count)s results).other": "(~%(count)s Ergebnis)",
|
||||
"Device Name": "Geräte-Name"
|
||||
}
|
||||
|
|
391
src/i18n/strings/el.json
Normal file
391
src/i18n/strings/el.json
Normal file
|
@ -0,0 +1,391 @@
|
|||
{
|
||||
"af": "Αφρικάνικα",
|
||||
"Error": "Σφάλμα",
|
||||
"Failed to forget room %(errCode)s": "Δεν ήταν δυνατή η διαγραφή του δωματίου (%(errCode)s)",
|
||||
"Failed to join the room": "Δεν ήταν δυνατή η σύνδεση στο δωμάτιο",
|
||||
"Mute": "Σίγαση",
|
||||
"Notifications": "Ειδοποιήσεις",
|
||||
"Operation failed": "Η λειτουργία απέτυχε",
|
||||
"Please Register": "Παρακαλούμε εγγραφείτε",
|
||||
"Remove": "Αφαίρεση",
|
||||
"Search": "Αναζήτηση",
|
||||
"Settings": "Ρυθμίσεις",
|
||||
"unknown error code": "άγνωστος κωδικός σφάλματος",
|
||||
"Sunday": "Κυριακή",
|
||||
"ar-ae": "Αραβικά (Η.Α.Ε)",
|
||||
"ar-bh": "Αραβικά (Μπαχρέιν)",
|
||||
"ar-dz": "Αραβικά (Αλγερία)",
|
||||
"ar-eg": "Αραβικά (Αίγυπτος)",
|
||||
"ar-iq": "Αραβικά (Ιράκ)",
|
||||
"ar-jo": "Αραβικά (Ιορδανία)",
|
||||
"ar-kw": "Αραβικά (Κουβέιτ)",
|
||||
"ar-lb": "Αραβικά (Λίβανος)",
|
||||
"ar-ly": "Αραβικά (Λιβύη)",
|
||||
"ar-ma": "Αραβικά (Μαρόκο)",
|
||||
"ar-om": "Αραβικά (Ομάν)",
|
||||
"ar-qa": "Αραβικά (Κατάρ)",
|
||||
"ar-sa": "Αραβικά (Σαουδική Αραβία)",
|
||||
"ar-sy": "Αραβικά (Συρία)",
|
||||
"ar-tn": "Αραβικά (Τυνισία)",
|
||||
"ar-ye": "Αραβικά (Υεμένη)",
|
||||
"accept": "αποδοχή",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s δέχτηκε την πρόσκληση.",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s δέχτηκες την πρόσκληση για %(displayName)s.",
|
||||
"Account": "Λογαριασμός",
|
||||
"Add a topic": "Πρόσθεσε μια περιγραφή",
|
||||
"Add email address": "Πρόσθεσε ένα email",
|
||||
"Add phone number": "Πρόσθεσε έναν αριθμό τηλεφώνου",
|
||||
"Admin": "Διαχειριστής",
|
||||
"VoIP": "VoIP",
|
||||
"No Microphones detected": "Δεν εντοπίστηκε μικρόφωνο",
|
||||
"No Webcams detected": "Δεν εντοπίστηκε κάμερα",
|
||||
"Default Device": "Προεπιλεγμένη Συσκευή",
|
||||
"Microphone": "Μικρόφωνο",
|
||||
"Camera": "Κάμερα",
|
||||
"Advanced": "Προχωρημένα",
|
||||
"Algorithm": "Αλγόριθμος",
|
||||
"Hide removed messages": "Κρύψε διαγραμμένα μηνύματα",
|
||||
"Authentication": "Πιστοποίηση",
|
||||
"and": "και",
|
||||
"An email has been sent to": "Ένα email στάλθηκε σε",
|
||||
"A new password must be entered.": "Ο νέος κωδικός πρέπει να εισαχθεί.",
|
||||
"%(senderName)s answered the call.": "Ο χρήστης %(senderName)s απάντησε.",
|
||||
"An error has occurred.": "Ένα σφάλμα προέκυψε",
|
||||
"Anyone": "Oποιοσδήποτε",
|
||||
"Are you sure?": "Είσαι σίγουρος;",
|
||||
"Are you sure you want to leave the room '%(roomName)s'?": "Είσαι σίγουρος οτι θές να φύγεις από το δωμάτιο '%(roomName)s';",
|
||||
"Are you sure you want to reject the invitation?": "Είσαι σίγουρος οτι θες να απορρίψεις την πρόσκληση;",
|
||||
"Are you sure you want to upload the following files?": "Είσαι σίγουρος οτι θές να ανεβάσεις τα ακόλουθα αρχεία;",
|
||||
"Attachment": "Επισύναψη",
|
||||
"%(senderName)s banned %(targetName)s.": "Ο χρήστης %(senderName)s έδιωξε τον χρήστη %(targetName)s.",
|
||||
"Autoplay GIFs and videos": "Αυτόματη αναπαραγωγή GIFs και βίντεο",
|
||||
"Bug Report": "Αναφορά Σφάλματος",
|
||||
"anyone": "οποιοσδήποτε",
|
||||
"Anyone who knows the room's link, apart from guests": "Oποιοσδήποτε",
|
||||
"all room members, from the point they joined": "όλα τα μέλη του δωματίου, από τη στιγμή που συνδέθηκαν",
|
||||
"%(items)s and %(lastItem)s": "%(items)s %(lastItem)s",
|
||||
"be": "Λευκορώσικα",
|
||||
"bg": "Βουλγάρικα",
|
||||
"ca": "Καταλανικά",
|
||||
"cs": "Τσέχικα",
|
||||
"da": "Δανέζικα",
|
||||
"de-at": "Γερμανικά (Αυστρία)",
|
||||
"de-ch": "Γερμανικά (Ελβετία)",
|
||||
"de": "Γερμανικά",
|
||||
"de-li": "Γερμανικά (Λιχτενστάιν)",
|
||||
"de-lu": "Γερμανικά (Λουξεμβούργο)",
|
||||
"el": "Ελληνικά",
|
||||
"en-au": "Αγγλικά (Αυστραλία)",
|
||||
"en-bz": "Αγγλικά (Μπελίζε)",
|
||||
"en-ca": "Αγγλικά (Καναδάς)",
|
||||
"en": "Αγγλικά",
|
||||
"en-gb": "Αγγλικά (Ηνωμένο Βασίλειο)",
|
||||
"en-ie": "Αγγλικά (Ιρλανδία)",
|
||||
"en-jm": "Αγγλικά (Τζαμάικα)",
|
||||
"en-nz": "Αγγλικά (Νέα Ζηλανδία)",
|
||||
"en-tt": "Αγγλικά (Τρινιντάντ)",
|
||||
"en-us": "Αγγλικά (Ηνωμένες Πολιτείες)",
|
||||
"en-za": "Αγγλικά (Νότια Αφρική)",
|
||||
"es-ar": "Ισπανικά (Αργεντινή)",
|
||||
"es-bo": "Ισπανικά (Βολιβία)",
|
||||
"es-cl": "Ισπανικά (Χιλή)",
|
||||
"es-co": "Ισπανικά (Κολομβία)",
|
||||
"es-cr": "Ισπανικά (Κόστα Ρίκα)",
|
||||
"es-do": "Ισπανικά (Δομινικανή Δημοκρατία)",
|
||||
"es-ec": "Ισπανικά (Ισημερινός)",
|
||||
"es-gt": "Ισπανικά (Γουατεμάλα)",
|
||||
"es-hn": "Ισπανικά (Ονδούρα)",
|
||||
"es-mx": "Ισπανικά (Μεξικό)",
|
||||
"es-ni": "Ισπανικά (Νικαράγουα)",
|
||||
"es-pa": "Ισπανικά (Παναμάς)",
|
||||
"es-pe": "Ισπανικά (Περού)",
|
||||
"es-pr": "Ισπανικά (Πουέρτο Ρίκο)",
|
||||
"es-py": "Ισπανικά (Παραγουάη)",
|
||||
"es": "Ισπανικά (Ισπανία)",
|
||||
"es-sv": "Ισπανικά (Ελ Σαλβαδόρ)",
|
||||
"es-uy": "Ισπανικά (Ουρουγουάη)",
|
||||
"es-ve": "Ισπανικά (Βενεζουέλα)",
|
||||
"et": "Εσθονικά",
|
||||
"eu": "Βασκική (βασκική)",
|
||||
"fa": "Φάρσι",
|
||||
"fi": "Φινλανδικά",
|
||||
"fo": "Φαρόε",
|
||||
"fr-be": "Γαλλικά (Βέλγιο)",
|
||||
"fr-ca": "Γαλλικά (Καναδάς)",
|
||||
"fr-ch": "Γαλλικά (Ελβετία)",
|
||||
"fr": "Γαλλικά",
|
||||
"fr-lu": "Γαλλικά (Λουξεμβούργο)",
|
||||
"ga": "Ιρλανδικά",
|
||||
"gd": "Γαελική (Σκωτία)",
|
||||
"he": "Εβραϊκά",
|
||||
"hi": "Χίντι",
|
||||
"hr": "Κροατικά",
|
||||
"hu": "Ουγγρικά",
|
||||
"is": "Ισλανδικά",
|
||||
"it-ch": "Ιταλικά (Ελβετία)",
|
||||
"it": "Ιταλικά",
|
||||
"ja": "Ιαπωνικά",
|
||||
"ji": "Γίντις",
|
||||
"ko": "Κορεάτικα",
|
||||
"lt": "Λιθουανικά",
|
||||
"mk": "Μακεδονική (ΠΓΔΜ)",
|
||||
"ms": "Μαλαισίας",
|
||||
"mt": "Μαλτέζικα",
|
||||
"nl-be": "Ολλανδικά (Βέλγιο)",
|
||||
"nl": "Ολλανδικά",
|
||||
"no": "Νορβηγικά",
|
||||
"pl": "Πολωνέζικα",
|
||||
"pt-br": "Πορτογαλικά Βραζιλίας",
|
||||
"pt": "Πορτογαλικά",
|
||||
"rm": "Ραιτορωμαϊκά",
|
||||
"ro-mo": "Ρουμάνικα (Δημοκρατία της Μολδαβίας)",
|
||||
"ro": "Ρουμάνικα",
|
||||
"ru-mo": "Ρώσικα (Δημοκρατία της Μολδαβίας)",
|
||||
"ru": "Ρώσικα",
|
||||
"sb": "Σορβικά",
|
||||
"sk": "Σλοβάκικα",
|
||||
"sl": "Σλοβενικά",
|
||||
"sq": "Αλβανικά",
|
||||
"sr": "Σερβικά",
|
||||
"sv-fi": "Σουηδικά (Φινλανδία)",
|
||||
"sv": "Σουηδικά",
|
||||
"sx": "Σούτου",
|
||||
"sz": "Σάμη (Λαπωνικά)",
|
||||
"th": "Ταϊλανδέζικα",
|
||||
"tn": "Τσουάνα",
|
||||
"tr": "Τουρκικά",
|
||||
"ts": "Τσονγκά",
|
||||
"uk": "Ουκρανικά",
|
||||
"ur": "Ουρντού",
|
||||
"ve": "Venda",
|
||||
"vi": "Βιετναμέζικα",
|
||||
"xh": "Xhosa",
|
||||
"zh-cn": "Κινέζικα (ΛΔΚ)",
|
||||
"zh-hk": "Κινέζικα (ΕΔΠ Χονγκ Κονγκ)",
|
||||
"zh-sg": "Κινέζικα (Σιγκαπούρη)",
|
||||
"zh-tw": "Κινέζικα (Ταϊβάν)",
|
||||
"zu": "Ζουλού",
|
||||
"id": "Ινδονησιακά",
|
||||
"lv": "Λετονικά",
|
||||
"A registered account is required for this action": "Ένας εγγεγραμμένος λογαριασμός απαιτείται για αυτή την ενέργεια",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Ένα μήνυμα στάλθηκε στο +%(msisdn)s. Παρακαλώ γράψε τον κωδικό επαλήθευσης που περιέχει",
|
||||
"Access Token:": "Κωδικός Πρόσβασης:",
|
||||
"Always show message timestamps": "Δείχνε πάντα ένδειξη ώρας στα μηνύματα",
|
||||
"all room members": "όλα τα μέλη του δωματίου",
|
||||
"all room members, from the point they are invited": "όλα τα μέλη του δωματίου, από τη στιγμή που προσκλήθηκαν",
|
||||
"an address": "μία διεύθηνση",
|
||||
"%(items)s and %(remaining)s others": "%(items)s και %(remaining)s ακόμα",
|
||||
"%(items)s and one other": "%(items)s και ένας ακόμα",
|
||||
"and %(overflowCount)s others...": "και %(overflowCount)s άλλοι...",
|
||||
"and one other...": "και ένας ακόμα...",
|
||||
"%(names)s and %(lastPerson)s are typing": "%(names)s και %(lastPerson)s γράφουν",
|
||||
"%(names)s and one other are typing": "%(names)s και ένας ακόμα γράφουν",
|
||||
"%(names)s and %(count)s others are typing": "%(names)s και %(count)s άλλοι γράφουν",
|
||||
"Anyone who knows the room's link, including guests": "Οποιοσδήποτε γνωρίζει τον σύνδεδμο του δωματίου, συμπεριλαμβάνωντας τους επισκέπτες",
|
||||
"Blacklisted": "Στη μαύρη λίστα",
|
||||
"Can't load user settings": "Δεν είναι δυνατή η φόρτωση των ρυθμίσεων χρήστη",
|
||||
"Change Password": "Αλλαγή Κωδικού",
|
||||
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "ο χρήστης %(senderName)s άλλαξε το όνομά του από %(oldDisplayName)s σε %(displayName)s.",
|
||||
"%(senderName)s changed their profile picture.": "ο χρήστης %(senderName)s άλλαξε τη φωτογραφία του προφίλ του.",
|
||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "Ο χρήστης %(senderDisplayName)s άλλαξε το όνομα του δωματίου σε %(roomName)s.",
|
||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "Ο χρήστης %(senderDisplayName)s άλλαξε το θέμα σε \"%(topic)s\".",
|
||||
"Clear Cache and Reload": "Καθάρισε την μνήμη και Ανανέωσε",
|
||||
"Clear Cache": "Καθάρισε την μνήμη",
|
||||
"Bans user with given id": "Διώχνει τον χρήστη με το συγκεκριμένο id",
|
||||
"%(senderDisplayName)s removed the room name.": "Ο χρήστης %(senderDisplayName)s διέγραψε το όνομα του δωματίου.",
|
||||
"Changes your display nickname": "Αλλάζει το όνομα χρήστη",
|
||||
"Click here": "Κάνε κλικ εδώ",
|
||||
"Drop here %(toAction)s": "Απόθεση εδώ %(toAction)s",
|
||||
"Conference call failed.": "Η κλήση συνδιάσκεψης απέτυχε.",
|
||||
"powered by Matrix": "βασισμένο στο πρωτόκολλο Matrix",
|
||||
"Confirm password": "Επιβεβαίωση κωδικού",
|
||||
"Confirm your new password": "Επιβεβαίωση του νέου κωδικού",
|
||||
"Continue": "Συνέχεια",
|
||||
"Create an account": "Δημιουργία λογαριασμού",
|
||||
"Create Room": "Δημιουργία Δωματίου",
|
||||
"Cryptography": "Κρυπτογραφία",
|
||||
"Current password": "Τωρινός κωδικός",
|
||||
"Curve25519 identity key": "Κλειδί ταυτότητας Curve25519",
|
||||
"Custom level": "Προσαρμοσμένο επίπεδο",
|
||||
"/ddg is not a command": "/ddg δεν αναγνωρίζεται ως εντολή",
|
||||
"Deactivate Account": "Απενεργοποίηση Λογαριασμού",
|
||||
"Deactivate my account": "Απενεργοποίηση του λογαριασμού μου",
|
||||
"decline": "απόρριψη",
|
||||
"Decrypt %(text)s": "Αποκρυπτογράφησε %(text)s",
|
||||
"Decryption error": "Σφάλμα αποκρυπτογράφησης",
|
||||
"(default: %(userName)s)": "(προεπιλογή: %(userName)s)",
|
||||
"Delete": "Διαγραφή",
|
||||
"Default": "Προεπιλογή",
|
||||
"Device already verified!": "Η συσκευή έχει ήδη επαληθευτεί!",
|
||||
"Device ID": "ID Συσκευής",
|
||||
"Device ID:": "ID Συσκευής:",
|
||||
"device id: ": "id συσκευής: ",
|
||||
"Device key:": "Κλειδί Συσκευής:",
|
||||
"Devices": "Συσκευές",
|
||||
"Direct Chat": "Απευθείας συνομιλία",
|
||||
"Direct chats": "Απευθείας συνομιλίες",
|
||||
"disabled": "ανενεργό",
|
||||
"Disinvite": "Ανακάλεσε πρόσκληση",
|
||||
"Display name": "Όνομα χρήστη",
|
||||
"Download %(text)s": "Κατέβασε %(text)s",
|
||||
"Ed25519 fingerprint": "Αποτύπωμα Ed25519",
|
||||
"Email": "Ηλ. Αλληλογραφία",
|
||||
"Email address": "Διεύθυνση email",
|
||||
"Email address (optional)": "Διεύθυνση email (προαιρετικό)",
|
||||
"Email, name or matrix ID": "Email, όνομα ή matrix ID",
|
||||
"Emoji": "Εικονίδια",
|
||||
"enabled": "ενεργό",
|
||||
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Τα κρυπτογραφημένα μηνύματα δεν θα είναι ορατά σε εφαρμογές που δεν παρέχουν τη δυνατότητα κρυπτογράφησης",
|
||||
"Encrypted room": "Κρυπτογραφημένο δωμάτιο",
|
||||
"%(senderName)s ended the call.": "%(senderName)s τερμάτισε την κλήση.",
|
||||
"End-to-end encryption information": "Πληροφορίες σχετικά με τη κρυπτογράφηση από άκρο σε άκρο (End-to-end encryption)",
|
||||
"Error decrypting attachment": "Σφάλμα κατά την αποκρυπτογράφηση της επισύναψης",
|
||||
"Event information": "Πληροφορίες μηνύματος",
|
||||
"Existing Call": "Υπάρχουσα Κλήση",
|
||||
"Export": "Εξαγωγή",
|
||||
"Export E2E room keys": "Εξαγωγή κλειδιών κρυπτογραφίας για το δωμάτιο",
|
||||
"Failed to change password. Is your password correct?": "Δεν ήταν δυνατή η αλλαγή του κωδικού πρόσβασης. Είναι σωστός ο κωδικός πρόσβασης;",
|
||||
"Failed to delete device": "Δεν ήταν δυνατή η διαγραφή της συσκευής",
|
||||
"Failed to join room": "Δεν ήταν δυνατή η σύνδεση στο δωμάτιο",
|
||||
"Failed to leave room": "Δεν ήταν δυνατή η αποχώρηση από το δωμάτιο",
|
||||
"Failed to mute user": "Δεν ήταν δυνατή η σίγαση του χρήστη",
|
||||
"Failed to register as guest:": "Δεν ήταν δυνατή η εγγραφή ως επισκέπτης:",
|
||||
"Failed to reject invite": "Δεν ήταν δυνατή η απόρριψη της πρόσκλησης",
|
||||
"Failed to reject invitation": "Δεν ήταν δυνατή η απόρριψη της πρόσκλησης",
|
||||
"Failed to save settings": "Δεν ήταν δυνατή η αποθήκευση των ρυθμίσεων",
|
||||
"Failed to send email": "Δεν ήταν δυνατή η απστολή email",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "Δεν ήταν δυνατή η επαλήθευση του email: βεβαιωθείτε οτι κάνατε κλικ στον σύνδεσμο που σας στάλθηκε",
|
||||
"Favourite": "Αγαπημένο",
|
||||
"favourite": "αγαπημένο",
|
||||
"Favourites": "Αγαπημένα",
|
||||
"Fill screen": "Γέμισε την οθόνη",
|
||||
"Filter room members": "Φίλτραρε τα μέλη",
|
||||
"Forget room": "Διέγραψε το δωμάτιο",
|
||||
"Forgot your password?": "Ξέχασες τον κωδικό σου;",
|
||||
"For security, this session has been signed out. Please sign in again.": "Για λόγους ασφαλείας, αυτή η συνεδρία έχει τερματιστεί. Παρακαλώ συνδεθείτε ξανά.",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Για λόγους ασφαλείας, τα κλειδιά κρυπτογράφησης θα διαγράφονται από τον φυλλομετρητή κατά την αποσύνδεση σας. Εάν επιθυμείτε να αποκρυπτογραφήσετε τις συνομιλίες σας στο μέλλον, εξάγετε τα κλειδιά σας και κρατήστε τα ασφαλή.",
|
||||
"Found a bug?": "Βρήκατε κάποιο πρόβλημα;",
|
||||
"Guest users can't upload files. Please register to upload.": "Οι επισκέπτες δεν μπορούν να ανεβάσουν αρχεία. Παρακαλώ εγγραφείτε πρώτα.",
|
||||
"had": "είχε",
|
||||
"Hangup": "Κλείσε",
|
||||
"Historical": "Ιστορικό",
|
||||
"Homeserver is": "Ο διακομιστής είναι",
|
||||
"Identity Server is": "Διακομιστής Ταυτοποίησης",
|
||||
"I have verified my email address": "Έχω επαληθεύσει το email μου",
|
||||
"Import": "Εισαγωγή",
|
||||
"Import E2E room keys": "Εισαγωγή κλειδιών κρυπτογράφησης",
|
||||
"Incorrect username and/or password.": "Λανθασμένο όνομα χρήστη και/ή κωδικός.",
|
||||
"Incorrect verification code": "Λανθασμένος κωδικός επαλήθευσης",
|
||||
"Interface Language": "Γλώσσα Διεπαφής",
|
||||
"Invalid Email Address": "Μη έγκυρο email",
|
||||
"Invite new room members": "Προσκάλεσε νέα μέλη",
|
||||
"Invited": "Προσκλήθηκε",
|
||||
"Invites": "Προσκλήσεις",
|
||||
"is a": "είναι ένα",
|
||||
"%(displayName)s is typing": "ο χρήστης %(displayName)s γράφει",
|
||||
"Sign in with": "Συνδέσου με",
|
||||
"joined and left": "μπήκε και βγήκε",
|
||||
"joined": "μπήκε",
|
||||
"%(targetName)s joined the room.": "ο χρήστης %(targetName)s συνδέθηκε στο δωμάτιο.",
|
||||
"Jump to first unread message.": "Πήγαινε στο πρώτο μη αναγνωσμένο μήνυμα.",
|
||||
"%(senderName)s kicked %(targetName)s.": "Ο χρήστης %(senderName)s έδιωξε τον χρήστη %(targetName)s.",
|
||||
"Kick": "Διώξε",
|
||||
"Kicks user with given id": "Διώχνει χρήστες με το συγκεκριμένο id",
|
||||
"Labs": "Πειραματικά",
|
||||
"Leave room": "Φύγε από το δωμάτιο",
|
||||
"left and rejoined": "έφυγε και ξανασυνδέθηκε",
|
||||
"left": "έφυγε",
|
||||
"%(targetName)s left the room.": "Ο χρήστης %(targetName)s έφυγε από το δωμάτιο.",
|
||||
"Level": "Επίπεδο",
|
||||
"List this room in %(domain)s's room directory?": "Να εμφανίζεται το δωμάτιο στο γενικό ευρετήριο του διακομιστή %(domain)s;",
|
||||
"Local addresses for this room:": "Τοπική διεύθυνση για το δωμάτιο:",
|
||||
"Logged in as:": "Συνδέθηκες ως:",
|
||||
"Login as guest": "Συνδέσου ως επισκέπτης",
|
||||
"Logout": "Αποσύνδεση",
|
||||
"Low priority": "Χαμηλής προτεραιότητας",
|
||||
"matrix-react-sdk version:": "έκδοση matrix-react-sdk:",
|
||||
"Members only": "Μέλη μόνο",
|
||||
"Message not sent due to unknown devices being present": "Το μήνυμα δεν στάλθηκε γιατί υπάρχουν άγνωστες συσκευές",
|
||||
"Mobile phone number": "Αριθμός κινητού τηλεφώνου",
|
||||
"Click here to fix": "Κάνε κλικ εδώ για διόρθωση",
|
||||
"Command error": "Σφάλμα εντολής",
|
||||
"Commands": "Εντολές",
|
||||
"Conference calls are not supported in encrypted rooms": "Οι κλήσεις συνδιάσκεψης δεν είναι υποστηρίζονται σε κρυπτογραφημένα δωμάτια",
|
||||
"Conference calls are not supported in this client": "Οι κλήσεις συνδιάσκεψης δεν είναι υποστηρίζονται από την εφαρμογή",
|
||||
"Enable encryption": "Ενεργοποίηση κρυπτογραφίας",
|
||||
"Enter Code": "Κωδικός",
|
||||
"Failed to send request.": "Δεν ήταν δυνατή η αποστολή αιτήματος.",
|
||||
"Failed to upload file": "Δεν ήταν δυνατό το ανέβασμα αρχείου",
|
||||
"Failure to create room": "Δεν ήταν δυνατή η δημιουργία δωματίου",
|
||||
"Join Room": "Συνδέσου",
|
||||
"Moderator": "Συντονιστής",
|
||||
"my Matrix ID": "το Matrix ID μου",
|
||||
"Name": "Όνομα",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "Νέα διεύθυνση (e.g. #όνομα:%(localDomain)s)",
|
||||
"New password": "Νέος κωδικός",
|
||||
"New passwords don't match": "Οι νέοι κωδικοί είναι διαφορετικοί",
|
||||
"New passwords must match each other.": "Οι νέοι κωδικόι πρέπει να ταιριάζουν.",
|
||||
"none": "κανένα",
|
||||
"(not supported by this browser)": "(δεν υποστηρίζεται από τον browser)",
|
||||
"<not supported>": "<δεν υποστηρίζεται>",
|
||||
"No more results": "Δεν υπάρχουν άλλα αποτελέσματα",
|
||||
"No results": "Κανένα αποτέλεσμα",
|
||||
"OK": "Εντάξει",
|
||||
"olm version:": "έκδοση olm:",
|
||||
"Password": "Κωδικός",
|
||||
"Password:": "Κωδικός:",
|
||||
"Passwords can't be empty": "",
|
||||
"People": "Άτομα",
|
||||
"Phone": "Τηλέφωνο",
|
||||
"Register": "Εγγραφή",
|
||||
"riot-web version:": "έκδοση riot-web:",
|
||||
"Room Colour": "Χρώμα Δωματίου",
|
||||
"Room name (optional)": "Όνομα Δωματίου (προαιρετικό)",
|
||||
"Rooms": "Δωμάτια",
|
||||
"Save": "Αποθήκευση",
|
||||
"Search failed": "Η αναζήτηση απέτυχε",
|
||||
"Send an encrypted message": "Στείλε ένα κρυπτογραφημένο μήνυμα",
|
||||
"Send a message (unencrypted)": "Στείλε ένα μήνυμα (απλό)",
|
||||
"sent an image": "έστειλε μια εικόνα",
|
||||
"sent a video": "έστειλε ένα βίντεο",
|
||||
"Server error": "Σφάλμα διακομιστή",
|
||||
"Signed Out": "Αποσυνδέθηκες",
|
||||
"Sign in": "Συνδέση",
|
||||
"Sign out": "Αποσύνδεση",
|
||||
"since they joined": "από τη στιγμή που συνδέθηκαν",
|
||||
"since they were invited": "από τη στιγμή που προσκλήθηκαν",
|
||||
"Someone": "Κάποιος",
|
||||
"Start a chat": "Ξεκίνα μια συνομιλία",
|
||||
"This email address is already in use": "Το email χρησιμοποιείται",
|
||||
"This email address was not found": "Η διεύθηνση email δεν βρέθηκε",
|
||||
"Success": "Επιτυχία",
|
||||
"Start Chat": "Συνομιλία",
|
||||
"Cancel": "Ακύρωση",
|
||||
"cancel all": "ακύρωση όλων",
|
||||
"or": "ή",
|
||||
"Custom Server Options": "Προσαρμοσμένες ρυθμίσεις διακομιστή",
|
||||
"Dismiss": "Απόρριψη",
|
||||
"Monday": "Δευτέρα",
|
||||
"Tuesday": "Τρίτη",
|
||||
"Wednesday": "Τετάρτη",
|
||||
"Thursday": "Πέμπτη",
|
||||
"Friday": "Παρασκευή",
|
||||
"Saturday": "Σάββατο",
|
||||
"bold": "έντονα",
|
||||
"italic": "πλάγια",
|
||||
"underline": "υπογράμμιση",
|
||||
"code": "κώδικας",
|
||||
"quote": "αναφορά",
|
||||
"%(oneUser)sleft %(repeats)s times": "%(oneUser)s έφυγε %(repeats)s φορές",
|
||||
"%(severalUsers)sleft": "%(severalUsers)s έφυγαν",
|
||||
"%(oneUser)sleft": "%(oneUser)s έφυγε",
|
||||
"%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s συνδέθηκαν και έφυγαν %(repeats)s φορές",
|
||||
"%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s συνδέθηκε και έφυγε %(repeats)s φορές",
|
||||
"%(severalUsers)sjoined and left": "%(severalUsers)s συνδέθηκαν και έφυγαν",
|
||||
"%(oneUser)sjoined and left": "%(oneUser)s συνδέθηκε και έφυγε",
|
||||
"Close": "Κλείσιμο",
|
||||
"Create new room": "Δημιουργία νέου δωματίου",
|
||||
"Room directory": "Ευρετήριο",
|
||||
"Start chat": "Έναρξη συνομιλίας",
|
||||
"Welcome page": "Αρχική σελίδα"
|
||||
}
|
|
@ -120,16 +120,21 @@
|
|||
"zh-tw":"Chinese (Taiwan)",
|
||||
"zu":"Zulu",
|
||||
"A registered account is required for this action": "A registered account is required for this action",
|
||||
"a room": "a room",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains",
|
||||
"accept": "accept",
|
||||
"Accept": "Accept",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s accepted an invitation.",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",
|
||||
"Account": "Account",
|
||||
"Access Token:": "Access Token:",
|
||||
"Active call (%(roomName)s)": "Active call (%(roomName)s)",
|
||||
"Add": "Add",
|
||||
"Add a topic": "Add a topic",
|
||||
"Add email address": "Add email address",
|
||||
"Add phone number": "Add phone number",
|
||||
"Admin": "Admin",
|
||||
"Admin tools": "Admin tools",
|
||||
"And %(count)s more...": "And %(count)s more...",
|
||||
"VoIP": "VoIP",
|
||||
"Missing Media Permissions, click here to request.": "Missing Media Permissions, click here to request.",
|
||||
"No Microphones detected": "No Microphones detected",
|
||||
|
@ -144,10 +149,10 @@
|
|||
"Hide removed messages": "Hide removed messages",
|
||||
"Always show message timestamps": "Always show message timestamps",
|
||||
"Authentication": "Authentication",
|
||||
"Alias (optional)": "Alias (optional)",
|
||||
"all room members": "all room members",
|
||||
"all room members, from the point they are invited": "all room members, from the point they are invited",
|
||||
"all room members, from the point they joined": "all room members, from the point they joined",
|
||||
"an address": "an address",
|
||||
"and": "and",
|
||||
"%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others",
|
||||
"%(items)s and one other": "%(items)s and one other",
|
||||
|
@ -179,7 +184,7 @@
|
|||
"Bug Report": "Bug Report",
|
||||
"Bulk Options": "Bulk Options",
|
||||
"Call Timeout": "Call Timeout",
|
||||
"Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||
"Can't load user settings": "Can't load user settings",
|
||||
"Change Password": "Change Password",
|
||||
|
@ -196,13 +201,14 @@
|
|||
"Claimed Ed25519 fingerprint key": "Claimed Ed25519 fingerprint key",
|
||||
"Clear Cache and Reload": "Clear Cache and Reload",
|
||||
"Clear Cache": "Clear Cache",
|
||||
"Click here": "Click here",
|
||||
"<a>Click here</a> to join the discussion!": "<a>Click here</a> to join the discussion!",
|
||||
"Click here to fix": "Click here to fix",
|
||||
"Click to mute audio": "Click to mute audio",
|
||||
"Click to mute video": "Click to mute video",
|
||||
"click to reveal": "click to reveal",
|
||||
"Click to unmute video": "Click to unmute video",
|
||||
"Click to unmute audio": "Click to unmute audio",
|
||||
"Close": "Close",
|
||||
"Command error": "Command error",
|
||||
"Commands": "Commands",
|
||||
"Conference call failed.": "Conference call failed.",
|
||||
|
@ -213,16 +219,22 @@
|
|||
"Confirm your new password": "Confirm your new password",
|
||||
"Continue": "Continue",
|
||||
"Could not connect to the integration server": "Could not connect to the integration server",
|
||||
"%(count)s new messages": {
|
||||
"one": "%(count)s new message",
|
||||
"other": "%(count)s new messages"
|
||||
},
|
||||
"Create a new chat or reuse an existing one": "Create a new chat or reuse an existing one",
|
||||
"Create an account": "Create an account",
|
||||
"Create Room": "Create Room",
|
||||
"Cryptography": "Cryptography",
|
||||
"Current password": "Current password",
|
||||
"Curve25519 identity key": "Curve25519 identity key",
|
||||
"Custom": "Custom",
|
||||
"Custom level": "Custom level",
|
||||
"/ddg is not a command": "/ddg is not a command",
|
||||
"Deactivate Account": "Deactivate Account",
|
||||
"Deactivate my account": "Deactivate my account",
|
||||
"decline": "decline",
|
||||
"Decline": "Decline",
|
||||
"Decrypt %(text)s": "Decrypt %(text)s",
|
||||
"Decryption error": "Decryption error",
|
||||
"(default: %(userName)s)": "(default: %(userName)s)",
|
||||
|
@ -239,13 +251,16 @@
|
|||
"Devices will not yet be able to decrypt history from before they joined the room": "Devices will not yet be able to decrypt history from before they joined the room",
|
||||
"Direct Chat": "Direct Chat",
|
||||
"Direct chats": "Direct chats",
|
||||
"Disable Notifications": "Disable Notifications",
|
||||
"disabled": "disabled",
|
||||
"Disable inline URL previews by default": "Disable inline URL previews by default",
|
||||
"Disable markdown formatting": "Disable markdown formatting",
|
||||
"Disinvite": "Disinvite",
|
||||
"Display name": "Display name",
|
||||
"Displays action": "Displays action",
|
||||
"Don't send typing notifications": "Don't send typing notifications",
|
||||
"Download %(text)s": "Download %(text)s",
|
||||
"Drop File Here": "Drop File Here",
|
||||
"Drop here %(toAction)s": "Drop here %(toAction)s",
|
||||
"Drop here to tag %(section)s": "Drop here to tag %(section)s",
|
||||
"Ed25519 fingerprint": "Ed25519 fingerprint",
|
||||
|
@ -255,15 +270,22 @@
|
|||
"Email, name or matrix ID": "Email, name or matrix ID",
|
||||
"Emoji": "Emoji",
|
||||
"Enable encryption": "Enable encryption",
|
||||
"Enable Notifications": "Enable Notifications",
|
||||
"enabled": "enabled",
|
||||
"Encrypted by a verified device": "Encrypted by a verified device",
|
||||
"Encrypted by an unverified device": "Encrypted by an unverified device",
|
||||
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Encrypted messages will not be visible on clients that do not yet implement encryption",
|
||||
"Encrypted room": "Encrypted room",
|
||||
"Encryption is enabled in this room": "Encryption is enabled in this room",
|
||||
"Encryption is not enabled in this room": "Encryption is not enabled in this room",
|
||||
"%(senderName)s ended the call.": "%(senderName)s ended the call.",
|
||||
"End-to-end encryption information": "End-to-end encryption information",
|
||||
"End-to-end encryption is in beta and may not be reliable": "End-to-end encryption is in beta and may not be reliable",
|
||||
"Enter Code": "Enter Code",
|
||||
"Enter passphrase": "Enter passphrase",
|
||||
"Error": "Error",
|
||||
"Error decrypting attachment": "Error decrypting attachment",
|
||||
"Error: Problem communicating with the given homeserver.": "Error: Problem communicating with the given homeserver.",
|
||||
"Event information": "Event information",
|
||||
"Existing Call": "Existing Call",
|
||||
"Export": "Export",
|
||||
|
@ -272,6 +294,7 @@
|
|||
"Failed to change password. Is your password correct?": "Failed to change password. Is your password correct?",
|
||||
"Failed to change power level": "Failed to change power level",
|
||||
"Failed to delete device": "Failed to delete device",
|
||||
"Failed to fetch avatar URL": "Failed to fetch avatar URL",
|
||||
"Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
|
||||
"Failed to join room": "Failed to join room",
|
||||
"Failed to join the room": "Failed to join the room",
|
||||
|
@ -292,6 +315,7 @@
|
|||
"Failed to toggle moderator status": "Failed to toggle moderator status",
|
||||
"Failed to unban": "Failed to unban",
|
||||
"Failed to upload file": "Failed to upload file",
|
||||
"Failed to upload profile picture!": "Failed to upload profile picture!",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "Failed to verify email address: make sure you clicked the link in the email",
|
||||
"Failure to create room": "Failure to create room",
|
||||
"Favourite": "Favourite",
|
||||
|
@ -308,7 +332,7 @@
|
|||
"Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.",
|
||||
"Guests can't set avatars. Please register.": "Guests can't set avatars. Please register.",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Guest users can't create new rooms. Please register to create room and start a chat.",
|
||||
"Guest users can't upload files. Please register to upload": "Guest users can't upload files. Please register to upload",
|
||||
"Guest users can't upload files. Please register to upload.": "Guest users can't upload files. Please register to upload.",
|
||||
"Guests can't use labs features. Please register.": "Guests can't use labs features. Please register.",
|
||||
"Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.",
|
||||
"had": "had",
|
||||
|
@ -316,11 +340,15 @@
|
|||
"Hide read receipts": "Hide read receipts",
|
||||
"Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar",
|
||||
"Historical": "Historical",
|
||||
"Home": "Home",
|
||||
"Homeserver is": "Homeserver is",
|
||||
"Identity Server is": "Identity Server is",
|
||||
"I have verified my email address": "I have verified my email address",
|
||||
"Import": "Import",
|
||||
"Import E2E room keys": "Import E2E room keys",
|
||||
"Incoming call from %(name)s": "Incoming call from %(name)s",
|
||||
"Incoming video call from %(name)s": "Incoming video call from %(name)s",
|
||||
"Incoming voice call from %(name)s": "Incoming voice call from %(name)s",
|
||||
"Incorrect username and/or password.": "Incorrect username and/or password.",
|
||||
"Incorrect verification code": "Incorrect verification code",
|
||||
"Interface Language": "Interface Language",
|
||||
|
@ -333,11 +361,11 @@
|
|||
"Invited": "Invited",
|
||||
"Invites": "Invites",
|
||||
"Invites user with given id to current room": "Invites user with given id to current room",
|
||||
"is a": "is a",
|
||||
"'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
|
||||
"%(displayName)s is typing": "%(displayName)s is typing",
|
||||
"Sign in with": "Sign in with",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.",
|
||||
"Join Room": "Join Room",
|
||||
"joined and left": "joined and left",
|
||||
"joined": "joined",
|
||||
|
@ -348,11 +376,12 @@
|
|||
"Kick": "Kick",
|
||||
"Kicks user with given id": "Kicks user with given id",
|
||||
"Labs": "Labs",
|
||||
"Last seen": "Last seen",
|
||||
"Leave room": "Leave room",
|
||||
"left and rejoined": "left and rejoined",
|
||||
"left": "left",
|
||||
"%(targetName)s left the room.": "%(targetName)s left the room.",
|
||||
"Level": "Level",
|
||||
"Level:": "Level:",
|
||||
"List this room in %(domain)s's room directory?": "List this room in %(domain)s's room directory?",
|
||||
"Local addresses for this room:": "Local addresses for this room:",
|
||||
"Logged in as:": "Logged in as:",
|
||||
|
@ -391,6 +420,7 @@
|
|||
"<not supported>": "<not supported>",
|
||||
"NOT verified": "NOT verified",
|
||||
"No devices with registered encryption keys": "No devices with registered encryption keys",
|
||||
"No display name": "No display name",
|
||||
"No more results": "No more results",
|
||||
"No results": "No results",
|
||||
"No users have specific privileges in this room": "No users have specific privileges in this room",
|
||||
|
@ -400,6 +430,7 @@
|
|||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Only people who have been invited": "Only people who have been invited",
|
||||
"Operation failed": "Operation failed",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Otherwise, <a>click here</a> to send a bug report.",
|
||||
"Password": "Password",
|
||||
"Password:": "Password:",
|
||||
"Passwords can't be empty": "Passwords can't be empty",
|
||||
|
@ -412,9 +443,12 @@
|
|||
"Power level must be positive integer.": "Power level must be positive integer.",
|
||||
"Press": "Press",
|
||||
"Privacy warning": "Privacy warning",
|
||||
"Private Chat": "Private Chat",
|
||||
"Privileged Users": "Privileged Users",
|
||||
"Profile": "Profile",
|
||||
"Public Chat": "Public Chat",
|
||||
"Reason": "Reason",
|
||||
"Reason: %(reasonText)s": "Reason: %(reasonText)s",
|
||||
"Revoke Moderator": "Revoke Moderator",
|
||||
"Refer a friend to Riot:": "Refer a friend to Riot:",
|
||||
"Register": "Register",
|
||||
|
@ -422,6 +456,7 @@
|
|||
"rejected": "rejected",
|
||||
"%(targetName)s rejected the invitation.": "%(targetName)s rejected the invitation.",
|
||||
"Reject invitation": "Reject invitation",
|
||||
"Rejoin": "Rejoin",
|
||||
"Remote addresses for this room:": "Remote addresses for this room:",
|
||||
"Remove Contact Information?": "Remove Contact Information?",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removed their display name (%(oldDisplayName)s).",
|
||||
|
@ -440,7 +475,10 @@
|
|||
"riot-web version:": "riot-web version:",
|
||||
"Room %(roomId)s not visible": "Room %(roomId)s not visible",
|
||||
"Room Colour": "Room Colour",
|
||||
"Room contains unknown devices": "Room contains unknown devices",
|
||||
"Room name (optional)": "Room name (optional)",
|
||||
"%(roomName)s does not exist.": "%(roomName)s does not exist.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s is not accessible at this time.",
|
||||
"Rooms": "Rooms",
|
||||
"Save": "Save",
|
||||
"Scroll to bottom of page": "Scroll to bottom of page",
|
||||
|
@ -448,8 +486,11 @@
|
|||
"Search": "Search",
|
||||
"Search failed": "Search failed",
|
||||
"Searches DuckDuckGo for results": "Searches DuckDuckGo for results",
|
||||
"Searching known users": "Searching known users",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s",
|
||||
"Send a message (unencrypted)": "Send a message (unencrypted)",
|
||||
"Send an encrypted message": "Send an encrypted message",
|
||||
"Send anyway": "Send anyway",
|
||||
"Sender device information": "Sender device information",
|
||||
"Send Invites": "Send Invites",
|
||||
"Send Reset Email": "Send Reset Email",
|
||||
|
@ -466,9 +507,11 @@
|
|||
"Session ID": "Session ID",
|
||||
"%(senderName)s set a profile picture.": "%(senderName)s set a profile picture.",
|
||||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s set their display name to %(displayName)s.",
|
||||
"Set": "Set",
|
||||
"Setting a user name will create a fresh account": "Setting a user name will create a fresh account",
|
||||
"Settings": "Settings",
|
||||
"Show panel": "Show panel",
|
||||
"Show Text Formatting Toolbar": "Show Text Formatting Toolbar",
|
||||
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Show timestamps in 12 hour format (e.g. 2:30pm)",
|
||||
"Signed Out": "Signed Out",
|
||||
"Sign in": "Sign in",
|
||||
|
@ -476,10 +519,11 @@
|
|||
"since the point in time of selecting this option": "since the point in time of selecting this option",
|
||||
"since they joined": "since they joined",
|
||||
"since they were invited": "since they were invited",
|
||||
"Some of your messages have not been sent": "Some of your messages have not been sent",
|
||||
"Some of your messages have not been sent.": "Some of your messages have not been sent.",
|
||||
"Someone": "Someone",
|
||||
"Sorry, this homeserver is using a login which is not recognised ": "Sorry, this homeserver is using a login which is not recognised ",
|
||||
"Start a chat": "Start a chat",
|
||||
"Start authentication": "Start authentication",
|
||||
"Start Chat": "Start Chat",
|
||||
"Submit": "Submit",
|
||||
"Success": "Success",
|
||||
|
@ -488,8 +532,9 @@
|
|||
"Tagged as: ": "Tagged as: ",
|
||||
"The default role for new room members is": "The default role for new room members is",
|
||||
"The main address for this room is": "The main address for this room is",
|
||||
"The phone number entered looks invalid": "The phone number entered looks invalid",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "This action cannot be performed by a guest user. Please register to be able to do this",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "This action cannot be performed by a guest user. Please register to be able to do this.",
|
||||
"This email address is already in use": "This email address is already in use",
|
||||
"This email address was not found": "This email address was not found",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s this person?",
|
||||
|
@ -498,16 +543,16 @@
|
|||
"The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload",
|
||||
"The remote side failed to pick up": "The remote side failed to pick up",
|
||||
"This Home Server does not support login using email address.": "This Home Server does not support login using email address.",
|
||||
"This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:",
|
||||
"There was a problem logging in.": "There was a problem logging in.",
|
||||
"This room has no local addresses": "This room has no local addresses",
|
||||
"This room is not recognised.": "This room is not recognised.",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "This room is private or inaccessible to guests. You may be able to join if you register",
|
||||
"These are experimental features that may break in unexpected ways": "These are experimental features that may break in unexpected ways",
|
||||
"The visibility of existing history will be unchanged": "The visibility of existing history will be unchanged",
|
||||
"This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address",
|
||||
"this invitation?": "this invitation?",
|
||||
"This is a preview of this room. Room interactions have been disabled": "This is a preview of this room. Room interactions have been disabled",
|
||||
"This phone number is already in use": "This phone number is already in use",
|
||||
"This room": "This room",
|
||||
"This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers",
|
||||
"This room's internal ID is": "This room's internal ID is",
|
||||
"times": "times",
|
||||
|
@ -517,9 +562,8 @@
|
|||
"to demote": "to demote",
|
||||
"to favourite": "to favourite",
|
||||
"To invite users into the room": "To invite users into the room",
|
||||
"to join the discussion": "to join the discussion",
|
||||
"To kick users": "To kick users",
|
||||
"To link to a room it must have": "To link to a room it must have",
|
||||
"To link to a room it must have <a>an address</a>.": "To link to a room it must have <a>an address</a>.",
|
||||
"to make a room or": "to make a room or",
|
||||
"To remove other users' messages": "To remove other users' messages",
|
||||
"To reset your password, enter the email address linked to your account": "To reset your password, enter the email address linked to your account",
|
||||
|
@ -530,8 +574,8 @@
|
|||
"to tag as %(tagName)s": "to tag as %(tagName)s",
|
||||
"to tag direct chat": "to tag direct chat",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it": "Tried to load a specific point in this room's timeline, but was unable to find it",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
||||
"Turn Markdown off": "Turn Markdown off",
|
||||
"Turn Markdown on": "Turn Markdown on",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).",
|
||||
|
@ -541,11 +585,15 @@
|
|||
"Unable to verify email address.": "Unable to verify email address.",
|
||||
"Unban": "Unban",
|
||||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s unbanned %(targetName)s.",
|
||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.",
|
||||
"Unable to capture screen": "Unable to capture screen",
|
||||
"Unable to enable Notifications": "Unable to enable Notifications",
|
||||
"Unable to load device list": "Unable to load device list",
|
||||
"Undecryptable": "Undecryptable",
|
||||
"Unencrypted room": "Unencrypted room",
|
||||
"unencrypted": "unencrypted",
|
||||
"Unencrypted message": "Unencrypted message",
|
||||
"unknown caller": "unknown caller",
|
||||
"Unknown command": "Unknown command",
|
||||
"unknown device": "unknown device",
|
||||
"unknown error code": "unknown error code",
|
||||
|
@ -553,24 +601,36 @@
|
|||
"Unknown (user, device) pair:": "Unknown (user, device) pair:",
|
||||
"unknown": "unknown",
|
||||
"Unmute": "Unmute",
|
||||
"Unnamed Room": "Unnamed Room",
|
||||
"Unrecognised command:": "Unrecognised command:",
|
||||
"Unrecognised room alias:": "Unrecognised room alias:",
|
||||
"Unverified": "Unverified",
|
||||
"Uploading %(filename)s and %(count)s others": {
|
||||
"zero": "Uploading %(filename)s",
|
||||
"one": "Uploading %(filename)s and %(count)s other",
|
||||
"other": "Uploading %(filename)s and %(count)s others"
|
||||
},
|
||||
"uploaded a file": "uploaded a file",
|
||||
"Upload avatar": "Upload avatar",
|
||||
"Upload Failed": "Upload Failed",
|
||||
"Upload Files": "Upload Files",
|
||||
"Upload file": "Upload file",
|
||||
"Upload new:": "Upload new:",
|
||||
"Usage": "Usage",
|
||||
"Use compact timeline layout": "Use compact timeline layout",
|
||||
"Use with caution": "Use with caution",
|
||||
"User ID": "User ID",
|
||||
"User Interface": "User Interface",
|
||||
"%(user)s is a": "%(user)s is a",
|
||||
"User name": "User name",
|
||||
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)",
|
||||
"Username invalid: %(errMessage)s": "Username invalid: %(errMessage)s",
|
||||
"Users": "Users",
|
||||
"User": "User",
|
||||
"Verification Pending": "Verification Pending",
|
||||
"Verification": "Verification",
|
||||
"verified": "verified",
|
||||
"Verified": "Verified",
|
||||
"Verified key": "Verified key",
|
||||
"Video call": "Video call",
|
||||
"Voice call": "Voice call",
|
||||
|
@ -586,20 +646,25 @@
|
|||
"Who would you like to add to this room?": "Who would you like to add to this room?",
|
||||
"Who would you like to communicate with?": "Who would you like to communicate with?",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s withdrew %(targetName)s's invitation.",
|
||||
"Would you like to": "Would you like to",
|
||||
"Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?": "Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?",
|
||||
"You already have existing direct chats with this user:": "You already have existing direct chats with this user:",
|
||||
"You are already in a call.": "You are already in a call.",
|
||||
"You're not in any rooms yet! Press": "You're not in any rooms yet! Press",
|
||||
"You are trying to access %(roomName)s": "You are trying to access %(roomName)s",
|
||||
"You are trying to access %(roomName)s.": "You are trying to access %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "You cannot place a call with yourself.",
|
||||
"You cannot place VoIP calls in this browser.": "You cannot place VoIP calls in this browser.",
|
||||
"You do not have permission to post to this room": "You do not have permission to post to this room",
|
||||
"You have been banned from %(roomName)s by %(userName)s.": "You have been banned from %(roomName)s by %(userName)s.",
|
||||
"You have been invited to join this room by %(inviterName)s": "You have been invited to join this room by %(inviterName)s",
|
||||
"You have been kicked from %(roomName)s by %(userName)s.": "You have been kicked from %(roomName)s by %(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": "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",
|
||||
"You must <a>register</a> to use this functionality": "You must <a>register</a> to use this functionality",
|
||||
"You need to be able to invite users to do that.": "You need to be able to invite users to do that.",
|
||||
"You need to be logged in.": "You need to be logged in.",
|
||||
"You need to enter a user name.": "You need to enter a user name.",
|
||||
|
@ -610,7 +675,8 @@
|
|||
"You seem to be in a call, are you sure you want to quit?": "You seem to be in a call, are you sure you want to quit?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "You seem to be uploading files, are you sure you want to quit?",
|
||||
"You should not yet trust it to secure data": "You should not yet trust it to secure data",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
|
||||
"Your home server does not support device management.": "Your home server does not support device management.",
|
||||
"Sun": "Sun",
|
||||
"Mon": "Mon",
|
||||
"Tue": "Tue",
|
||||
|
@ -645,7 +711,7 @@
|
|||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "User names may only contain letters, numbers, dots, hyphens and underscores.",
|
||||
"An unknown error occurred.": "An unknown error occurred.",
|
||||
"I already have an account": "I already have an account",
|
||||
"An error occured: %(error_string)s": "An error occured: %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "An error occurred: %(error_string)s",
|
||||
"Topic": "Topic",
|
||||
"Make Moderator": "Make Moderator",
|
||||
"Make this room private": "Make this room private",
|
||||
|
@ -656,12 +722,13 @@
|
|||
"Connectivity to the server has been lost.": "Connectivity to the server has been lost.",
|
||||
"Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.",
|
||||
"Auto-complete": "Auto-complete",
|
||||
"Resend all": "Resend all",
|
||||
"(~%(searchCount)s results)": "(~%(searchCount)s results)",
|
||||
"<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.": "<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.",
|
||||
"(~%(count)s results)": {
|
||||
"one": "(~%(count)s result)",
|
||||
"other": "(~%(count)s results)"
|
||||
},
|
||||
"Cancel": "Cancel",
|
||||
"cancel all": "cancel all",
|
||||
"or": "or",
|
||||
"now. You can also select individual messages to resend or cancel.": "now. You can also select individual messages to resend or cancel.",
|
||||
"Active call": "Active call",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
|
@ -727,6 +794,11 @@
|
|||
"%(severalUsers)schanged their avatar": "%(severalUsers)schanged their avatar",
|
||||
"%(oneUser)schanged their avatar": "%(oneUser)schanged their avatar",
|
||||
"Please select the destination room for this message": "Please select the destination room for this message",
|
||||
"Create new room": "Create new room",
|
||||
"Welcome page": "Welcome page",
|
||||
"Room directory": "Room directory",
|
||||
"Start chat": "Start chat",
|
||||
"New Password": "New Password",
|
||||
"Start automatically after system login": "Start automatically after system login",
|
||||
"Desktop specific": "Desktop specific",
|
||||
"Analytics": "Analytics",
|
||||
|
@ -736,7 +808,6 @@
|
|||
"Passphrases must match": "Passphrases must match",
|
||||
"Passphrase must not be empty": "Passphrase must not be empty",
|
||||
"Export room keys": "Export room keys",
|
||||
"Enter passphrase": "Enter passphrase",
|
||||
"Confirm passphrase": "Confirm passphrase",
|
||||
"Import room keys": "Import room keys",
|
||||
"File to import": "File to import",
|
||||
|
@ -760,6 +831,7 @@
|
|||
"To continue, please enter your password.": "To continue, please enter your password.",
|
||||
"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:": "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:",
|
||||
"Device name": "Device name",
|
||||
"Device Name": "Device Name",
|
||||
"Device key": "Device key",
|
||||
"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.": "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.",
|
||||
"In future this verification process will be more sophisticated.": "In future this verification process will be more sophisticated.",
|
||||
|
@ -809,12 +881,13 @@
|
|||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?",
|
||||
"Removed or unknown message type": "Removed or unknown message type",
|
||||
"Disable URL previews by default for participants in this room": "Disable URL previews by default for participants in this room",
|
||||
"Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)",
|
||||
"URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.",
|
||||
"URL Previews": "URL Previews",
|
||||
"Enable URL previews for this room (affects only you)": "Enable URL previews for this room (affects only you)",
|
||||
"Drop file here to upload": "Drop file here to upload",
|
||||
" (unsupported)": " (unsupported)",
|
||||
"Ongoing conference call%(supportedText)s. %(joinText)s": "Ongoing conference call%(supportedText)s. %(joinText)s",
|
||||
"Ongoing conference call%(supportedText)s.": "Ongoing conference call%(supportedText)s.",
|
||||
"for %(amount)ss": "for %(amount)ss",
|
||||
"for %(amount)sm": "for %(amount)sm",
|
||||
"for %(amount)sh": "for %(amount)sh",
|
||||
|
@ -822,8 +895,15 @@
|
|||
"Online": "Online",
|
||||
"Idle": "Idle",
|
||||
"Offline": "Offline",
|
||||
"Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)",
|
||||
"Start chatting": "Start chatting",
|
||||
"Start Chatting": "Start Chatting",
|
||||
"Click on the button below to start chatting!": "Click on the button below to start chatting!",
|
||||
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName changed the room avatar to <img/>",
|
||||
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.",
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s"
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s",
|
||||
"Username available": "Username available",
|
||||
"Username not available": "Username not available",
|
||||
"Something went wrong!": "Something went wrong!",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "If you already have a Matrix account you can <a>log in</a> instead."
|
||||
}
|
||||
|
|
845
src/i18n/strings/en_US.json
Normal file
845
src/i18n/strings/en_US.json
Normal file
|
@ -0,0 +1,845 @@
|
|||
{
|
||||
"af": "Afrikaans",
|
||||
"ar-ae": "Arabic (U.A.E.)",
|
||||
"ar-bh": "Arabic (Bahrain)",
|
||||
"ar-dz": "Arabic (Algeria)",
|
||||
"ar-eg": "Arabic (Egypt)",
|
||||
"ar-iq": "Arabic (Iraq)",
|
||||
"ar-jo": "Arabic (Jordan)",
|
||||
"ar-kw": "Arabic (Kuwait)",
|
||||
"ar-lb": "Arabic (Lebanon)",
|
||||
"ar-ly": "Arabic (Libya)",
|
||||
"ar-ma": "Arabic (Morocco)",
|
||||
"ar-om": "Arabic (Oman)",
|
||||
"ar-qa": "Arabic (Qatar)",
|
||||
"ar-sa": "Arabic (Saudi Arabia)",
|
||||
"ar-sy": "Arabic (Syria)",
|
||||
"ar-tn": "Arabic (Tunisia)",
|
||||
"ar-ye": "Arabic (Yemen)",
|
||||
"be": "Belarusian",
|
||||
"bg": "Bulgarian",
|
||||
"ca": "Catalan",
|
||||
"cs": "Czech",
|
||||
"da": "Danish",
|
||||
"de-at": "German (Austria)",
|
||||
"de-ch": "German (Switzerland)",
|
||||
"de": "German",
|
||||
"de-li": "German (Liechtenstein)",
|
||||
"de-lu": "German (Luxembourg)",
|
||||
"el": "Greek",
|
||||
"en-au": "English (Australia)",
|
||||
"en-bz": "English (Belize)",
|
||||
"en-ca": "English (Canada)",
|
||||
"en": "English",
|
||||
"en-gb": "English (United Kingdom)",
|
||||
"en-ie": "English (Ireland)",
|
||||
"en-jm": "English (Jamaica)",
|
||||
"en-nz": "English (New Zealand)",
|
||||
"en-tt": "English (Trinidad)",
|
||||
"en-us": "English (United States)",
|
||||
"en-za": "English (South Africa)",
|
||||
"es-ar": "Spanish (Argentina)",
|
||||
"es-bo": "Spanish (Bolivia)",
|
||||
"es-cl": "Spanish (Chile)",
|
||||
"es-co": "Spanish (Colombia)",
|
||||
"es-cr": "Spanish (Costa Rica)",
|
||||
"es-do": "Spanish (Dominican Republic)",
|
||||
"es-ec": "Spanish (Ecuador)",
|
||||
"es-gt": "Spanish (Guatemala)",
|
||||
"es-hn": "Spanish (Honduras)",
|
||||
"es-mx": "Spanish (Mexico)",
|
||||
"es-ni": "Spanish (Nicaragua)",
|
||||
"es-pa": "Spanish (Panama)",
|
||||
"es-pe": "Spanish (Peru)",
|
||||
"es-pr": "Spanish (Puerto Rico)",
|
||||
"es-py": "Spanish (Paraguay)",
|
||||
"es": "Spanish (Spain)",
|
||||
"es-sv": "Spanish (El Salvador)",
|
||||
"es-uy": "Spanish (Uruguay)",
|
||||
"es-ve": "Spanish (Venezuela)",
|
||||
"et": "Estonian",
|
||||
"eu": "Basque (Basque)",
|
||||
"fa": "Farsi",
|
||||
"fi": "Finnish",
|
||||
"fo": "Faeroese",
|
||||
"fr-be": "French (Belgium)",
|
||||
"fr-ca": "French (Canada)",
|
||||
"fr-ch": "French (Switzerland)",
|
||||
"fr": "French",
|
||||
"fr-lu": "French (Luxembourg)",
|
||||
"ga": "Irish",
|
||||
"gd": "Gaelic (Scotland)",
|
||||
"he": "Hebrew",
|
||||
"hi": "Hindi",
|
||||
"hr": "Croatian",
|
||||
"hu": "Hungarian",
|
||||
"id": "Indonesian",
|
||||
"is": "Icelandic",
|
||||
"it-ch": "Italian (Switzerland)",
|
||||
"it": "Italian",
|
||||
"ja": "Japanese",
|
||||
"ji": "Yiddish",
|
||||
"ko": "Korean",
|
||||
"lt": "Lithuanian",
|
||||
"lv": "Latvian",
|
||||
"mk": "Macedonian (FYROM)",
|
||||
"ms": "Malaysian",
|
||||
"mt": "Maltese",
|
||||
"nl-be": "Dutch (Belgium)",
|
||||
"nl": "Dutch",
|
||||
"no": "Norwegian",
|
||||
"pl": "Polish",
|
||||
"pt-br": "Brazilian Portuguese",
|
||||
"pt": "Portuguese",
|
||||
"rm": "Rhaeto-Romanic",
|
||||
"ro-mo": "Romanian (Republic of Moldova)",
|
||||
"ro": "Romanian",
|
||||
"ru-mo": "Russian (Republic of Moldova)",
|
||||
"ru": "Russian",
|
||||
"sb": "Sorbian",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"sq": "Albanian",
|
||||
"sr": "Serbian",
|
||||
"sv-fi": "Swedish (Finland)",
|
||||
"sv": "Swedish",
|
||||
"sx": "Sutu",
|
||||
"sz": "Sami (Lappish)",
|
||||
"th": "Thai",
|
||||
"tn": "Tswana",
|
||||
"tr": "Turkish",
|
||||
"ts": "Tsonga",
|
||||
"uk": "Ukrainian",
|
||||
"ur": "Urdu",
|
||||
"ve": "Venda",
|
||||
"vi": "Vietnamese",
|
||||
"xh": "Xhosa",
|
||||
"zh-cn": "Chinese (PRC)",
|
||||
"zh-hk": "Chinese (Hong Kong SAR)",
|
||||
"zh-sg": "Chinese (Singapore)",
|
||||
"zh-tw": "Chinese (Taiwan)",
|
||||
"zu": "Zulu",
|
||||
"A registered account is required for this action": "A registered account is required for this action",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains",
|
||||
"accept": "accept",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s accepted an invitation.",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",
|
||||
"Account": "Account",
|
||||
"Access Token:": "Access Token:",
|
||||
"Add a topic": "Add a topic",
|
||||
"Add email address": "Add email address",
|
||||
"Add phone number": "Add phone number",
|
||||
"Admin": "Admin",
|
||||
"VoIP": "VoIP",
|
||||
"Missing Media Permissions, click here to request.": "Missing Media Permissions, click here to request.",
|
||||
"No Microphones detected": "No Microphones detected",
|
||||
"No Webcams detected": "No Webcams detected",
|
||||
"No media permissions": "No media permissions",
|
||||
"You may need to manually permit Riot to access your microphone/webcam": "You may need to manually permit Riot to access your microphone/webcam",
|
||||
"Default Device": "Default Device",
|
||||
"Microphone": "Microphone",
|
||||
"Camera": "Camera",
|
||||
"Advanced": "Advanced",
|
||||
"Algorithm": "Algorithm",
|
||||
"Hide removed messages": "Hide removed messages",
|
||||
"Always show message timestamps": "Always show message timestamps",
|
||||
"Authentication": "Authentication",
|
||||
"all room members": "all room members",
|
||||
"all room members, from the point they are invited": "all room members, from the point they are invited",
|
||||
"all room members, from the point they joined": "all room members, from the point they joined",
|
||||
"an address": "an address",
|
||||
"and": "and",
|
||||
"%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others",
|
||||
"%(items)s and one other": "%(items)s and one other",
|
||||
"%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s",
|
||||
"and %(overflowCount)s others...": "and %(overflowCount)s others...",
|
||||
"and one other...": "and one other...",
|
||||
"%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing",
|
||||
"%(names)s and one other are typing": "%(names)s and one other are typing",
|
||||
"%(names)s and %(count)s others are typing": "%(names)s and %(count)s others are typing",
|
||||
"An email has been sent to": "An email has been sent to",
|
||||
"A new password must be entered.": "A new password must be entered.",
|
||||
"%(senderName)s answered the call.": "%(senderName)s answered the call.",
|
||||
"anyone": "anyone",
|
||||
"An error has occurred.": "An error has occurred.",
|
||||
"Anyone": "Anyone",
|
||||
"Anyone who knows the room's link, apart from guests": "Anyone who knows the room's link, apart from guests",
|
||||
"Anyone who knows the room's link, including guests": "Anyone who knows the room's link, including guests",
|
||||
"Are you sure?": "Are you sure?",
|
||||
"Are you sure you want to leave the room '%(roomName)s'?": "Are you sure you want to leave the room '%(roomName)s'?",
|
||||
"Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?",
|
||||
"Are you sure you want to upload the following files?": "Are you sure you want to upload the following files?",
|
||||
"Attachment": "Attachment",
|
||||
"Autoplay GIFs and videos": "Autoplay GIFs and videos",
|
||||
"%(senderName)s banned %(targetName)s.": "%(senderName)s banned %(targetName)s.",
|
||||
"Ban": "Ban",
|
||||
"Banned users": "Banned users",
|
||||
"Bans user with given id": "Bans user with given id",
|
||||
"Blacklisted": "Blacklisted",
|
||||
"Bug Report": "Bug Report",
|
||||
"Bulk Options": "Bulk Options",
|
||||
"Call Timeout": "Call Timeout",
|
||||
"Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.",
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||
"Can't load user settings": "Can't load user settings",
|
||||
"Change Password": "Change Password",
|
||||
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.",
|
||||
"%(senderName)s changed their profile picture.": "%(senderName)s changed their profile picture.",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s changed the power level of %(powerLevelDiffText)s.",
|
||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s changed the room name to %(roomName)s.",
|
||||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s removed the room name.",
|
||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s changed the topic to \"%(topic)s\".",
|
||||
"Changes to who can read history will only apply to future messages in this room": "Changes to who can read history will only apply to future messages in this room",
|
||||
"Changes your display nickname": "Changes your display nickname",
|
||||
"changing room on a RoomView is not supported": "changing room on a RoomView is not supported",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.",
|
||||
"Claimed Ed25519 fingerprint key": "Claimed Ed25519 fingerprint key",
|
||||
"Clear Cache and Reload": "Clear Cache and Reload",
|
||||
"Clear Cache": "Clear Cache",
|
||||
"Click here": "Click here",
|
||||
"Click here to fix": "Click here to fix",
|
||||
"Click to mute audio": "Click to mute audio",
|
||||
"Click to mute video": "Click to mute video",
|
||||
"click to reveal": "click to reveal",
|
||||
"Click to unmute video": "Click to unmute video",
|
||||
"Click to unmute audio": "Click to unmute audio",
|
||||
"Command error": "Command error",
|
||||
"Commands": "Commands",
|
||||
"Conference call failed.": "Conference call failed.",
|
||||
"Conference calling is in development and may not be reliable.": "Conference calling is in development and may not be reliable.",
|
||||
"Conference calls are not supported in encrypted rooms": "Conference calls are not supported in encrypted rooms",
|
||||
"Conference calls are not supported in this client": "Conference calls are not supported in this client",
|
||||
"Confirm password": "Confirm password",
|
||||
"Confirm your new password": "Confirm your new password",
|
||||
"Continue": "Continue",
|
||||
"Could not connect to the integration server": "Could not connect to the integration server",
|
||||
"Create an account": "Create an account",
|
||||
"Create Room": "Create Room",
|
||||
"Cryptography": "Cryptography",
|
||||
"Current password": "Current password",
|
||||
"Curve25519 identity key": "Curve25519 identity key",
|
||||
"Custom level": "Custom level",
|
||||
"/ddg is not a command": "/ddg is not a command",
|
||||
"Deactivate Account": "Deactivate Account",
|
||||
"Deactivate my account": "Deactivate my account",
|
||||
"decline": "decline",
|
||||
"Decrypt %(text)s": "Decrypt %(text)s",
|
||||
"Decryption error": "Decryption error",
|
||||
"(default: %(userName)s)": "(default: %(userName)s)",
|
||||
"Delete": "Delete",
|
||||
"demote": "demote",
|
||||
"Deops user with given id": "Deops user with given id",
|
||||
"Default": "Default",
|
||||
"Device already verified!": "Device already verified!",
|
||||
"Device ID": "Device ID",
|
||||
"Device ID:": "Device ID:",
|
||||
"device id: ": "device id: ",
|
||||
"Device key:": "Device key:",
|
||||
"Devices": "Devices",
|
||||
"Devices will not yet be able to decrypt history from before they joined the room": "Devices will not yet be able to decrypt history from before they joined the room",
|
||||
"Direct Chat": "Direct Chat",
|
||||
"Direct chats": "Direct chats",
|
||||
"disabled": "disabled",
|
||||
"Disable inline URL previews by default": "Disable inline URL previews by default",
|
||||
"Disinvite": "Disinvite",
|
||||
"Display name": "Display name",
|
||||
"Displays action": "Displays action",
|
||||
"Don't send typing notifications": "Don't send typing notifications",
|
||||
"Download %(text)s": "Download %(text)s",
|
||||
"Drop here %(toAction)s": "Drop here %(toAction)s",
|
||||
"Drop here to tag %(section)s": "Drop here to tag %(section)s",
|
||||
"Ed25519 fingerprint": "Ed25519 fingerprint",
|
||||
"Email": "Email",
|
||||
"Email address": "Email address",
|
||||
"Email address (optional)": "Email address (optional)",
|
||||
"Email, name or matrix ID": "Email, name or matrix ID",
|
||||
"Emoji": "Emoji",
|
||||
"Enable encryption": "Enable encryption",
|
||||
"enabled": "enabled",
|
||||
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Encrypted messages will not be visible on clients that do not yet implement encryption",
|
||||
"Encrypted room": "Encrypted room",
|
||||
"%(senderName)s ended the call.": "%(senderName)s ended the call.",
|
||||
"End-to-end encryption information": "End-to-end encryption information",
|
||||
"End-to-end encryption is in beta and may not be reliable": "End-to-end encryption is in beta and may not be reliable",
|
||||
"Enter Code": "Enter Code",
|
||||
"Error": "Error",
|
||||
"Error decrypting attachment": "Error decrypting attachment",
|
||||
"Event information": "Event information",
|
||||
"Existing Call": "Existing Call",
|
||||
"Export": "Export",
|
||||
"Export E2E room keys": "Export E2E room keys",
|
||||
"Failed to ban user": "Failed to ban user",
|
||||
"Failed to change password. Is your password correct?": "Failed to change password. Is your password correct?",
|
||||
"Failed to change power level": "Failed to change power level",
|
||||
"Failed to delete device": "Failed to delete device",
|
||||
"Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
|
||||
"Failed to join room": "Failed to join room",
|
||||
"Failed to join the room": "Failed to join the room",
|
||||
"Failed to kick": "Failed to kick",
|
||||
"Failed to leave room": "Failed to leave room",
|
||||
"Failed to load timeline position": "Failed to load timeline position",
|
||||
"Failed to lookup current room": "Failed to lookup current room",
|
||||
"Failed to mute user": "Failed to mute user",
|
||||
"Failed to register as guest:": "Failed to register as guest:",
|
||||
"Failed to reject invite": "Failed to reject invite",
|
||||
"Failed to reject invitation": "Failed to reject invitation",
|
||||
"Failed to save settings": "Failed to save settings",
|
||||
"Failed to send email": "Failed to send email",
|
||||
"Failed to send request.": "Failed to send request.",
|
||||
"Failed to set avatar.": "Failed to set avatar.",
|
||||
"Failed to set display name": "Failed to set display name",
|
||||
"Failed to set up conference call": "Failed to set up conference call",
|
||||
"Failed to toggle moderator status": "Failed to toggle moderator status",
|
||||
"Failed to unban": "Failed to unban",
|
||||
"Failed to upload file": "Failed to upload file",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "Failed to verify email address: make sure you clicked the link in the email",
|
||||
"Failure to create room": "Failure to create room",
|
||||
"Favourite": "Favorite",
|
||||
"favourite": "favorite",
|
||||
"Favourites": "Favorites",
|
||||
"Fill screen": "Fill screen",
|
||||
"Filter room members": "Filter room members",
|
||||
"Forget room": "Forget room",
|
||||
"Forgot your password?": "Forgot your password?",
|
||||
"For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.",
|
||||
"Found a bug?": "Found a bug?",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s",
|
||||
"Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.",
|
||||
"Guests can't set avatars. Please register.": "Guests can't set avatars. Please register.",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Guest users can't create new rooms. Please register to create room and start a chat.",
|
||||
"Guest users can't upload files. Please register to upload.": "Guest users can't upload files. Please register to upload.",
|
||||
"Guests can't use labs features. Please register.": "Guests can't use labs features. Please register.",
|
||||
"Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.",
|
||||
"had": "had",
|
||||
"Hangup": "Hangup",
|
||||
"Hide read receipts": "Hide read receipts",
|
||||
"Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar",
|
||||
"Historical": "Historical",
|
||||
"Homeserver is": "Homeserver is",
|
||||
"Identity Server is": "Identity Server is",
|
||||
"I have verified my email address": "I have verified my email address",
|
||||
"Import": "Import",
|
||||
"Import E2E room keys": "Import E2E room keys",
|
||||
"Incorrect username and/or password.": "Incorrect username and/or password.",
|
||||
"Incorrect verification code": "Incorrect verification code",
|
||||
"Interface Language": "Interface Language",
|
||||
"Invalid alias format": "Invalid alias format",
|
||||
"Invalid address format": "Invalid address format",
|
||||
"Invalid Email Address": "Invalid Email Address",
|
||||
"Invalid file%(extra)s": "Invalid file%(extra)s",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s invited %(targetName)s.",
|
||||
"Invite new room members": "Invite new room members",
|
||||
"Invited": "Invited",
|
||||
"Invites": "Invites",
|
||||
"Invites user with given id to current room": "Invites user with given id to current room",
|
||||
"is a": "is a",
|
||||
"'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
|
||||
"%(displayName)s is typing": "%(displayName)s is typing",
|
||||
"Sign in with": "Sign in with",
|
||||
"Join Room": "Join Room",
|
||||
"joined and left": "joined and left",
|
||||
"joined": "joined",
|
||||
"%(targetName)s joined the room.": "%(targetName)s joined the room.",
|
||||
"Joins room with given alias": "Joins room with given alias",
|
||||
"Jump to first unread message.": "Jump to first unread message.",
|
||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s kicked %(targetName)s.",
|
||||
"Kick": "Kick",
|
||||
"Kicks user with given id": "Kicks user with given id",
|
||||
"Labs": "Labs",
|
||||
"Leave room": "Leave room",
|
||||
"left and rejoined": "left and rejoined",
|
||||
"left": "left",
|
||||
"%(targetName)s left the room.": "%(targetName)s left the room.",
|
||||
"Level": "Level",
|
||||
"List this room in %(domain)s's room directory?": "List this room in %(domain)s's room directory?",
|
||||
"Local addresses for this room:": "Local addresses for this room:",
|
||||
"Logged in as:": "Logged in as:",
|
||||
"Login as guest": "Login as guest",
|
||||
"Logout": "Logout",
|
||||
"Low priority": "Low priority",
|
||||
"%(senderName)s made future room history visible to": "%(senderName)s made future room history visible to",
|
||||
"Manage Integrations": "Manage Integrations",
|
||||
"Markdown is disabled": "Markdown is disabled",
|
||||
"Markdown is enabled": "Markdown is enabled",
|
||||
"matrix-react-sdk version:": "matrix-react-sdk version:",
|
||||
"Members only": "Members only",
|
||||
"Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present",
|
||||
"Missing room_id in request": "Missing room_id in request",
|
||||
"Missing user_id in request": "Missing user_id in request",
|
||||
"Mobile phone number": "Mobile phone number",
|
||||
"Mobile phone number (optional)": "Mobile phone number (optional)",
|
||||
"Moderator": "Moderator",
|
||||
"Must be viewing a room": "Must be viewing a room",
|
||||
"Mute": "Mute",
|
||||
"my Matrix ID": "my Matrix ID",
|
||||
"Name": "Name",
|
||||
"Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
|
||||
"Never send encrypted messages to unverified devices in this room": "Never send encrypted messages to unverified devices in this room",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Never send encrypted messages to unverified devices in this room from this device",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)",
|
||||
"New Composer & Autocomplete": "New Composer & Autocomplete",
|
||||
"New password": "New password",
|
||||
"New passwords don't match": "New passwords don't match",
|
||||
"New passwords must match each other.": "New passwords must match each other.",
|
||||
"none": "none",
|
||||
"not set": "not set",
|
||||
"not specified": "not specified",
|
||||
"Notifications": "Notifications",
|
||||
"(not supported by this browser)": "(not supported by this browser)",
|
||||
"<not supported>": "<not supported>",
|
||||
"NOT verified": "NOT verified",
|
||||
"No devices with registered encryption keys": "No devices with registered encryption keys",
|
||||
"No more results": "No more results",
|
||||
"No results": "No results",
|
||||
"No users have specific privileges in this room": "No users have specific privileges in this room",
|
||||
"OK": "OK",
|
||||
"olm version:": "olm version:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Once encryption is enabled for a room it cannot be turned off again (for now)",
|
||||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Only people who have been invited": "Only people who have been invited",
|
||||
"Operation failed": "Operation failed",
|
||||
"Password": "Password",
|
||||
"Password:": "Password:",
|
||||
"Passwords can't be empty": "Passwords can't be empty",
|
||||
"People": "People",
|
||||
"Permissions": "Permissions",
|
||||
"Phone": "Phone",
|
||||
"%(senderName)s placed a %(callType)s call.": "%(senderName)s placed a %(callType)s call.",
|
||||
"Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.",
|
||||
"Please Register": "Please Register",
|
||||
"Power level must be positive integer.": "Power level must be positive integer.",
|
||||
"Press": "Press",
|
||||
"Privacy warning": "Privacy warning",
|
||||
"Privileged Users": "Privileged Users",
|
||||
"Profile": "Profile",
|
||||
"Reason": "Reason",
|
||||
"Revoke Moderator": "Revoke Moderator",
|
||||
"Refer a friend to Riot:": "Refer a friend to Riot:",
|
||||
"Register": "Register",
|
||||
"Registration required": "Registration required",
|
||||
"rejected": "rejected",
|
||||
"%(targetName)s rejected the invitation.": "%(targetName)s rejected the invitation.",
|
||||
"Reject invitation": "Reject invitation",
|
||||
"Remote addresses for this room:": "Remote addresses for this room:",
|
||||
"Remove Contact Information?": "Remove Contact Information?",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removed their display name (%(oldDisplayName)s).",
|
||||
"%(senderName)s removed their profile picture.": "%(senderName)s removed their profile picture.",
|
||||
"Remove": "Remove",
|
||||
"Remove %(threePid)s?": "Remove %(threePid)s?",
|
||||
"%(senderName)s requested a VoIP conference.": "%(senderName)s requested a VoIP conference.",
|
||||
"Report it": "Report it",
|
||||
"Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.",
|
||||
"restore": "restore",
|
||||
"Results from DuckDuckGo": "Results from DuckDuckGo",
|
||||
"Return to app": "Return to app",
|
||||
"Return to login screen": "Return to login screen",
|
||||
"Riot does not have permission to send you notifications - please check your browser settings": "Riot does not have permission to send you notifications - please check your browser settings",
|
||||
"Riot was not given permission to send notifications - please try again": "Riot was not given permission to send notifications - please try again",
|
||||
"riot-web version:": "riot-web version:",
|
||||
"Room %(roomId)s not visible": "Room %(roomId)s not visible",
|
||||
"Room Colour": "Room Color",
|
||||
"Room name (optional)": "Room name (optional)",
|
||||
"Rooms": "Rooms",
|
||||
"Save": "Save",
|
||||
"Scroll to bottom of page": "Scroll to bottom of page",
|
||||
"Scroll to unread messages": "Scroll to unread messages",
|
||||
"Search": "Search",
|
||||
"Search failed": "Search failed",
|
||||
"Searches DuckDuckGo for results": "Searches DuckDuckGo for results",
|
||||
"Send a message (unencrypted)": "Send a message (unencrypted)",
|
||||
"Send an encrypted message": "Send an encrypted message",
|
||||
"Sender device information": "Sender device information",
|
||||
"Send Invites": "Send Invites",
|
||||
"Send Reset Email": "Send Reset Email",
|
||||
"sent an image": "sent an image",
|
||||
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s sent an image.",
|
||||
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.",
|
||||
"sent a video": "sent a video",
|
||||
"Server error": "Server error",
|
||||
"Server may be unavailable or overloaded": "Server may be unavailable or overloaded",
|
||||
"Server may be unavailable, overloaded, or search timed out :(": "Server may be unavailable, overloaded, or search timed out :(",
|
||||
"Server may be unavailable, overloaded, or the file too big": "Server may be unavailable, overloaded, or the file too big",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Server unavailable, overloaded, or something else went wrong.",
|
||||
"Session ID": "Session ID",
|
||||
"%(senderName)s set a profile picture.": "%(senderName)s set a profile picture.",
|
||||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s set their display name to %(displayName)s.",
|
||||
"Setting a user name will create a fresh account": "Setting a user name will create a fresh account",
|
||||
"Settings": "Settings",
|
||||
"Show panel": "Show panel",
|
||||
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Show timestamps in 12 hour format (e.g. 2:30pm)",
|
||||
"Signed Out": "Signed Out",
|
||||
"Sign in": "Sign in",
|
||||
"Sign out": "Sign out",
|
||||
"since the point in time of selecting this option": "since the point in time of selecting this option",
|
||||
"since they joined": "since they joined",
|
||||
"since they were invited": "since they were invited",
|
||||
"Some of your messages have not been sent.": "Some of your messages have not been sent.",
|
||||
"Someone": "Someone",
|
||||
"Sorry, this homeserver is using a login which is not recognised ": "Sorry, this homeserver is using a login which is not recognized ",
|
||||
"Start a chat": "Start a chat",
|
||||
"Start Chat": "Start Chat",
|
||||
"Submit": "Submit",
|
||||
"Success": "Success",
|
||||
"tag as %(tagName)s": "tag as %(tagName)s",
|
||||
"tag direct chat": "tag direct chat",
|
||||
"Tagged as: ": "Tagged as: ",
|
||||
"The default role for new room members is": "The default role for new room members is",
|
||||
"The main address for this room is": "The main address for this room is",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "This action cannot be performed by a guest user. Please register to be able to do this.",
|
||||
"This email address is already in use": "This email address is already in use",
|
||||
"This email address was not found": "This email address was not found",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s this person?",
|
||||
"The email address linked to your account must be entered.": "The email address linked to your account must be entered.",
|
||||
"The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads",
|
||||
"The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload",
|
||||
"The remote side failed to pick up": "The remote side failed to pick up",
|
||||
"This Home Server does not support login using email address.": "This Home Server does not support login using email address.",
|
||||
"There was a problem logging in.": "There was a problem logging in.",
|
||||
"This room has no local addresses": "This room has no local addresses",
|
||||
"This room is not recognised.": "This room is not recognized.",
|
||||
"These are experimental features that may break in unexpected ways": "These are experimental features that may break in unexpected ways",
|
||||
"The visibility of existing history will be unchanged": "The visibility of existing history will be unchanged",
|
||||
"This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address",
|
||||
"this invitation?": "this invitation?",
|
||||
"This is a preview of this room. Room interactions have been disabled": "This is a preview of this room. Room interactions have been disabled",
|
||||
"This phone number is already in use": "This phone number is already in use",
|
||||
"This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers",
|
||||
"This room's internal ID is": "This room's internal ID is",
|
||||
"times": "times",
|
||||
"To ban users": "To ban users",
|
||||
"to browse the directory": "to browse the directory",
|
||||
"To configure the room": "To configure the room",
|
||||
"to demote": "to demote",
|
||||
"to favourite": "to favorite",
|
||||
"To invite users into the room": "To invite users into the room",
|
||||
"to join the discussion": "to join the discussion",
|
||||
"To kick users": "To kick users",
|
||||
"To link to a room it must have": "To link to a room it must have",
|
||||
"to make a room or": "to make a room or",
|
||||
"To remove other users' messages": "To remove other users' messages",
|
||||
"To reset your password, enter the email address linked to your account": "To reset your password, enter the email address linked to your account",
|
||||
"to restore": "to restore",
|
||||
"To send events of type": "To send events of type",
|
||||
"To send messages": "To send messages",
|
||||
"to start a chat with someone": "to start a chat with someone",
|
||||
"to tag as %(tagName)s": "to tag as %(tagName)s",
|
||||
"to tag direct chat": "to tag direct chat",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
||||
"Turn Markdown off": "Turn Markdown off",
|
||||
"Turn Markdown on": "Turn Markdown on",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).",
|
||||
"Unable to add email address": "Unable to add email address",
|
||||
"Unable to remove contact information": "Unable to remove contact information",
|
||||
"Unable to restore previous session": "Unable to restore previous session",
|
||||
"Unable to verify email address.": "Unable to verify email address.",
|
||||
"Unban": "Unban",
|
||||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s unbanned %(targetName)s.",
|
||||
"Unable to capture screen": "Unable to capture screen",
|
||||
"Unable to enable Notifications": "Unable to enable Notifications",
|
||||
"Unable to load device list": "Unable to load device list",
|
||||
"Unencrypted room": "Unencrypted room",
|
||||
"unencrypted": "unencrypted",
|
||||
"Unknown command": "Unknown command",
|
||||
"unknown device": "unknown device",
|
||||
"unknown error code": "unknown error code",
|
||||
"Unknown room %(roomId)s": "Unknown room %(roomId)s",
|
||||
"Unknown (user, device) pair:": "Unknown (user, device) pair:",
|
||||
"unknown": "unknown",
|
||||
"Unmute": "Unmute",
|
||||
"Unrecognised command:": "Unrecognized command:",
|
||||
"Unrecognised room alias:": "Unrecognized room alias:",
|
||||
"uploaded a file": "uploaded a file",
|
||||
"Upload avatar": "Upload avatar",
|
||||
"Upload Failed": "Upload Failed",
|
||||
"Upload Files": "Upload Files",
|
||||
"Upload file": "Upload file",
|
||||
"Usage": "Usage",
|
||||
"Use compact timeline layout": "Use compact timeline layout",
|
||||
"Use with caution": "Use with caution",
|
||||
"User ID": "User ID",
|
||||
"User Interface": "User Interface",
|
||||
"User name": "User name",
|
||||
"Users": "Users",
|
||||
"User": "User",
|
||||
"Verification Pending": "Verification Pending",
|
||||
"Verification": "Verification",
|
||||
"verified": "verified",
|
||||
"Verified key": "Verified key",
|
||||
"Video call": "Video call",
|
||||
"Voice call": "Voice call",
|
||||
"VoIP conference finished.": "VoIP conference finished.",
|
||||
"VoIP conference started.": "VoIP conference started.",
|
||||
"VoIP is unsupported": "VoIP is unsupported",
|
||||
"(warning: cannot be disabled again!)": "(warning: cannot be disabled again!)",
|
||||
"Warning!": "Warning!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "WARNING: Device already verified, but keys do NOT MATCH!",
|
||||
"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!": "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!",
|
||||
"Who can access this room?": "Who can access this room?",
|
||||
"Who can read history?": "Who can read history?",
|
||||
"Who would you like to add to this room?": "Who would you like to add to this room?",
|
||||
"Who would you like to communicate with?": "Who would you like to communicate with?",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s withdrew %(targetName)s's invitation.",
|
||||
"Would you like to": "Would you like to",
|
||||
"You are already in a call.": "You are already in a call.",
|
||||
"You're not in any rooms yet! Press": "You're not in any rooms yet! Press",
|
||||
"You are trying to access %(roomName)s.": "You are trying to access %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "You cannot place a call with yourself.",
|
||||
"You cannot place VoIP calls in this browser.": "You cannot place VoIP calls in this browser.",
|
||||
"You do not have permission to post to this room": "You do not have permission to post to this room",
|
||||
"You have been invited to join this room by %(inviterName)s": "You have been invited to join this room by %(inviterName)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": "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.",
|
||||
"You need to be logged in.": "You need to be logged in.",
|
||||
"You need to enter a user name.": "You need to enter a user name.",
|
||||
"You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a one-off; sorry for the inconvenience.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
|
||||
"Your password has been reset": "Your password has been reset",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them",
|
||||
"You seem to be in a call, are you sure you want to quit?": "You seem to be in a call, are you sure you want to quit?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "You seem to be uploading files, are you sure you want to quit?",
|
||||
"You should not yet trust it to secure data": "You should not yet trust it to secure data",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
|
||||
"Sun": "Sun",
|
||||
"Mon": "Mon",
|
||||
"Tue": "Tue",
|
||||
"Wed": "Wed",
|
||||
"Thu": "Thu",
|
||||
"Fri": "Fri",
|
||||
"Sat": "Sat",
|
||||
"Jan": "Jan",
|
||||
"Feb": "Feb",
|
||||
"Mar": "Mar",
|
||||
"Apr": "Apr",
|
||||
"May": "May",
|
||||
"Jun": "Jun",
|
||||
"Jul": "Jul",
|
||||
"Aug": "Aug",
|
||||
"Sep": "Sep",
|
||||
"Oct": "Oct",
|
||||
"Nov": "Nov",
|
||||
"Dec": "Dec",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s",
|
||||
"%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s",
|
||||
"Set a display name:": "Set a display name:",
|
||||
"Set a Display Name": "Set a Display Name",
|
||||
"Upload an avatar:": "Upload an avatar:",
|
||||
"This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.",
|
||||
"Missing password.": "Missing password.",
|
||||
"Passwords don't match.": "Passwords don't match.",
|
||||
"Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Password too short (min %(MIN_PASSWORD_LENGTH)s).",
|
||||
"This doesn't look like a valid email address.": "This doesn't look like a valid email address.",
|
||||
"This doesn't look like a valid phone number.": "This doesn't look like a valid phone number.",
|
||||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "User names may only contain letters, numbers, dots, hyphens and underscores.",
|
||||
"An unknown error occurred.": "An unknown error occurred.",
|
||||
"I already have an account": "I already have an account",
|
||||
"An error occurred: %(error_string)s": "An error occurred: %(error_string)s",
|
||||
"Topic": "Topic",
|
||||
"Make Moderator": "Make Moderator",
|
||||
"Make this room private": "Make this room private",
|
||||
"Share message history with new users": "Share message history with new users",
|
||||
"Encrypt room": "Encrypt room",
|
||||
"There are no visible files in this room": "There are no visible files in this room",
|
||||
"Room": "Room",
|
||||
"Connectivity to the server has been lost.": "Connectivity to the server has been lost.",
|
||||
"Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.",
|
||||
"Auto-complete": "Auto-complete",
|
||||
"Resend all": "Resend all",
|
||||
"(~%(searchCount)s results)": "(~%(searchCount)s results)",
|
||||
"Cancel": "Cancel",
|
||||
"cancel all": "cancel all",
|
||||
"or": "or",
|
||||
"now. You can also select individual messages to resend or cancel.": "now. You can also select individual messages to resend or cancel.",
|
||||
"Active call": "Active call",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
"Wednesday": "Wednesday",
|
||||
"Thursday": "Thursday",
|
||||
"Friday": "Friday",
|
||||
"Saturday": "Saturday",
|
||||
"Sunday": "Sunday",
|
||||
"bold": "bold",
|
||||
"italic": "italic",
|
||||
"strike": "strike",
|
||||
"underline": "underline",
|
||||
"code": "code",
|
||||
"quote": "quote",
|
||||
"bullet": "bullet",
|
||||
"numbullet": "numbullet",
|
||||
"%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sjoined %(repeats)s times",
|
||||
"%(oneUser)sjoined %(repeats)s times": "%(oneUser)sjoined %(repeats)s times",
|
||||
"%(severalUsers)sjoined": "%(severalUsers)sjoined",
|
||||
"%(oneUser)sjoined": "%(oneUser)sjoined",
|
||||
"%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sleft %(repeats)s times",
|
||||
"%(oneUser)sleft %(repeats)s times": "%(oneUser)sleft %(repeats)s times",
|
||||
"%(severalUsers)sleft": "%(severalUsers)sleft",
|
||||
"%(oneUser)sleft": "%(oneUser)sleft",
|
||||
"%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sjoined and left %(repeats)s times",
|
||||
"%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sjoined and left %(repeats)s times",
|
||||
"%(severalUsers)sjoined and left": "%(severalUsers)sjoined and left",
|
||||
"%(oneUser)sjoined and left": "%(oneUser)sjoined and left",
|
||||
"%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sleft and rejoined %(repeats)s times",
|
||||
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sleft and rejoined %(repeats)s times",
|
||||
"%(severalUsers)sleft and rejoined": "%(severalUsers)sleft and rejoined",
|
||||
"%(oneUser)sleft and rejoined": "%(oneUser)sleft and rejoined",
|
||||
"%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)srejected their invitations %(repeats)s times",
|
||||
"%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)srejected their invitation %(repeats)s times",
|
||||
"%(severalUsers)srejected their invitations": "%(severalUsers)srejected their invitations",
|
||||
"%(oneUser)srejected their invitation": "%(oneUser)srejected their invitation",
|
||||
"%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)shad their invitations withdrawn %(repeats)s times",
|
||||
"%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)shad their invitation withdrawn %(repeats)s times",
|
||||
"%(severalUsers)shad their invitations withdrawn": "%(severalUsers)shad their invitations withdrawn",
|
||||
"%(oneUser)shad their invitation withdrawn": "%(oneUser)shad their invitation withdrawn",
|
||||
"were invited %(repeats)s times": "were invited %(repeats)s times",
|
||||
"was invited %(repeats)s times": "was invited %(repeats)s times",
|
||||
"were invited": "were invited",
|
||||
"was invited": "was invited",
|
||||
"were banned %(repeats)s times": "were banned %(repeats)s times",
|
||||
"was banned %(repeats)s times": "was banned %(repeats)s times",
|
||||
"were banned": "were banned",
|
||||
"was banned": "was banned",
|
||||
"were unbanned %(repeats)s times": "were unbanned %(repeats)s times",
|
||||
"was unbanned %(repeats)s times": "was unbanned %(repeats)s times",
|
||||
"were unbanned": "were unbanned",
|
||||
"was unbanned": "was unbanned",
|
||||
"were kicked %(repeats)s times": "were kicked %(repeats)s times",
|
||||
"was kicked %(repeats)s times": "was kicked %(repeats)s times",
|
||||
"were kicked": "were kicked",
|
||||
"was kicked": "was kicked",
|
||||
"%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)schanged their name %(repeats)s times",
|
||||
"%(oneUser)schanged their name %(repeats)s times": "%(oneUser)schanged their name %(repeats)s times",
|
||||
"%(severalUsers)schanged their name": "%(severalUsers)schanged their name",
|
||||
"%(oneUser)schanged their name": "%(oneUser)schanged their name",
|
||||
"%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)schanged their avatar %(repeats)s times",
|
||||
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)schanged their avatar %(repeats)s times",
|
||||
"%(severalUsers)schanged their avatar": "%(severalUsers)schanged their avatar",
|
||||
"%(oneUser)schanged their avatar": "%(oneUser)schanged their avatar",
|
||||
"Please select the destination room for this message": "Please select the destination room for this message",
|
||||
"Start automatically after system login": "Start automatically after system login",
|
||||
"Desktop specific": "Desktop specific",
|
||||
"Analytics": "Analytics",
|
||||
"Opt out of analytics": "Opt out of analytics",
|
||||
"Options": "Options",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.",
|
||||
"Passphrases must match": "Passphrases must match",
|
||||
"Passphrase must not be empty": "Passphrase must not be empty",
|
||||
"Export room keys": "Export room keys",
|
||||
"Enter passphrase": "Enter passphrase",
|
||||
"Confirm passphrase": "Confirm passphrase",
|
||||
"Import room keys": "Import room keys",
|
||||
"File to import": "File to import",
|
||||
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.",
|
||||
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.",
|
||||
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.",
|
||||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.",
|
||||
"You must join the room to see its files": "You must join the room to see its files",
|
||||
"Reject all %(invitedRooms)s invites": "Reject all %(invitedRooms)s invites",
|
||||
"Start new chat": "Start new chat",
|
||||
"Guest users can't invite users. Please register.": "Guest users can't invite users. Please register.",
|
||||
"Failed to invite": "Failed to invite",
|
||||
"Failed to invite user": "Failed to invite user",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Failed to invite the following users to the %(roomName)s room:",
|
||||
"Confirm Removal": "Confirm Removal",
|
||||
"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.": "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.",
|
||||
"Unknown error": "Unknown error",
|
||||
"Incorrect password": "Incorrect password",
|
||||
"This will make your account permanently unusable. You will not be able to re-register the same user ID.": "This will make your account permanently unusable. You will not be able to re-register the same user ID.",
|
||||
"This action is irreversible.": "This action is irreversible.",
|
||||
"To continue, please enter your password.": "To continue, please enter your password.",
|
||||
"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:": "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:",
|
||||
"Device name": "Device name",
|
||||
"Device key": "Device key",
|
||||
"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.": "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.",
|
||||
"In future this verification process will be more sophisticated.": "In future this verification process will be more sophisticated.",
|
||||
"Verify device": "Verify device",
|
||||
"I verify that the keys match": "I verify that the keys match",
|
||||
"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.": "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.",
|
||||
"Unable to restore session": "Unable to restore session",
|
||||
"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.": "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.",
|
||||
"Continue anyway": "Continue anyway",
|
||||
"Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contains devices that you haven't seen before.",
|
||||
"Unknown devices": "Unknown devices",
|
||||
"Unknown Address": "Unknown Address",
|
||||
"Unblacklist": "Unblacklist",
|
||||
"Blacklist": "Blacklist",
|
||||
"Unverify": "Unverify",
|
||||
"Verify...": "Verify...",
|
||||
"ex. @bob:example.com": "ex. @bob:example.com",
|
||||
"Add User": "Add User",
|
||||
"This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot",
|
||||
"Sign in with CAS": "Sign in with CAS",
|
||||
"Custom Server Options": "Custom Server Options",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.",
|
||||
"This allows you to use this app with an existing Matrix account on a different home server.": "This allows you to use this app with an existing Matrix account on a different home server.",
|
||||
"You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "You can also set a custom identity server but this will typically prevent interaction with users based on email address.",
|
||||
"Dismiss": "Dismiss",
|
||||
"Please check your email to continue registration.": "Please check your email to continue registration.",
|
||||
"Token incorrect": "Token incorrect",
|
||||
"A text message has been sent to": "A text message has been sent to",
|
||||
"Please enter the code it contains:": "Please enter the code it contains:",
|
||||
"powered by Matrix": "powered by Matrix",
|
||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
|
||||
"You are registering with %(SelectedTeamName)s": "You are registering with %(SelectedTeamName)s",
|
||||
"Default server": "Default server",
|
||||
"Custom server": "Custom server",
|
||||
"Home server URL": "Home server URL",
|
||||
"Identity server URL": "Identity server URL",
|
||||
"What does this mean?": "What does this mean?",
|
||||
"Error decrypting audio": "Error decrypting audio",
|
||||
"Error decrypting image": "Error decrypting image",
|
||||
"Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.",
|
||||
"This image cannot be displayed.": "This image cannot be displayed.",
|
||||
"Error decrypting video": "Error decrypting video",
|
||||
"Add an Integration": "Add an Integration",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?",
|
||||
"Removed or unknown message type": "Removed or unknown message type",
|
||||
"Disable URL previews by default for participants in this room": "Disable URL previews by default for participants in this room",
|
||||
"URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.",
|
||||
"URL Previews": "URL Previews",
|
||||
"Enable URL previews for this room (affects only you)": "Enable URL previews for this room (affects only you)",
|
||||
"Drop file here to upload": "Drop file here to upload",
|
||||
" (unsupported)": " (unsupported)",
|
||||
"Ongoing conference call%(supportedText)s.": "Ongoing conference call%(supportedText)s.",
|
||||
"for %(amount)ss": "for %(amount)ss",
|
||||
"for %(amount)sm": "for %(amount)sm",
|
||||
"for %(amount)sh": "for %(amount)sh",
|
||||
"for %(amount)sd": "for %(amount)sd",
|
||||
"Online": "Online",
|
||||
"Idle": "Idle",
|
||||
"Offline": "Offline",
|
||||
"Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)",
|
||||
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName changed the room avatar to <img/>",
|
||||
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.",
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s",
|
||||
"Active call (%(roomName)s)": "Active call (%(roomName)s)",
|
||||
"Accept": "Accept",
|
||||
"a room": "a room",
|
||||
"Add": "Add",
|
||||
"Admin tools": "Admin tools",
|
||||
"And %(count)s more...": "And %(count)s more...",
|
||||
"Alias (optional)": "Alias (optional)",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
|
||||
"<a>Click here</a> to join the discussion!": "<a>Click here</a> to join the discussion!",
|
||||
"Close": "Close",
|
||||
"%(count)s new messages.one": "%(count)s new message",
|
||||
"%(count)s new messages.other": "%(count)s new messages",
|
||||
"Custom": "Custom",
|
||||
"Decline": "Decline",
|
||||
"Disable markdown formatting": "Disable markdown formatting",
|
||||
"Disable Notifications": "Disable Notifications",
|
||||
"Enable Notifications": "Enable Notifications"
|
||||
}
|
|
@ -225,7 +225,7 @@
|
|||
"Displays action": "Mostrar acción",
|
||||
"Don't send typing notifications": "No enviar notificaciones cuando se escribe",
|
||||
"Download %(text)s": "Descargar %(text)s",
|
||||
"Drop here %(toAction)s": "Suelta aquí para %(toAction)s",
|
||||
"Drop here %(toAction)s": "Suelta aquí %(toAction)s",
|
||||
"Drop here to tag %(section)s": "Suelta aquí para etiquetar %(section)s",
|
||||
"Ed25519 fingerprint": "Clave de cifrado Ed25519",
|
||||
"Email": "Correo electrónico",
|
||||
|
@ -282,7 +282,7 @@
|
|||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s",
|
||||
"Guests can't set avatars. Please register.": "Invitados no puedes establecer avatares. Por favor regístrate.",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Usuarios invitados no pueden crear nuevas salas. Por favor regístrate para crear la sala y iniciar la conversación.",
|
||||
"Guest users can't upload files. Please register to upload": "Usuarios invitados no puedes subir archivos. Por favor regístrate para subir tus archivos",
|
||||
"Guest users can't upload files. Please register to upload.": "Usuarios invitados no puedes subir archivos. Por favor regístrate para subir tus archivos.",
|
||||
"Guests can't use labs features. Please register.": "Invitados no puedes usar las características en desarrollo. Por favor regístrate.",
|
||||
"Guests cannot join this room even if explicitly invited.": "Invitados no pueden unirse a esta sala aun cuando han sido invitados explícitamente.",
|
||||
"had": "tuvo",
|
||||
|
|
|
@ -294,7 +294,7 @@
|
|||
"Found a bug?": "Trouvé un problème ?",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Les visiteurs ne peuvent créer de nouveaux salons. Merci de vous enregistrer pour commencer une discussion.",
|
||||
"Guest users can't upload files. Please register to upload": "Les visiteurs ne peuvent telécharger de fichiers. Merci de vous enregistrer pour télécharger",
|
||||
"Guest users can't upload files. Please register to upload.": "Les visiteurs ne peuvent pas télécharger de fichier. Veuillez vous enregistrer pour télécharger.",
|
||||
"had": "avait",
|
||||
"Hangup": "Raccrocher",
|
||||
"Hide read receipts": "Cacher les accusés de réception",
|
||||
|
@ -386,7 +386,7 @@
|
|||
"Email address": "Adresse e-mail",
|
||||
"Error decrypting attachment": "Erreur lors du déchiffrement de la pièce jointe",
|
||||
"Failed to set avatar.": "Erreur lors de la définition de la photo de profil.",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Par sécurité une deconnexion supprimera toutes les clés d’encryption de cet explorateur. Si vous voulez être capable de décrypter l’historique de votre conversation lors de sessions futures de Riot, merci d’exporter les clés pour le salon.",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Par sécurité une déconnexion supprimera toutes les clés d’encryption de ce navigateur. Si vous voulez être capable de décrypter l’historique de votre conversation lors de sessions futures de Riot, merci d’exporter les clés pour le salon.",
|
||||
"Guests can't set avatars. Please register.": "Les visiteurs ne peuvent définir de photo de profil. Merci de vous enregistrer.",
|
||||
"Guests can't use labs features. Please register.": "Les visiteurs ne peuvent utiliser les fonctionalités du laboratoire. Merci de vous enregistrer.",
|
||||
"Guests cannot join this room even if explicitly invited.": "Les visiteurs ne peuvent rejoindre ce salon, même si explicitement invités.",
|
||||
|
@ -457,7 +457,7 @@
|
|||
"since the point in time of selecting this option": "depuis le moment où cette option a été sélectionnée",
|
||||
"since they joined": "depuis qu’ils ont rejoint le salon",
|
||||
"since they were invited": "depuis qu’ils ont été invités",
|
||||
"Some of your messages have not been sent": "Certains de vos messages n’ont pas été envoyés",
|
||||
"Some of your messages have not been sent.": "Certains de vos messages n’ont pas été envoyés.",
|
||||
"Someone": "Quelqu'un",
|
||||
"Sorry, this homeserver is using a login which is not recognised ": "Désolé, ce homeserver utilise un identifiant qui n’est pas reconnu ",
|
||||
"Start a chat": "Démarrer une conversation",
|
||||
|
@ -468,7 +468,7 @@
|
|||
"tag direct chat": "marquer comme conversation directe",
|
||||
"The default role for new room members is": "Le rôle par défaut des nouveaux membres est",
|
||||
"The main address for this room is": "L'adresse principale pour ce salon est",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "Cette action ne peut être effectuée par un visiteur. Merci de vous enregistrer afin de pouvoir effectuer cette action",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "Cette action ne peut être effectuée par un visiteur. Merci de vous enregistrer afin de pouvoir effectuer cette action.",
|
||||
"This email address is already in use": "Cette adresse e-mail est déjà utilisée",
|
||||
"This email address was not found": "Cette adresse e-mail n’a pas été trouvée",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s cette personne ?",
|
||||
|
@ -478,7 +478,6 @@
|
|||
"The remote side failed to pick up": "Le correspondant n’a pas décroché",
|
||||
"This room has no local addresses": "Ce salon n'a pas d'adresse locale",
|
||||
"This room is not recognised.": "Ce salon n'a pas été reconnu.",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "Ce salon est privé ou non autorisé aux visiteurs. Vous devriez pouvoir le rejoindre si vous vous enregistrez",
|
||||
"These are experimental features that may break in unexpected ways": "Ces fonctionnalités sont expérimentales et risquent de mal fonctionner",
|
||||
"The visibility of existing history will be unchanged": "La visibilité de l’historique existant sera inchangée",
|
||||
"This doesn't appear to be a valid email address": "Cette adresse n’a pas l’air d’être valide",
|
||||
|
@ -500,15 +499,15 @@
|
|||
"to make a room or": "pour créer un salon ou",
|
||||
"To remove other users' messages": "Pour supprimer les messages des autres utilisateurs",
|
||||
"To reset your password, enter the email address linked to your account": "Pour réinitialiser votre mot de passe, merci d’entrer l’adresse email liée à votre compte",
|
||||
"to restore": "restaurer",
|
||||
"to restore": "pour restaurer",
|
||||
"To send events of type": "Pour envoyer des évènements du type",
|
||||
"To send messages": "Pour envoyer des messages",
|
||||
"to start a chat with someone": "pour démarrer une conversation avec quelqu’un",
|
||||
"to tag as %(tagName)s": "pour marquer comme %(tagName)s",
|
||||
"to tag direct chat": "pour marquer comme conversation directe",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "Pour l’utiliser, attendez simplement que les résultats de l’auto-complétion s’affichent et défilez avec la touche Tab.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question": "Une tentative de chargement d’un point donné dans la chronologie de ce salon a été effectuée, mais vous n’avez pas la permission de voir le message en question",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it": "Une tentative de chargement d’un point donné dans la chronologie de ce salon a été effectuée, mais il n’a pas été trouvé",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Un instant donné de la chronologie n’a pu être chargé car vous n’avez pas la permission de le visualiser.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Un instant donné de la chronologie n’a pu être chargé car il n’a pas pu être trouvé.",
|
||||
"Turn Markdown off": "Désactiver le formatage ’Markdown’",
|
||||
"Turn Markdown on": "Activer le formatage ’Markdown’",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s a activé l’encryption bout-en-bout (algorithme %(algorithm)s).",
|
||||
|
@ -558,7 +557,7 @@
|
|||
"Would you like to": "Voulez-vous",
|
||||
"You are already in a call.": "Vous êtes déjà dans un appel.",
|
||||
"You're not in any rooms yet! Press": "Vous n’êtes dans aucun salon ! Cliquez",
|
||||
"You are trying to access %(roomName)s": "Vous essayez d'accéder à %(roomName)s",
|
||||
"You are trying to access %(roomName)s.": "Vous essayez d'accéder à %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "Vous ne pouvez pas passer d'appel avec vous-même.",
|
||||
"You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel voix dans cet explorateur.",
|
||||
"You do not have permission to post to this room": "Vous n’avez pas la permission de poster dans ce salon",
|
||||
|
@ -577,7 +576,7 @@
|
|||
"You seem to be uploading files, are you sure you want to quit?": "Vous semblez être en train de télécharger des fichiers, êtes-vous sûr(e) de vouloir quitter ?",
|
||||
"You should not yet trust it to secure data": "Vous ne pouvez pas encore lui faire confiance pour sécuriser vos données",
|
||||
"changing room on a RoomView is not supported": "changer de salon sur un RoomView n'est pas supporté",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself": "Vous ne pourrez pas défaire ce changement car vous promouvez l’utilisateur aux mêmes pouvoirs que vous",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Vous ne pourrez pas défaire ce changement car vous promouvez l’utilisateur aux mêmes pouvoirs que vous.",
|
||||
"Sun": "Dim",
|
||||
"Mon": "Lun",
|
||||
"Tue": "Mar",
|
||||
|
@ -611,7 +610,7 @@
|
|||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Les noms d’utilisateurs ne peuvent contenir que des lettres, chiffres, points et tirets hauts ou bas.",
|
||||
"An unknown error occurred.": "Une erreur inconnue est survenue.",
|
||||
"I already have an account": "J’ai déjà un compte",
|
||||
"An error occured: %(error_string)s": "Une erreur est survenue : %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "Une erreur est survenue : %(error_string)s",
|
||||
"Topic": "Sujet",
|
||||
"Make Moderator": "Nommer modérateur",
|
||||
"Make this room private": "Rendre ce salon privé",
|
||||
|
@ -620,7 +619,7 @@
|
|||
"There are no visible files in this room": "Il n'y a pas de fichier visible dans ce salon",
|
||||
"Room": "Salon",
|
||||
"Connectivity to the server has been lost.": "La connectivité au serveur a été perdue.",
|
||||
"Sent messages will be stored until your connection has returned.": "Les messages envoyé seront stockés jusqu’à ce que votre connection revienne.",
|
||||
"Sent messages will be stored until your connection has returned.": "Les messages envoyés seront stockés jusqu’à ce que votre connection revienne.",
|
||||
"Auto-complete": "Auto-complétion",
|
||||
"Resend all": "Tout renvoyer",
|
||||
"(~%(searchCount)s results)": "(~%(searchCount)s résultats)",
|
||||
|
@ -760,7 +759,7 @@
|
|||
"Enable URL previews for this room (affects only you)": "Activer les aperçus d'URL pour ce salon (n'affecte que vous)",
|
||||
"Drop file here to upload": "Déposer le fichier ici pour le télécharger",
|
||||
" (unsupported)": " (non supporté)",
|
||||
"Ongoing conference call%(supportedText)s. %(joinText)s": "Appel conférence en cours%(supportedText)s. %(joinText)s",
|
||||
"Ongoing conference call%(supportedText)s.": "Appel conférence en cours%(supportedText)s.",
|
||||
"Online": "En ligne",
|
||||
"Offline": "Déconnecté",
|
||||
"Disable URL previews for this room (affects only you)": "Désactiver les aperçus d'URL pour ce salon (n'affecte que vous)",
|
||||
|
@ -827,5 +826,33 @@
|
|||
"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"
|
||||
"Hide removed messages": "Cacher les messages supprimés",
|
||||
"Add": "Ajouter",
|
||||
"%(count)s new messages.one": "%(count)s nouveau message",
|
||||
"%(count)s new messages.other": "%(count)s nouveaux messages",
|
||||
"Disable markdown formatting": "Désactiver le formattage markdown",
|
||||
"Error: Problem communicating with the given homeserver.": "Erreur: Problème de communication avec le homeserveur.",
|
||||
"Failed to fetch avatar URL": "Échec lors de la récupération de l’URL de l’avatar",
|
||||
"The phone number entered looks invalid": "Le numéro de téléphone entré semble être invalide",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register.": "Ce salon est privé ou interdits aux visiteurs. Vous pourrez peut-être le joindre si vous vous enregistrez.",
|
||||
"Uploading %(filename)s and %(count)s others.zero": "Téléchargement de %(filename)s",
|
||||
"Uploading %(filename)s and %(count)s others.one": "Téléchargement de %(filename)s et %(count)s autre",
|
||||
"Uploading %(filename)s and %(count)s others.other": "Téléchargement de %(filename)s et %(count)s autres",
|
||||
"You must <a>register</a> to use this functionality": "Vous devez vous <a>inscrire</a> pour utiliser cette fonctionnalité",
|
||||
"<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.": "<a>Tout renvoyer</a> or <a>tout annuler</a> maintenant. Vous pouvez aussi sélectionner des messages individuels à envoyer ou annuler.",
|
||||
"Create new room": "Créer un nouveau salon",
|
||||
"Welcome page": "Page d'accueil",
|
||||
"Room directory": "Répertoire des salons",
|
||||
"Start chat": "Démarrer une discussion",
|
||||
"New Password": "Nouveau mot de passe",
|
||||
"Start chatting": "Démarrer une discussion",
|
||||
"Start Chatting": "Démarrer une discussion",
|
||||
"Click on the button below to start chatting!": "Cliquer sur le bouton ci-dessous pour commencer une discussion !",
|
||||
"Create a new chat or reuse an existing one": "Démarrer une nouvelle discussion ou en réutiliser une existante",
|
||||
"You already have existing direct chats with this user:": "Vous avez déjà des discussions en cours avec cet utilisateur :",
|
||||
"Username available": "Nom d'utilisateur disponible",
|
||||
"Username not available": "Nom d'utilisateur indisponible",
|
||||
"Something went wrong!": "Quelque chose s’est mal passé !",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Cela sera le nom de votre compte sur le serveur <span></span>, ou vous pouvez sélectionner un <a>autre serveur</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Si vous avez déjà un compte Matrix vous pouvez vous <a>identifier</a> à la place."
|
||||
}
|
||||
|
|
21
src/i18n/strings/he.json
Normal file
21
src/i18n/strings/he.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"ar-ae": "ערבית (U.A.E)",
|
||||
"ar-bh": "ערבית (בחריין)",
|
||||
"ar-dz": "ערבית (אלג'יריה)",
|
||||
"ar-eg": "ערבית (מצריים)",
|
||||
"ar-iq": "ערבית (עיראק)",
|
||||
"ar-jo": "ערבית (ירדן)",
|
||||
"af": "אפריקאית",
|
||||
"ar-kw": "ערבית (כווית)",
|
||||
"ar-lb": "ערבית (לבנון)",
|
||||
"ar-ly": "ערבית (לוב)",
|
||||
"ar-ma": "ערבית (מרוקו)",
|
||||
"ar-om": "ערבית (אומן)",
|
||||
"ar-qa": "ערבית (קטאר)",
|
||||
"ar-sa": "ערבית (ערב הסעודית)",
|
||||
"ar-sy": "ערבית (סוריה)",
|
||||
"ar-tn": "ערבית (תוניסיה)",
|
||||
"ar-ye": "ערבית (תימן)",
|
||||
"be": "בלארוסית",
|
||||
"bg": "בולגרית"
|
||||
}
|
|
@ -1 +1,183 @@
|
|||
{}
|
||||
{
|
||||
"Cancel": "Mégse",
|
||||
"Search": "Keresés",
|
||||
"OK": "Rendben",
|
||||
"Custom Server Options": "Egyedi szerver beállítások",
|
||||
"Direct Chat": "Közvetlen csevegés",
|
||||
"Dismiss": "Eltűntet",
|
||||
"Drop here %(toAction)s": "%(toAction)s -t húzd ide",
|
||||
"Error": "Hiba",
|
||||
"Failed to forget room %(errCode)s": "Nem lehet eltávolítani a szobát: %(errCode)s",
|
||||
"Failed to join the room": "Nem lehet csatlakozni a szobához",
|
||||
"Favourite": "Kedvenc",
|
||||
"Mute": "Elnémít",
|
||||
"Notifications": "Értesítések",
|
||||
"Operation failed": "Művelet sikertelen",
|
||||
"Please Register": "Regisztrálj",
|
||||
"powered by Matrix": "Matrixon alapul",
|
||||
"Remove": "Töröl",
|
||||
"Settings": "Beállítások",
|
||||
"unknown error code": "ismeretlen hiba kód",
|
||||
"Sunday": "Vasárnap",
|
||||
"Monday": "Hétfő",
|
||||
"Tuesday": "Kedd",
|
||||
"Wednesday": "Szerda",
|
||||
"Thursday": "Csütörtök",
|
||||
"Friday": "Péntek",
|
||||
"Saturday": "Szombat",
|
||||
"af": "Afrikaans",
|
||||
"ar-ae": "Arabic (U.A.E.)",
|
||||
"ar-bh": "Arabic (Bahrain)",
|
||||
"ar-dz": "Arabic (Algeria)",
|
||||
"ar-eg": "Arabic (Egypt)",
|
||||
"ar-iq": "Arabic (Iraq)",
|
||||
"ar-jo": "Arabic (Jordan)",
|
||||
"ar-kw": "Arabic (Kuwait)",
|
||||
"ar-lb": "Arabic (Lebanon)",
|
||||
"ar-ly": "Arabic (Libya)",
|
||||
"ar-ma": "Arabic (Morocco)",
|
||||
"ar-om": "Arabic (Oman)",
|
||||
"ar-qa": "Arabic (Qatar)",
|
||||
"ar-sa": "Arabic (Saudi Arabia)",
|
||||
"ar-sy": "Arabic (Syria)",
|
||||
"ar-tn": "Arabic (Tunisia)",
|
||||
"ar-ye": "Arabic (Yemen)",
|
||||
"be": "Belorusz",
|
||||
"bg": "Bolgár",
|
||||
"ca": "Katalán",
|
||||
"cs": "Cseh",
|
||||
"da": "Dán",
|
||||
"de-at": "Német (Osztrák)",
|
||||
"de-ch": "Német (Svájci)",
|
||||
"de": "Német",
|
||||
"de-li": "Német (Lichtenstein)",
|
||||
"de-lu": "Német (Luxemburg)",
|
||||
"el": "Görög",
|
||||
"en-au": "Angol (Ausztrál)",
|
||||
"en-bz": "Angol (Belize)",
|
||||
"en-ca": "Angol (Kanada)",
|
||||
"en": "Angol",
|
||||
"en-gb": "Angol (Egyesült Királyság)",
|
||||
"en-ie": "Angol (Ír)",
|
||||
"en-jm": "Angol (Jamaika)",
|
||||
"en-nz": "Angol (Új-Zéland)",
|
||||
"en-tt": "Angol (Trinidad)",
|
||||
"en-us": "Angol (Egyesült Államok)",
|
||||
"en-za": "Angol (Dél-Afrika)",
|
||||
"es-ar": "Spanyol (Argentína)",
|
||||
"es-bo": "Spanyol (Bolívia)",
|
||||
"es-cl": "Spanyol (Chile)",
|
||||
"es-co": "Spanyol (Kolumbia)",
|
||||
"es-cr": "Spanyol (Costa Rica)",
|
||||
"es-do": "Spanyol (Dominikai Köztársaság)",
|
||||
"es-ec": "Spanyol (Ecuador)",
|
||||
"es-gt": "Spanyol (Guatemala)",
|
||||
"es-hn": "Spanyol (Honduras)",
|
||||
"es-mx": "Spanyol (Mexikó)",
|
||||
"es-ni": "Spanyol (Nicaragua)",
|
||||
"es-pa": "Spanyol (Panama)",
|
||||
"es-pe": "Spanyol (Peru)",
|
||||
"es-pr": "Spanyol (Puerto Rico)",
|
||||
"es-py": "Spanyol (Paraguay)",
|
||||
"es": "Spanyol (Spanyol)",
|
||||
"es-sv": "Spanyol (El Salvador)",
|
||||
"es-uy": "Spanyol (Uruguay)",
|
||||
"es-ve": "Spanyol (Venezuela)",
|
||||
"et": "Észt",
|
||||
"eu": "Baszk (Baszk)",
|
||||
"fa": "Perzsa",
|
||||
"fi": "Finn",
|
||||
"fo": "Feröer",
|
||||
"fr-be": "Francia (Belgium)",
|
||||
"fr-ca": "Francia (Kanada)",
|
||||
"fr-ch": "Francia (Svájc)",
|
||||
"fr": "Francia",
|
||||
"fr-lu": "Francia (Luxemburg)",
|
||||
"ga": "Ír",
|
||||
"gd": "Gall (Skót)",
|
||||
"he": "Héber",
|
||||
"hi": "Hindu",
|
||||
"hr": "Horvát",
|
||||
"hu": "Magyar",
|
||||
"id": "Indonéz",
|
||||
"is": "Izland",
|
||||
"it-ch": "Olasz (Svájc)",
|
||||
"it": "Olasz",
|
||||
"ja": "Japán",
|
||||
"ji": "Jiddis",
|
||||
"ko": "Korea",
|
||||
"lt": "Litván",
|
||||
"lv": "Lett",
|
||||
"mk": "Macedónia (FYROM)",
|
||||
"ms": "Maláj",
|
||||
"mt": "Málta",
|
||||
"nl-be": "Holland (Belgium)",
|
||||
"nl": "Holland",
|
||||
"no": "Norvég",
|
||||
"pl": "Lengyel",
|
||||
"pt-br": "Portugál (Brazil)",
|
||||
"pt": "Portugál",
|
||||
"ro-mo": "Román (Moldova)",
|
||||
"ro": "Román",
|
||||
"ru-mo": "Orosz (Moldova)",
|
||||
"ru": "Orosz",
|
||||
"sk": "Szlovák",
|
||||
"sl": "Szlovén",
|
||||
"sq": "Albán",
|
||||
"sr": "Szerb",
|
||||
"sv-fi": "Svéd (Finn)",
|
||||
"sv": "Svéd",
|
||||
"sx": "Sutu",
|
||||
"sz": "Sami (Lapp)",
|
||||
"th": "Thai",
|
||||
"tr": "Török",
|
||||
"ts": "Tsonga",
|
||||
"uk": "Ukrán",
|
||||
"ur": "Urdu",
|
||||
"ve": "Venda",
|
||||
"vi": "Vietnám",
|
||||
"xh": "Xhosa",
|
||||
"zh-cn": "Kína (PRC)",
|
||||
"zh-hk": "Kína (Hong Kong SAR)",
|
||||
"zh-sg": "Kína (Szingapúr)",
|
||||
"zh-tw": "Kína (Tajvan)",
|
||||
"zu": "Zulu",
|
||||
"A registered account is required for this action": "Regisztrált fiókra van szükség ehhez a művelethez",
|
||||
"a room": "egy szoba",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Elküldtük a szöveges üzenetet ide: +%(msisdn)s. Kérlek add meg az ellenőrző kódot ami benne van",
|
||||
"Accept": "Elfogad",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s elfogadta a meghívást.",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s elfogadta a meghívást ide: %(displayName)s.",
|
||||
"Account": "Fiók",
|
||||
"Access Token:": "Elérési kulcs:",
|
||||
"Active call (%(roomName)s)": "Hívás folyamatban (%(roomName)s)",
|
||||
"Add": "Hozzáad",
|
||||
"Add a topic": "Téma megadása",
|
||||
"Add email address": "E-mail cím megadása",
|
||||
"Add phone number": "Telefonszám megadása",
|
||||
"Admin": "Adminisztrátor",
|
||||
"Admin tools": "Admin. eszközök",
|
||||
"And %(count)s more...": "És még %(count)s...",
|
||||
"VoIP": "VoIP",
|
||||
"Missing Media Permissions, click here to request.": "Hiányzó Média jogosultság, kattintson ide az igényléshez.",
|
||||
"No Microphones detected": "Nem található mikrofon",
|
||||
"No Webcams detected": "Nem található webkamera",
|
||||
"No media permissions": "Nincs media jogosultság",
|
||||
"You may need to manually permit Riot to access your microphone/webcam": "Lehet hogy manuálisan kell engedélyeznie a Riot-nak a hozzáférést a mikrofonhoz ás webkamerához",
|
||||
"Default Device": "Alapértelmezett eszköz",
|
||||
"Microphone": "Mikrofon",
|
||||
"Camera": "Kamera",
|
||||
"Advanced": "Haladó",
|
||||
"Algorithm": "Algoritmus",
|
||||
"Hide removed messages": "Törölt üzenetek elrejtése",
|
||||
"Always show message timestamps": "Üzenet időbélyeg folyamatos megjelenítése",
|
||||
"Authentication": "Azonosítás",
|
||||
"Alias (optional)": "Becenév (opcionális)",
|
||||
"all room members": "minden szoba tagság",
|
||||
"Failed to change password. Is your password correct?": "Nem sikerült megváltoztatni a jelszót. Helyesen írtad be a jelszavadat?",
|
||||
"Continue": "Folytatás",
|
||||
"Create new room": "Új szoba létrehozása",
|
||||
"sb": "Szorb",
|
||||
"rm": "Rétoromán",
|
||||
"tn": "Tswana"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,6 @@
|
|||
"Confirm password": "Bevestigen wachtwoord",
|
||||
"Confirm your new password": "Bevestig je nieuwe wachtwoord",
|
||||
"Continue": "Doorgaan",
|
||||
"Could not connect to the integration server": "Mislukt om te verbinden met de integratie server"
|
||||
"Could not connect to the integration server": "Mislukt om te verbinden met de integratie server",
|
||||
"Cancel": "Annuleer"
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
"Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.",
|
||||
"Guests can't set avatars. Please register.": "Convidados não podem definir uma foto do perfil. Por favor, registre-se.",
|
||||
"Guests can't use labs features. Please register.": "Convidados não podem usar as funcionalidades de laboratório (lab), por gentileza se registre.",
|
||||
"Guest users can't upload files. Please register to upload": "Usuários não podem fazer envio de arquivos. Por favor se cadastre para enviar arquivos",
|
||||
"Guest users can't upload files. Please register to upload.": "Usuários não podem fazer envio de arquivos. Por favor se cadastre para enviar arquivos.",
|
||||
"had": "teve",
|
||||
"Hangup": "Desligar",
|
||||
"Historical": "Histórico",
|
||||
|
@ -161,7 +161,7 @@
|
|||
"Phone": "Telefone",
|
||||
"placed a": "iniciou uma",
|
||||
"Please check your email and click on the link it contains. Once this is done, click continue.": "Por favor verifique seu email e clique no link enviado. Quando finalizar este processo, clique para continuar.",
|
||||
"Please Register": "Por favor, cadastre-se",
|
||||
"Please Register": "Por favor registe-se",
|
||||
"Privacy warning": "Alerta sobre privacidade",
|
||||
"Privileged Users": "Usuárias/os privilegiadas/os",
|
||||
"Profile": "Perfil",
|
||||
|
@ -329,7 +329,7 @@
|
|||
"Conference calls are not supported in encrypted rooms": "Chamadas de conferência não são possíveis em salas criptografadas",
|
||||
"Conference calls are not supported in this client": "Chamadas de conferência não são possíveis neste navegador",
|
||||
"/ddg is not a command": "/ddg não é um comando",
|
||||
"Drop here %(toAction)s": "Arraste aqui %(toAction)s",
|
||||
"Drop here %(toAction)s": "Arraste aqui para %(toAction)s",
|
||||
"Drop here to tag %(section)s": "Arraste aqui para marcar como %(section)s",
|
||||
"%(senderName)s ended the call.": "%(senderName)s finalizou a chamada.",
|
||||
"Existing Call": "Chamada em andamento",
|
||||
|
@ -399,7 +399,7 @@
|
|||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.",
|
||||
"You are already in a call.": "Você já está em uma chamada.",
|
||||
"You're not in any rooms yet! Press": "Você ainda não está em nenhuma sala! Pressione",
|
||||
"You are trying to access %(roomName)s": "Você está tentando acessar a sala %(roomName)s",
|
||||
"You are trying to access %(roomName)s.": "Você está tentando acessar a sala %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "Você não pode iniciar uma chamada.",
|
||||
"You cannot place VoIP calls in this browser.": "Você não pode fazer chamadas de voz neste navegador.",
|
||||
"You need to be able to invite users to do that.": "Para fazer isso, você tem que ter permissão para convidar outras pessoas.",
|
||||
|
@ -417,7 +417,7 @@
|
|||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Nomes de usuária/o podem conter apenas letras, números, pontos, hífens e linha inferior (_).",
|
||||
"An unknown error occurred.": "Um erro desconhecido ocorreu.",
|
||||
"I already have an account": "Eu já tenho uma conta",
|
||||
"An error occured: %(error_string)s": "Um erro ocorreu: %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "Um erro ocorreu: %(error_string)s",
|
||||
"Topic": "Tópico",
|
||||
"Make this room private": "Tornar esta sala privada",
|
||||
"Share message history with new users": "Compartilhar histórico de mensagens com novas/os usuárias/os",
|
||||
|
@ -433,17 +433,17 @@
|
|||
"now. You can also select individual messages to resend or cancel.": "agora. Você também pode escolher mensagens individuais e definir se vai reenviar ou cancelar o envio.",
|
||||
"Active call": "Chamada ativa",
|
||||
"af": "Afrikaans",
|
||||
"ar-ae": "Árabe (U.A.E.)",
|
||||
"ar-ae": "Árabe (E.A.U.)",
|
||||
"ar-bh": "Árabe (Bahrain)",
|
||||
"ar-dz": "Árabe (Algéria)",
|
||||
"ar-dz": "Árabe (Argélia)",
|
||||
"Sunday": "Domingo",
|
||||
"Monday": "Segunda",
|
||||
"Monday": "Segunda-feira",
|
||||
"ar-eg": "Árabe (Egito)",
|
||||
"ar-tn": "Árabe (Tunisia)",
|
||||
"be": "Bielorusso",
|
||||
"ar-tn": "Árabe (Tunísia)",
|
||||
"be": "Bielorrusso",
|
||||
"bg": "Búlgaro",
|
||||
"ca": "Catalão",
|
||||
"cs": "Tcheco",
|
||||
"cs": "Checo",
|
||||
"el": "Grego",
|
||||
"en-au": "Inglês (Austrália)",
|
||||
"en-ca": "Inglês (Canadá)",
|
||||
|
@ -496,12 +496,12 @@
|
|||
"vi": "Vietnamita",
|
||||
"xh": "Xhosa",
|
||||
"zu": "Zulu",
|
||||
"Failed to forget room %(errCode)s": "Falhou ao esquecer a sala %(errCode)s",
|
||||
"Failed to join the room": "Falhou ao entrar na sala",
|
||||
"Tuesday": "Terça",
|
||||
"Wednesday": "Quarta",
|
||||
"Thursday": "Quinta",
|
||||
"Friday": "Sexta",
|
||||
"Failed to forget room %(errCode)s": "Falha ao esquecer a sala %(errCode)s",
|
||||
"Failed to join the room": "Falha ao entrar na sala",
|
||||
"Tuesday": "Terça-feira",
|
||||
"Wednesday": "Quarta-feira",
|
||||
"Thursday": "Quinta-feira",
|
||||
"Friday": "Sexta-feira",
|
||||
"Saturday": "Sábado",
|
||||
"ar-iq": "Árabe (Iraque)",
|
||||
"ar-jo": "Árabe (Jordânia)",
|
||||
|
@ -514,13 +514,13 @@
|
|||
"ar-sa": "Árabe (Arábia Saudita)",
|
||||
"ar-sy": "Árabe (Síria)",
|
||||
"ar-ye": "Árabe (Iémen)",
|
||||
"de-at": "Alemão (Austria)",
|
||||
"de-at": "Alemão (Áustria)",
|
||||
"de-ch": "Alemão (Suíça)",
|
||||
"de-li": "Alemão (Liechtenstein)",
|
||||
"de-lu": "Alemão (Luxemburgo)",
|
||||
"en-bz": "Inglês (Belize)",
|
||||
"en-jm": "Inglês (Jamaica)",
|
||||
"en-tt": "English (Trindade)",
|
||||
"en-tt": "Inglês (Trindade)",
|
||||
"en-za": "English (África do Sul)",
|
||||
"es-bo": "Espanhol (Bolívia)",
|
||||
"es-cl": "Espanhol (Chile)",
|
||||
|
@ -621,21 +621,20 @@
|
|||
"No results": "Sem resultados",
|
||||
"OK": "Ok",
|
||||
"Revoke Moderator": "Retirar status de moderador",
|
||||
"Search": "Buscar",
|
||||
"Search": "Pesquisar",
|
||||
"Search failed": "Busca falhou",
|
||||
"Server error": "Erro no servidor",
|
||||
"Server may be unavailable, overloaded, or search timed out :(": "O servidor pode estar indisponível, sobrecarregado, ou a busca ultrapassou o tempo limite :(",
|
||||
"Server may be unavailable, overloaded, or the file too big": "O servidor pode estar indisponível, sobrecarregado, ou o arquivo é muito grande",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "O servidor pode estar indisponível, sobrecarregado, ou alguma outra coisa não funcionou.",
|
||||
"Some of your messages have not been sent": "Algumas das suas mensagens não foram enviadas",
|
||||
"Some of your messages have not been sent.": "Algumas das suas mensagens não foram enviadas.",
|
||||
"Submit": "Enviar",
|
||||
"The main address for this room is": "O endereço principal desta sala é",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "Esta ação não pode ser realizada por um/a usuário/a visitante. Por favor, registre-se para poder fazer isso",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "Esta ação não pode ser realizada por um/a usuário/a visitante. Por favor, registre-se para poder fazer isso.",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s esta pessoa?",
|
||||
"This room has no local addresses": "Esta sala não tem endereços locais",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "Esta sala é privada ou inacessível para visitantes. Você poderá ingressar nela se registrar-se",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question": "Tentei carregar um ponto específico na linha do tempo desta sala, mas parece que você não tem permissões para ver a mensagem em questão",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas parece que você não tem permissões para ver a mensagem em questão.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei.",
|
||||
"Turn Markdown off": "Desabilitar a formatação 'Markdown'",
|
||||
"Turn Markdown on": "Habilitar a marcação 'Markdown'",
|
||||
"Unable to load device list": "Não foi possível carregar a lista de dispositivos",
|
||||
|
@ -644,7 +643,7 @@
|
|||
"You have been invited to join this room by %(inviterName)s": "Você foi convidada/o por %(inviterName)s a ingressar nesta sala",
|
||||
"You seem to be in a call, are you sure you want to quit?": "Parece que você está em uma chamada. Tem certeza que quer sair?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Parece que você está enviando arquivos. Tem certeza que quer sair?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself": "Você não poderá desfazer esta mudança, pois estará dando a este(a) usuário(a) o mesmo nível de permissões que você",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer esta mudança, pois estará dando a este(a) usuário(a) o mesmo nível de permissões que você.",
|
||||
"Make Moderator": "Tornar moderador(a)",
|
||||
"Room": "Sala",
|
||||
"(~%(searchCount)s results)": "(±%(searchCount)s resultados)",
|
||||
|
@ -714,7 +713,7 @@
|
|||
"Invalid file%(extra)s": "Arquivo inválido %(extra)s",
|
||||
"Logged in as:": "Logado como:",
|
||||
"matrix-react-sdk version:": "versão do matrix-react-sdk:",
|
||||
"Mute": "Mudo",
|
||||
"Mute": "Silenciar",
|
||||
"olm version:": "versão do olm:",
|
||||
"Operation failed": "A operação falhou",
|
||||
"Registration required": "Registro obrigatório",
|
||||
|
@ -809,7 +808,7 @@
|
|||
"Enable URL previews for this room (affects only you)": "Habilitar pré-visualizações de links para esta sala (afeta somente a você)",
|
||||
"Drop file here to upload": "Arraste um arquivo aqui para enviar",
|
||||
" (unsupported)": " (não suportado)",
|
||||
"Ongoing conference call%(supportedText)s. %(joinText)s": "Conferência%(supportedText)s em andamento. %(joinText)s",
|
||||
"Ongoing conference call%(supportedText)s.": "Conferência%(supportedText)s em andamento.",
|
||||
"Online": "Online",
|
||||
"Idle": "Ocioso",
|
||||
"Offline": "Offline",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"Error": "Erro",
|
||||
"Event information": "Informação do evento",
|
||||
"Export E2E room keys": "Exportar chaves ponta-a-ponta da sala",
|
||||
"Failed to change password. Is your password correct?": "Não foi possível modificar a senha. A senha informada está correta?",
|
||||
"Failed to change password. Is your password correct?": "Não foi possível mudar a senha. A sua senha está correta?",
|
||||
"Failed to forget room": "Não foi possível esquecer a sala",
|
||||
"Failed to leave room": "Falha ao tentar deixar a sala",
|
||||
"Failed to reject invitation": "Falha ao tentar rejeitar convite",
|
||||
|
@ -101,7 +101,7 @@
|
|||
"Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.",
|
||||
"Guests can't set avatars. Please register.": "Convidados não podem definir uma foto do perfil. Por favor, registre-se.",
|
||||
"Guests can't use labs features. Please register.": "Convidados não podem usar as funcionalidades de laboratório (lab), por gentileza se registre.",
|
||||
"Guest users can't upload files. Please register to upload": "Usuários não podem fazer envio de arquivos. Por favor se cadastre para enviar arquivos",
|
||||
"Guest users can't upload files. Please register to upload.": "Usuários não podem fazer envio de arquivos. Por favor se cadastre para enviar arquivos.",
|
||||
"had": "teve",
|
||||
"Hangup": "Desligar",
|
||||
"Historical": "Histórico",
|
||||
|
@ -399,7 +399,7 @@
|
|||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.",
|
||||
"You are already in a call.": "Você já está em uma chamada.",
|
||||
"You're not in any rooms yet! Press": "Você ainda não está em nenhuma sala! Pressione",
|
||||
"You are trying to access %(roomName)s": "Você está tentando acessar a sala %(roomName)s",
|
||||
"You are trying to access %(roomName)s.": "Você está tentando acessar a sala %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "Você não pode iniciar uma chamada.",
|
||||
"You cannot place VoIP calls in this browser.": "Você não pode fazer chamadas de voz neste navegador.",
|
||||
"You need to be able to invite users to do that.": "Para fazer isso, você tem que ter permissão para convidar outras pessoas.",
|
||||
|
@ -417,7 +417,7 @@
|
|||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Nomes de usuária/o podem conter apenas letras, números, pontos, hífens e linha inferior (_).",
|
||||
"An unknown error occurred.": "Um erro desconhecido ocorreu.",
|
||||
"I already have an account": "Eu já tenho uma conta",
|
||||
"An error occured: %(error_string)s": "Um erro ocorreu: %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "Um erro ocorreu: %(error_string)s",
|
||||
"Topic": "Tópico",
|
||||
"Make this room private": "Tornar esta sala privada",
|
||||
"Share message history with new users": "Compartilhar histórico de mensagens com novas/os usuárias/os",
|
||||
|
@ -627,15 +627,14 @@
|
|||
"Server may be unavailable, overloaded, or search timed out :(": "O servidor pode estar indisponível, sobrecarregado, ou a busca ultrapassou o tempo limite :(",
|
||||
"Server may be unavailable, overloaded, or the file too big": "O servidor pode estar indisponível, sobrecarregado, ou o arquivo é muito grande",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "O servidor pode estar indisponível, sobrecarregado, ou alguma outra coisa não funcionou.",
|
||||
"Some of your messages have not been sent": "Algumas das suas mensagens não foram enviadas",
|
||||
"Some of your messages have not been sent.": "Algumas das suas mensagens não foram enviadas.",
|
||||
"Submit": "Enviar",
|
||||
"The main address for this room is": "O endereço principal desta sala é",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "Esta ação não pode ser realizada por um/a usuário/a visitante. Por favor, registre-se para poder fazer isso",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "Esta ação não pode ser realizada por um/a usuário/a visitante. Por favor, registre-se para poder fazer isso.",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s esta pessoa?",
|
||||
"This room has no local addresses": "Esta sala não tem endereços locais",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "Esta sala é privada ou inacessível para visitantes. Você poderá ingressar nela se registrar-se",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question": "Tentei carregar um ponto específico na linha do tempo desta sala, mas parece que você não tem permissões para ver a mensagem em questão",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas parece que você não tem permissões para ver a mensagem em questão.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei.",
|
||||
"Turn Markdown off": "Desabilitar a formatação 'Markdown'",
|
||||
"Turn Markdown on": "Habilitar a marcação 'Markdown'",
|
||||
"Unable to load device list": "Não foi possível carregar a lista de dispositivos",
|
||||
|
@ -644,7 +643,7 @@
|
|||
"You have been invited to join this room by %(inviterName)s": "Você foi convidada/o por %(inviterName)s a ingressar nesta sala",
|
||||
"You seem to be in a call, are you sure you want to quit?": "Parece que você está em uma chamada. Tem certeza que quer sair?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Parece que você está enviando arquivos. Tem certeza que quer sair?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself": "Você não poderá desfazer esta mudança, pois estará dando a este(a) usuário(a) o mesmo nível de permissões que você",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer esta mudança, pois estará dando a este(a) usuário(a) o mesmo nível de permissões que você.",
|
||||
"Make Moderator": "Tornar moderador(a)",
|
||||
"Room": "Sala",
|
||||
"(~%(searchCount)s results)": "(±%(searchCount)s resultados)",
|
||||
|
@ -809,7 +808,7 @@
|
|||
"Enable URL previews for this room (affects only you)": "Habilitar pré-visualizações de links para esta sala (afeta somente a você)",
|
||||
"Drop file here to upload": "Arraste um arquivo aqui para enviar",
|
||||
" (unsupported)": " (não suportado)",
|
||||
"Ongoing conference call%(supportedText)s. %(joinText)s": "Conferência%(supportedText)s em andamento. %(joinText)s",
|
||||
"Ongoing conference call%(supportedText)s.": "Conferência%(supportedText)s em andamento.",
|
||||
"Online": "Online",
|
||||
"Idle": "Ocioso",
|
||||
"Offline": "Offline",
|
||||
|
@ -877,5 +876,93 @@
|
|||
"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"
|
||||
"Hide removed messages": "Ocultar mensagens removidas",
|
||||
"Add": "Adicionar",
|
||||
"%(count)s new messages.one": "%(count)s nova mensagem",
|
||||
"%(count)s new messages.other": "%(count)s novas mensagens",
|
||||
"Disable markdown formatting": "Desabilitar formatação MarkDown",
|
||||
"Error: Problem communicating with the given homeserver.": "Erro: problema de comunicação com o Servidor de Base fornecido.",
|
||||
"Failed to fetch avatar URL": "Falha ao obter a URL da imagem de perfil",
|
||||
"Home": "Início",
|
||||
"The phone number entered looks invalid": "O número de telefone inserido parece ser inválido",
|
||||
"Uploading %(filename)s and %(count)s others.zero": "Enviando o arquivo %(filename)s",
|
||||
"Uploading %(filename)s and %(count)s others.one": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
|
||||
"Uploading %(filename)s and %(count)s others.other": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
|
||||
"Username invalid: %(errMessage)s": "Nome de usuária(o) inválido: %(errMessage)s",
|
||||
"Searching known users": "Buscando pessoas conhecidas",
|
||||
"You must <a>register</a> to use this functionality": "Você deve <a>se registrar</a> para poder usar esta funcionalidade",
|
||||
"<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.": "<a>Reenviar todas</a> ou <a>cancelar todas</a> agora. Você também pode selecionar mensagens individuais que queira reenviar ou cancelar.",
|
||||
"Create new room": "Criar nova sala",
|
||||
"Welcome page": "Página de boas vindas",
|
||||
"Room directory": "Lista pública de salas",
|
||||
"Start chat": "Iniciar conversa pessoal",
|
||||
"New Password": "Nova senha",
|
||||
"Start chatting": "Iniciar a conversa",
|
||||
"Start Chatting": "Iniciar a conversa",
|
||||
"Click on the button below to start chatting!": "Clique no botão abaixo para começar a conversar!",
|
||||
"Create a new chat or reuse an existing one": "Criar uma nova conversa ou reutilizar alguma já existente",
|
||||
"You already have existing direct chats with this user:": "Você já tem conversas pessoais com esta pessoa:",
|
||||
"Username available": "Nome de usuária(o) disponível",
|
||||
"Username not available": "Nome de usuária(o) indisponível",
|
||||
"Something went wrong!": "Algo deu errado!",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Este será seu nome de conta no Servidor de Base <span></span>, ou então você pode escolher um <a>servidor diferente</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Se você já tem uma conta Matrix, pode também fazer <a>login</a>.",
|
||||
"a room": "uma sala",
|
||||
"Accept": "Aceitar",
|
||||
"Active call (%(roomName)s)": "Chamada ativa (%(roomName)s)",
|
||||
"Admin tools": "Ferramentas de administração",
|
||||
"And %(count)s more...": "E mais %(count)s...",
|
||||
"Alias (optional)": "Apelido (opcional)",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Não foi possível conectar ao Servidor de Base. Por favor, confira sua conectividade à internet, garanta que o <a>certificado SSL do Servidor de Base</a> é confiável, e que uma extensão do navegador não esteja bloqueando as requisições de rede.",
|
||||
"<a>Click here</a> to join the discussion!": "<a>Clique aqui</a> para participar da conversa!",
|
||||
"Close": "Fechar",
|
||||
"Custom": "Personalizado",
|
||||
"Decline": "Recusar",
|
||||
"Disable Notifications": "Desabilitar notificações",
|
||||
"Drop File Here": "Arraste o arquivo aqui",
|
||||
"Enable Notifications": "Habilitar notificações",
|
||||
"Encrypted by a verified device": "Criptografado por um dispositivo verificado",
|
||||
"Encrypted by an unverified device": "Criptografado por um dispositivo não verificado",
|
||||
"Failed to upload profile picture!": "Falha ao enviar a imagem de perfil!",
|
||||
"Incoming call from %(name)s": "Chamada de %(name)s recebida",
|
||||
"Incoming video call from %(name)s": "Chamada de vídeo de %(name)s recebida",
|
||||
"Incoming voice call from %(name)s": "Chamada de voz de %(name)s recebida",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Participar por <voiceText>voz</voiceText> ou por <videoText>vídeo</videoText>.",
|
||||
"Last seen": "Último uso",
|
||||
"Level:": "Nível:",
|
||||
"No display name": "Sem nome público de usuária(o)",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Caso contrário, <a>clique aqui</a> para enviar um relatório de erros.",
|
||||
"Private Chat": "Conversa privada",
|
||||
"Public Chat": "Conversa pública",
|
||||
"Reason: %(reasonText)s": "Justificativa: %(reasonText)s",
|
||||
"Rejoin": "Voltar a participar da sala",
|
||||
"Room contains unknown devices": "Esta sala contém dispositivos desconhecidos",
|
||||
"%(roomName)s does not exist.": "%(roomName)s não existe.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s não está acessível neste momento.",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s em %(dateTime)s",
|
||||
"Send anyway": "Enviar de qualquer maneira",
|
||||
"Set": "Definir",
|
||||
"Show Text Formatting Toolbar": "Exibir barra de formatação de texto",
|
||||
"Start authentication": "Iniciar autenticação",
|
||||
"This invitation was sent to an email address which is not associated with this account:": "Este convite foi enviado para um endereço de e-mail que não é associado a esta conta:",
|
||||
"This room": "Esta sala",
|
||||
"To link to a room it must have <a>an address</a>.": "Para produzir um link para uma sala, ela necessita ter <a>um endereço</a>.",
|
||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Não foi possível garantir que o endereço para o qual este convite foi enviado bate com alqum que está associado com sua conta.",
|
||||
"Undecryptable": "Não é possível descriptografar",
|
||||
"Unencrypted message": "Mensagem não criptografada",
|
||||
"unknown caller": "a pessoa que está chamando é desconhecida",
|
||||
"Unnamed Room": "Sala sem nome",
|
||||
"Unverified": "Não verificado",
|
||||
"Upload new:": "Enviar novo:",
|
||||
"%(user)s is a": "%(user)s é um(a)",
|
||||
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nível de permissão %(powerLevelNumber)s)",
|
||||
"Verified": "Verificado",
|
||||
"Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?": "Você gostaria de <acceptText>aceitar</acceptText> ou <declineText>recusar</declineText> este convite?",
|
||||
"You have been banned from %(roomName)s by %(userName)s.": "Você foi expulso(a) da sala %(roomName)s por %(userName)s.",
|
||||
"You have been kicked from %(roomName)s by %(userName)s.": "Você foi removido(a) da sala %(roomName)s por %(userName)s.",
|
||||
"You may wish to login with a different account, or add this email to this account.": "Você pode querer fazer login com uma conta diferente, ou adicionar este e-mail a esta conta.",
|
||||
"Your home server does not support device management.": "O seu Servidor de Base não suporta o gerenciamento de dispositivos.",
|
||||
"(~%(count)s results).one": "(~%(count)s resultado)",
|
||||
"(~%(count)s results).other": "(~%(count)s resultados)",
|
||||
"Device Name": "Nome do dispositivo"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"Account": "Аккаунт",
|
||||
"Add email address": "Добавить email адрес",
|
||||
"Add phone number": "Добавить телефонный номер",
|
||||
"Admin": "Admin",
|
||||
"Admin": "Админ",
|
||||
"Advanced": "Дополнительно",
|
||||
"Algorithm": "Алгоритм",
|
||||
"all room members": "все участники комнаты",
|
||||
|
@ -54,12 +54,12 @@
|
|||
"Deactivate my account": "Деактивировать мою учётную запись",
|
||||
"decline": "отказаться",
|
||||
"Decryption error": "Ошибка дешифрования",
|
||||
"Default": "Default",
|
||||
"Default": "Стандарт",
|
||||
"demote": "понижать",
|
||||
"Deops user with given id": "Deops пользователь с данным id",
|
||||
"Device ID": "Устройство ID",
|
||||
"Devices will not yet be able to decrypt history from before they joined the room": "Устройство еще не будет в состоянии дешифровать историю, до присоединения к комнате",
|
||||
"Direct Chat": "Персональное сообщение",
|
||||
"Direct Chat": "Приватный чат",
|
||||
"Disable inline URL previews by default": "Отключить встроенные предварительные просмотры URL по умолчанию",
|
||||
"Display name": "Отображаемое имя",
|
||||
"Displays action": "Отображение действий",
|
||||
|
@ -75,7 +75,7 @@
|
|||
"Error": "Ошибка",
|
||||
"Event information": "Event information",
|
||||
"Export E2E room keys": "Экспорт E2E ключей комнаты",
|
||||
"Failed to change password. Is your password correct?": "Не удалось изменить пароль. Ваш пароль правильный?",
|
||||
"Failed to change password. Is your password correct?": "Не удалось сменить пароль. Вы правильно ввели текущий пароль?",
|
||||
"Failed to forget room": "Не удалось забыть комнату",
|
||||
"Failed to leave room": "Не удалось выйти из комнаты",
|
||||
"Failed to reject invitation": "Не удалось отклонить приглашение",
|
||||
|
@ -83,23 +83,23 @@
|
|||
"Failed to unban": "Не удалось отменить запрет",
|
||||
"Failed to upload file": "Не удалось закачать файл",
|
||||
"Favourite": "Избранное",
|
||||
"favourite": "фаворит",
|
||||
"Favourites": "Фавориты",
|
||||
"favourite": "Избранное",
|
||||
"Favourites": "Избранное",
|
||||
"Filter room members": "Фильтр участников комнаты",
|
||||
"Forget room": "Забыть комнату",
|
||||
"Forgot your password?": "Вы забыли пароль?",
|
||||
"For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности, эта сессия была подписана. Войдите в систему еще раз.",
|
||||
"For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности эта сессия была завершена. Войдите в систему еще раз.",
|
||||
"Found a bug?": "Нашли ошибку?",
|
||||
"had": "имеет",
|
||||
"Hangup": "Отключение",
|
||||
"Historical": "Исторический",
|
||||
"Historical": "История",
|
||||
"Homeserver is": "Домашний сервер является",
|
||||
"Identity Server is": "Регистрационный Сервер является",
|
||||
"Identity Server is": "Регистрационный сервер",
|
||||
"I have verified my email address": "Я проверил мой адрес электронной почты",
|
||||
"Import E2E room keys": "Импортировать E2E ключ комнаты",
|
||||
"Invalid Email Address": "Недействительный адрес электронной почты",
|
||||
"invited": "invited",
|
||||
"Invite new room members": "Прегласить новых учасников комнаты",
|
||||
"Invite new room members": "Пригласить новых участников в комнату",
|
||||
"Invites": "Приглашать",
|
||||
"Invites user with given id to current room": "Пригласить пользователя с данным id в текущую комнату",
|
||||
"is a": "является",
|
||||
|
@ -108,10 +108,10 @@
|
|||
"joined": "присоединенный",
|
||||
"joined the room": "joined the room",
|
||||
"Joins room with given alias": "Присоединяется к комнате с данным псевдонимом",
|
||||
"Kicks user with given id": "Кик пользователя с заданным id",
|
||||
"Kicks user with given id": "Выгнать пользователя с заданным id",
|
||||
"Labs": "Лаборатория",
|
||||
"Leave room": "Уйти из комнаты",
|
||||
"left and rejoined": "Покинуть и переподключится",
|
||||
"left and rejoined": "Покинуть и пере подключится",
|
||||
"left": "покинуть",
|
||||
"left the room": "left the room",
|
||||
"Logged in as": "Зарегистрированный как",
|
||||
|
@ -119,13 +119,13 @@
|
|||
"Logout": "Выход из системы",
|
||||
"Low priority": "Низкий приоритет",
|
||||
"made future room history visible to": "made future room history visible to",
|
||||
"Manage Integrations": "Управление интеграций",
|
||||
"Manage Integrations": "Управление Интеграциями",
|
||||
"Members only": "Только участники",
|
||||
"Mobile phone number": "Номер мобильного телефона",
|
||||
"Moderator": "Ведущий",
|
||||
"my Matrix ID": "мой Matrix ID",
|
||||
"Name": "Имя",
|
||||
"Never send encrypted messages to unverified devices from this device": "Никогда не отправляйте зашифрованные сообщения в непроверенные устройства с этого устройства",
|
||||
"Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на не верифицированные устройства с этого устройства",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправляйте зашифрованные сообщения в непроверенные устройства в этой комнате из этого устройства",
|
||||
"New password": "Новый пароль",
|
||||
"New passwords must match each other.": "Новые пароли должны соответствовать друг другу.",
|
||||
|
@ -153,13 +153,13 @@
|
|||
"requested a VoIP conference": "requested a VoIP conference",
|
||||
"Return to login screen": "Return to login screen",
|
||||
"Send Reset Email": "Send Reset Email",
|
||||
"sent an image": "sent an image",
|
||||
"sent an image": "отправил изображение",
|
||||
"sent an invitation to": "sent an invitation to",
|
||||
"set a profile picture": "set a profile picture",
|
||||
"set their display name to": "set their display name to",
|
||||
"Settings": "Настройки",
|
||||
"Start a chat": "Start a chat",
|
||||
"Start Chat": "Start Chat",
|
||||
"Start a chat": "Начать чат",
|
||||
"Start Chat": "Начать чат",
|
||||
"tag as": "tag as",
|
||||
"These are experimental features that may break in unexpected ways. Use with caution": "These are experimental features that may break in unexpected ways. Use with caution",
|
||||
"To send events of type": "Для отправки типа событий",
|
||||
|
@ -170,8 +170,8 @@
|
|||
"Unable to verify email address.": "Невозможно проверить адрес электронной почты.",
|
||||
"Unban": "Отменить запрет",
|
||||
"Unencrypted room": "Незашифрованная комната",
|
||||
"unencrypted": "незашифрованно",
|
||||
"unknown device": "неизвесное устройство",
|
||||
"unencrypted": "незашифровано",
|
||||
"unknown device": "неизвестное устройство",
|
||||
"unknown error code": "неизвестная ошибка",
|
||||
"unknown": "неизвестно",
|
||||
"Upload avatar": "Загрузить аватар",
|
||||
|
@ -189,8 +189,8 @@
|
|||
"Video call": "Видио вызов",
|
||||
"Voice call": "Голосовой вызов",
|
||||
"VoIP conference finished.": "VoIP конференция закончилась.",
|
||||
"VoIP conference started.": "VoIP Конференция стартовала.",
|
||||
"(warning: cannot be disabled again!)": "(предупреждение: не может быть снова отключен!)",
|
||||
"VoIP conference started.": "VoIP Конференция началась.",
|
||||
"(warning: cannot be disabled again!)": "(предупреждение: не может быть отключено!)",
|
||||
"Warning!": "Предупреждение!",
|
||||
"was banned": "запрещен",
|
||||
"was invited": "приглашенный",
|
||||
|
@ -200,7 +200,7 @@
|
|||
"were": "быть",
|
||||
"Who can access this room?": "Кто может получить доступ к этой комнате?",
|
||||
"Who can read history?": "Кто может читать историю?",
|
||||
"Who would you like to add to this room?": "Кого хотели бы Вы добавлять к этой комнате?",
|
||||
"Who would you like to add to this room?": "Кого бы вы хотели пригласить в эту комнату?",
|
||||
"Who would you like to communicate with?": "С кем хотели бы Вы связываться?",
|
||||
"withdrawn": "уходить",
|
||||
"Would you like to": "Хотели бы Вы",
|
||||
|
@ -228,16 +228,16 @@
|
|||
"%(senderName)s banned %(targetName)s.": "%(senderName)s запрещенный %(targetName)s.",
|
||||
"Call Timeout": "Время ожидания вызова",
|
||||
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s их имя измененное с %(oldDisplayName)s на %(displayName)s.",
|
||||
"%(senderName)s changed their profile picture.": "%(senderName)s измененное ихнее фото профиля.",
|
||||
"%(senderName)s changed their profile picture.": "%(senderName)s изменил фото профиля.",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s уровень мощности изменен на %(powerLevelDiffText)s.",
|
||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s имя комнаты измененно на %(roomName)s.",
|
||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s имя комнаты изменено на %(roomName)s.",
|
||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s измененная тема на %(topic)s.",
|
||||
"Conference call failed.": "Конференц-вызов прервался.",
|
||||
"Conference calling is in development and may not be reliable.": "Конференц-вызов находится в процессе и может не быть надежным.",
|
||||
"Conference calls are not supported in encrypted rooms": "Конференц-вызовы не поддерживаются в зашифрованных комнатах",
|
||||
"Conference calls are not supported in this client": "Конференц-вызовы не поддерживаются в этом клиенте",
|
||||
"/ddg is not a command": "/ddg не команда",
|
||||
"Drop here %(toAction)s": "Вставить здесь %(toAction)s",
|
||||
"Drop here %(toAction)s": "Вставить сюда: %(toAction)s",
|
||||
"Drop here to tag %(section)s": "Вставить здесь для тега %(section)s",
|
||||
"%(senderName)s ended the call.": "%(senderName)s прекратил звонок.",
|
||||
"Existing Call": "Существующий вызов",
|
||||
|
@ -246,7 +246,7 @@
|
|||
"Failed to set up conference call": "Не удалось установить конференц-вызов",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "Не удалось подтвердить email-адрес: убедитесь что вы щелкнули по ссылке электронной почты",
|
||||
"Failure to create room": "Не удалось создать комнату",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s из %(fromPowerLevel)s до %(toPowerLevel)s",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId) изменил %(fromPowerLevel) на %(toPowerLevel)",
|
||||
"Guest users can't create new rooms. Please register to create room and start a chat.": "Гостевые пользователи не могут создавать новые комнаты. Зарегистрируйтесь для создания комнаты и чата.",
|
||||
"click to reveal": "нажать для открытия",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.",
|
||||
|
@ -254,16 +254,16 @@
|
|||
"%(targetName)s joined the room.": "%(targetName)s вошёл в комнату.",
|
||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s выкинул %(targetName)s.",
|
||||
"%(targetName)s left the room.": "%(targetName)s покинул комнату.",
|
||||
"%(senderName)s made future room history visible to": "%(senderName)s история сделаной будущей комнаты, видимая для",
|
||||
"%(senderName)s made future room history visible to": "%(senderName)s сделал видимой для всех будущую историю комнаты",
|
||||
"Missing room_id in request": "Отсутствует room_id в запросе",
|
||||
"Missing user_id in request": "Отсутствует user_id в запросе",
|
||||
"Must be viewing a room": "Комната должна быть посищена",
|
||||
"New Composer & Autocomplete": "Новые Компонист & Автозаполнение",
|
||||
"Must be viewing a room": "Посмотреть комнату",
|
||||
"New Composer & Autocomplete": "Новый автор & Автозаполнение",
|
||||
"(not supported by this browser)": "(не поддерживаемый этим браузером)",
|
||||
"af": "Африкаанс",
|
||||
"ar-ae": "Арабский (О.А.Е)",
|
||||
"ar-bh": "Арабский (Бахрейн)",
|
||||
"ar-dz": "Арабский (Алжыр)",
|
||||
"ar-dz": "Арабский (Алжир)",
|
||||
"ar-eg": "Арабский (Египет)",
|
||||
"ar-iq": "Арабский (Ирак)",
|
||||
"ar-jo": "Арабский (Иордания)",
|
||||
|
@ -285,7 +285,7 @@
|
|||
"de-ch": "Немецкий (Швейцария)",
|
||||
"de-li": "Немецкий (Лихтенштейн)",
|
||||
"de-lu": "Немецкий (Люксембург)",
|
||||
"el": "Гречиский",
|
||||
"el": "Греческий",
|
||||
"en-au": "Английский (Австралия)",
|
||||
"en-bz": "Английский (Белиз)",
|
||||
"en-ca": "Английский (Канада)",
|
||||
|
@ -310,7 +310,7 @@
|
|||
"es-pa": "Испанский (Панама)",
|
||||
"et": "Эстонский",
|
||||
"fi": "Финский",
|
||||
"fr": "Французкий",
|
||||
"fr": "Французский",
|
||||
"hr": "Хорватский",
|
||||
"it": "Итальянский",
|
||||
"ja": "Японский",
|
||||
|
@ -320,7 +320,7 @@
|
|||
"ro": "Румынский",
|
||||
"uk": "Украинский",
|
||||
"now. You can also select individual messages to resend or cancel.": "теперь. Вы можете также выбрать отдельные сообщения, чтобы снова послать или отменить.",
|
||||
"Auto-complete": "Автозаполнение",
|
||||
"Auto-complete": "Авто-заполнение",
|
||||
"Error changing language": "Ошибка изменения языка",
|
||||
"Riot was unable to find the correct Data for the selected Language.": "Riot был неспособен найти правельные данные для выбранного языка.",
|
||||
"Connectivity to the server has been lost.": "Связь с сервером была потеряна.",
|
||||
|
@ -336,7 +336,7 @@
|
|||
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Имена пользователей могут только содержать буквы, числа, точки, дефисы и подчеркивания.",
|
||||
"An unknown error occurred.": "Произошла неизвестная ошибка.",
|
||||
"I already have an account": "У меня уже есть учетная запись",
|
||||
"An error occured: %(error_string)s": "Произошла ошибка: %(error_string)s",
|
||||
"An error occurred: %(error_string)s": "Произошла ошибка: %(error_string)s",
|
||||
"Topic": "Тема",
|
||||
"Make this room private": "Сделать эту комнату частной",
|
||||
"Share message history with new users": "Поделись историей сообщений с новыми учасниками",
|
||||
|
@ -355,16 +355,16 @@
|
|||
"Friday": "Пятница",
|
||||
"Saturday": "Суббота",
|
||||
"Sunday": "Воскресенье",
|
||||
"%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s",
|
||||
"Upload an avatar:": "Загрузить аватар",
|
||||
"You need to be logged in.": "Вы должны быть зарегистрированы",
|
||||
"%(weekDayName)s %(time)s": "%(weekDayName) %(time)",
|
||||
"Upload an avatar:": "Загрузите аватар:",
|
||||
"You need to be logged in.": "Вы должны быть зарегистрированы.",
|
||||
"You need to be able to invite users to do that.": "Вам необходимо пригласить пользователей чтобы сделать это.",
|
||||
"You cannot place VoIP calls in this browser.": "Вы не можете сделать вызовы VoIP с этим браузером.",
|
||||
"You are already in a call.": "Вы уже находитесь в разговоре.",
|
||||
"You are already in a call.": "Связь уже установлена.",
|
||||
"You're not in any rooms yet! Press": "Вы еще не находитесь ни в каких комнатах! Нажать",
|
||||
"You are trying to access %(roomName)s": "Вы пытаетесь получить доступ %(roomName)s",
|
||||
"You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ %(roomName)s.",
|
||||
"You cannot place a call with yourself.": "Вы не можете позвонить самим себе.",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s анулировал %(targetName)s's преглашение.",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отменил %(targetName)s's приглашение.",
|
||||
"Sep": "Сен.",
|
||||
"Jan": "Янв.",
|
||||
"Feb": "Фев.",
|
||||
|
@ -377,7 +377,7 @@
|
|||
"Oct": "Окт.",
|
||||
"Nov": "Ноя.",
|
||||
"Dec": "Дек.",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s",
|
||||
"Mon": "Пн",
|
||||
"Sun": "Вс",
|
||||
"Tue": "Вт",
|
||||
|
@ -388,16 +388,16 @@
|
|||
"You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "Вам необходимо снова войти в генерировать сквозное шифрование (е2е) ключей для этого устройства и предоставить публичный ключ Вашему домашнему серверу. Это после выключения; приносим извинения за причиненные неудобства.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес электронной почты, кажется, не связан с Matrix ID на этом Homeserver.",
|
||||
"to start a chat with someone": "Начать чат с кем-то",
|
||||
"to tag direct chat": "Пометить прямой чат",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "Для его использования, просто подождите результатов автозаполнения для загрузки на вкладке и через них.",
|
||||
"to tag direct chat": "отметить прямой чат",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "Для его использования просто подождите загрузки результатов авто-заполнения и нажимайте Tab для навигации.",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включил сквозное шифрование (algorithm %(algorithm)s).",
|
||||
"Unable to restore previous session": "Невозможно востановить предыдущий сеанс",
|
||||
"Unable to restore previous session": "Невозможно восстановить предыдущий сеанс",
|
||||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s запрет отменен %(targetName)s.",
|
||||
"Unable to capture screen": "Невозможно записать снимок экрана",
|
||||
"Unable to enable Notifications": "Невозможно включить уведомления",
|
||||
"Upload Failed": "Неудавшаяся загрузка",
|
||||
"Usage": "Использование",
|
||||
"Use with caution": "Используйте с осторожностью",
|
||||
"Use with caution": "Использовать осторожно",
|
||||
"VoIP is unsupported": "VoIP не поддерживается",
|
||||
"es-pr": "Испанский (Пуэрто-Рико)",
|
||||
"es-py": "Испанский язык (Парагвай)",
|
||||
|
@ -426,7 +426,7 @@
|
|||
"sk": "Словацкий",
|
||||
"sl": "Словенский",
|
||||
"sq": "Албанский",
|
||||
"sr": "Сербский (Латиница)",
|
||||
"sr": "Сербский",
|
||||
"sv-fi": "Шведский (Финляндия)",
|
||||
"sz": "Саами (лопарский)",
|
||||
"tn": "Тсвана",
|
||||
|
@ -443,7 +443,7 @@
|
|||
"fr-lu": "Французский (Люксембург)",
|
||||
"gd": "Гэльский (Шотландия)",
|
||||
"it-ch": "Итальянский (Швейцария)",
|
||||
"ko": "Корейский (Johab)",
|
||||
"ko": "Корейский",
|
||||
"mk": "Македонский (FYROM)",
|
||||
"ro-mo": "Румынский (Республика Молдова)",
|
||||
"sx": "Суту",
|
||||
|
@ -477,8 +477,8 @@
|
|||
"Access Token:": "Токен:",
|
||||
"Always show message timestamps": "Всегда показывать время сообщения",
|
||||
"Authentication": "Авторизация",
|
||||
"olm version:": "версия olm:",
|
||||
"%(items)s and %(remaining)s others": "%(items)s и %(remaining)s другие",
|
||||
"olm version:": "Версия olm:",
|
||||
"%(items)s and %(remaining)s others": "%(items)s и другие %(remaining)s",
|
||||
"%(items)s and one other": "%(items)s и ещё один",
|
||||
"%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s",
|
||||
"and one other...": "и ещё один...",
|
||||
|
@ -491,14 +491,14 @@
|
|||
"Current password": "Текущий пароль",
|
||||
"Email": "Электронная почта",
|
||||
"Failed to kick": "Не удалось выгнать",
|
||||
"Failed to load timeline position": "Не удалось узнать место во времени",
|
||||
"Failed to load timeline position": "Не удалось загрузить позицию графика",
|
||||
"Failed to mute user": "Не удалось заглушить",
|
||||
"Failed to reject invite": "Не удалось отклонить приглашение",
|
||||
"Failed to save settings": "Не удалось сохранить настройки",
|
||||
"Failed to set display name": "Не удалось установить отображаемое имя",
|
||||
"Failed to toggle moderator status": "Не удалось изменить статус модератора",
|
||||
"Fill screen": "Заполнить экран",
|
||||
"Guest users can't upload files. Please register to upload": "Гости не могут посылать файлы. Пожалуйста, зарегистрируйтесь для отправки",
|
||||
"Guest users can't upload files. Please register to upload.": "Гости не могут посылать файлы. Пожалуйста, зарегистрируйтесь для отправки.",
|
||||
"Hide read receipts": "Скрыть отметки о прочтении",
|
||||
"Hide Text Formatting Toolbar": "Скрыть панель форматирования текста",
|
||||
"Incorrect verification code": "Неверный код подтверждения",
|
||||
|
@ -519,10 +519,10 @@
|
|||
"New passwords don't match": "Пароли не совпадают",
|
||||
"not set": "не установлено",
|
||||
"not specified": "не указано",
|
||||
"No devices with registered encryption keys": "Нет устройств с записанными ключами шифрования",
|
||||
"No devices with registered encryption keys": "Нет устройств с зарегистрированными ключами шифрования",
|
||||
"No more results": "Нет больше результатов",
|
||||
"No results": "Нет результатов",
|
||||
"OK": "Да",
|
||||
"OK": "ОК",
|
||||
"Only people who have been invited": "Только приглашённые люди",
|
||||
"Passwords can't be empty": "Пароли не могут быть пустыми",
|
||||
"%(senderName)s placed a %(callType)s call.": "%(senderName)s выполнил %(callType)s вызов.",
|
||||
|
@ -535,12 +535,12 @@
|
|||
"rejected": "отклонено",
|
||||
"%(targetName)s rejected the invitation.": "%(targetName)s отклонил приглашение.",
|
||||
"Reject invitation": "Отклонить приглашение",
|
||||
"Remove Contact Information?": "Убрать контактную информацию?",
|
||||
"Remove Contact Information?": "Удалить контактную информацию?",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s убрал своё отображаемое имя (%(oldDisplayName)s).",
|
||||
"%(senderName)s removed their profile picture.": "%(senderName)s убрал своё изображение.",
|
||||
"%(senderName)s requested a VoIP conference.": "%(senderName)s запросил голосовую конференц-связь.",
|
||||
"Report it": "Сообщить об этом",
|
||||
"Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "На данный момент сброс пароля сбросит все ключи шифрования на всех устройствах, зашифрованная история общения будет нечитаема, если вы сперва не скачаете ваши ключи от комнаты и не загрузите их после. В будущем это будет улучшено.",
|
||||
"Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "На данный момент сброс пароля сбросит все ключи шифрования на всех устройствах, зашифрованная история общения будет не читаема, если вы сперва не скачаете ваши ключи от комнаты и не загрузите их после. В будущем это будет улучшено.",
|
||||
"restore": "восстановить",
|
||||
"Return to app": "Вернуться в приложение",
|
||||
"Riot does not have permission to send you notifications - please check your browser settings": "Riot не имеет права для отправки вам уведомлений, пожалуйста, проверьте настройки вашего браузера",
|
||||
|
@ -567,7 +567,7 @@
|
|||
"since the point in time of selecting this option": "с момента выбора этой настройки",
|
||||
"since they joined": "с момента входа",
|
||||
"since they were invited": "с момента приглашения",
|
||||
"Some of your messages have not been sent": "Некоторые из ваших сообщений не были отправлены",
|
||||
"Some of your messages have not been sent.": "Некоторые из ваших сообщений не были отправлены.",
|
||||
"Someone": "Кто-то",
|
||||
"Submit": "Отправить",
|
||||
"Success": "Успех",
|
||||
|
@ -575,7 +575,7 @@
|
|||
"tag direct chat": "отметить прямое общение",
|
||||
"The default role for new room members is": "Роль по умолчанию для новых участников комнаты",
|
||||
"The main address for this room is": "Основной адрес для этой комнаты",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь для этого",
|
||||
"This action cannot be performed by a guest user. Please register to be able to do this.": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь для этого.",
|
||||
"This email address is already in use": "Этот адрес электронной почты уже используется",
|
||||
"This email address was not found": "Этот адрес электронной почты не найден",
|
||||
"The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учётной записью.",
|
||||
|
@ -583,10 +583,9 @@
|
|||
"The remote side failed to pick up": "Удалённая сторона не смогла ответить",
|
||||
"This room has no local addresses": "Эта комната не имеет местного адреса",
|
||||
"This room is not recognised.": "Эта комната не опознана.",
|
||||
"This room is private or inaccessible to guests. You may be able to join if you register": "Эта комната личная или недоступна для гостей. Мы может быть войдёте, если зарегистрируйтесь",
|
||||
"These are experimental features that may break in unexpected ways": "Это экспериментальные возможности, которые могут сломаться неожиданным образом",
|
||||
"These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут неожиданным образом вызывать ошибки",
|
||||
"This doesn't appear to be a valid email address": "Не похоже, что это правильный адрес электронной почты",
|
||||
"This is a preview of this room. Room interactions have been disabled": "Это просмотр данной комнаты. Взаимодействия с ней были отключены.",
|
||||
"This is a preview of this room. Room interactions have been disabled": "Это просмотр данной комнаты. Взаимодействия с ней были отключены",
|
||||
"This phone number is already in use": "Этот телефонный номер уже используется",
|
||||
"This room's internal ID is": "Внутренний ID этой комнаты",
|
||||
"times": "раз",
|
||||
|
@ -599,7 +598,7 @@
|
|||
"Unknown room %(roomId)s": "Неизвестная комната %(roomId)s",
|
||||
"You have been invited to join this room by %(inviterName)s": "Вы были приглашены войти в эту комнату от %(inviterName)s",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Похоже вы передаёте файлы, вы уверены, что хотите выйти?",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s",
|
||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s",
|
||||
"Make Moderator": "Сделать модератором",
|
||||
"Room": "Комната",
|
||||
"Cancel": "Отмена",
|
||||
|
@ -607,7 +606,7 @@
|
|||
"italic": "наклонный",
|
||||
"strike": "перечёркнутый",
|
||||
"underline": "подчёркнутый",
|
||||
"code": "текст",
|
||||
"code": "код",
|
||||
"quote": "цитата",
|
||||
"bullet": "пункт",
|
||||
"numbullet": "нумерация",
|
||||
|
@ -624,7 +623,7 @@
|
|||
"%(severalUsers)sjoined and left": "%(severalUsers)sвошли и ушли",
|
||||
"%(oneUser)sjoined and left": "%(oneUser)sвошёл и ушёл",
|
||||
"%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sушли и перезашли %(repeats)s раз",
|
||||
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sушёл и перезашёл %(repeats)s раз",
|
||||
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s ушёл и перезашёл %(repeats)s раз",
|
||||
"%(severalUsers)sleft and rejoined": "%(severalUsers)sушли и перезашли",
|
||||
"%(oneUser)sleft and rejoined": "%(oneUser)sушёл и перезашёл",
|
||||
"%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)sотклонили приглашения %(repeats)s раз",
|
||||
|
@ -651,5 +650,308 @@
|
|||
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sизменил своё изображение %(repeats)s раз",
|
||||
"%(severalUsers)schanged their avatar": "%(severalUsers)sизменили своё изображение",
|
||||
"%(oneUser)schanged their avatar": "%(oneUser)sизменил своё изображение",
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Не возможно подключиться к серверу через HTTP, когда в строке браузера HTTPS. Используйте HTTPS или <a>включив небезопасные скрипты</a>."
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Не возможно подключиться к серверу через HTTP, когда в строке браузера HTTPS. Используйте HTTPS или <a>включив небезопасные скрипты</a>.",
|
||||
"Dismiss": "Отказ",
|
||||
"Custom Server Options": "Расширенные настройки сервера",
|
||||
"Mute": "Беззвучный",
|
||||
"Operation failed": "Действие не удалось",
|
||||
"powered by Matrix": "управляемый с Matrix",
|
||||
"Add a topic": "Добавить тему",
|
||||
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Время отображать в 12 часовом формате (напр. 2:30pm)",
|
||||
"Use compact timeline layout": "Компактное отображение",
|
||||
"Hide removed messages": "Скрыть удаленное сообщение",
|
||||
"No Microphones detected": "Микрофоны не обнаружены",
|
||||
"Unknown devices": "Незнакомое устройство",
|
||||
"Camera": "Камера",
|
||||
"Microphone": "Микрофон",
|
||||
"Desktop specific": "Специфический десктоп",
|
||||
"Start automatically after system login": "Автостарт после входа в систему",
|
||||
"Analytics": "Аналитика",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, чтобы улучшить эту программу.",
|
||||
"Opt out of analytics": "Подтвердить отказ передачи аналитических данных",
|
||||
"Logged in as:": "Зарегистрирован как:",
|
||||
"Default Device": "Стандартное устройство",
|
||||
"No Webcams detected": "Веб-камера не обнаружена",
|
||||
"VoIP": "VoIP",
|
||||
"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Для обеспечения безопасности выход из системы удалит все ключи шифрования из этого браузера. Если вы хотите иметь возможность расшифровать переписку в будущем - вы должны экспортировать ключи вручную.",
|
||||
"Guest access is disabled on this Home Server.": "Гостевой доступ отключен на этом сервере.",
|
||||
"Guests can't set avatars. Please register.": "Гости не могут устанавливать аватар. Пожалуйста, зарегистрируйтесь.",
|
||||
"Guests can't use labs features. Please register.": "Гости не могут использовать экспериментальные возможности. Пожалуйста, зарегистрируйтесь.",
|
||||
"Guests cannot join this room even if explicitly invited.": "Гости не могут заходить в эту комнату если не были приглашены.",
|
||||
"Missing Media Permissions, click here to request.": "Отсутствуют разрешения, нажмите для запроса.",
|
||||
"No media permissions": "Нет разрешённых носителей",
|
||||
"You may need to manually permit Riot to access your microphone/webcam": "Вам необходимо предоставить Riot доступ к микрофону или веб-камере вручную",
|
||||
"Anyone": "Все",
|
||||
"Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?",
|
||||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил имя комнаты.",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля также сбросит все ключи шифрования на всех устройствах, сделав зашифрованную историю недоступной, если только вы сначала не экспортируете ключи шифрования и не импортируете их потом. В будущем это будет исправлено.",
|
||||
"Custom level": "Пользовательский уровень",
|
||||
"(default: %(userName)s)": "(по-умолчанию: %(userName)s)",
|
||||
"Device already verified!": "Устройство уже верифицировано!",
|
||||
"Device ID:": "ID устройства:",
|
||||
"device id: ": "id устройства: ",
|
||||
"Device key:": "Ключ устройства:",
|
||||
"disabled": "отключено",
|
||||
"Disable markdown formatting": "Отключить форматирование Markdown",
|
||||
"Email address": "Адрес email",
|
||||
"Email address (optional)": "Адрес email (не обязательно)",
|
||||
"enabled": "включено",
|
||||
"Error decrypting attachment": "Ошибка расшифровки файла",
|
||||
"Export": "Экспорт",
|
||||
"Failed to register as guest:": "Ошибка регистрации как гостя:",
|
||||
"Failed to set avatar.": "Не удалось установить аватар.",
|
||||
"Import": "Импорт",
|
||||
"Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.",
|
||||
"Invalid file%(extra)s": "Неправильный файл%(extra)s",
|
||||
"Invited": "Приглашен",
|
||||
"Jump to first unread message.": "Перейти к первому непрочитанному сообщению.",
|
||||
"List this room in %(domain)s's room directory?": "Показывать эту комнату в списке комнат %(domain)s?",
|
||||
"Message not sent due to unknown devices being present": "Сообщение не было отправлено из-за присутствия неизвестного устройства",
|
||||
"Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)",
|
||||
"Once you've followed the link it contains, click below": "Как только вы пройдете по ссылке, нажмите на кнопку ниже",
|
||||
"Password:": "Пароль:",
|
||||
"Privacy warning": "Предупреждение приватности",
|
||||
"Privileged Users": "Привилегированные пользователи",
|
||||
"Revoke Moderator": "Снять права Модератора",
|
||||
"Refer a friend to Riot:": "Расскажите другу о Riot:",
|
||||
"Register": "Регистрация",
|
||||
"Remote addresses for this room:": "Удаленные адреса для этой комнаты:",
|
||||
"Remove %(threePid)s?": "Удалить %(threePid)s?",
|
||||
"Results from DuckDuckGo": "Результаты от DuckDuckGo",
|
||||
"Save": "Сохранить",
|
||||
"Searches DuckDuckGo for results": "Ищет результаты через DuckDuckGo",
|
||||
"Server error": "Ошибка сервера",
|
||||
"Server may be unavailable or overloaded": "Сервер может быть недоступен или перегружен",
|
||||
"Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(",
|
||||
"Server may be unavailable, overloaded, or the file too big": "Сервер может быть недоступен, перегружен или размер файла слишком большой",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Сервер может быть недоступен, перегружен или вы нашли ошибку.",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.",
|
||||
"Session ID": "ID сессии",
|
||||
"%(senderName)s set a profile picture.": "%(senderName)s установил картинку профиля.",
|
||||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s установил отображаемое имя %(displayName)s.",
|
||||
"Setting a user name will create a fresh account": "Установка имени пользователя создаст новую учетную запись",
|
||||
"Signed Out": "Вышли",
|
||||
"Sorry, this homeserver is using a login which is not recognised ": "Извините, этот Home Server использует логин, который не удалось распознать ",
|
||||
"Tagged as: ": "Теги: ",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Ключ, предоставленный вами, совпадает с ключем, полученным от устройства %(userId)s с ID %(deviceId)s. Устройство помечено как верифицированное.",
|
||||
"%(actionVerb)s this person?": "%(actionVerb)s этого пользователя?",
|
||||
"The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает ограничение размера загрузок на этом Home Server'е",
|
||||
"This Home Server does not support login using email address.": "Этот Home Server не поддерживает вход по адресу email.",
|
||||
"There was a problem logging in.": "Возникла проблема входа в учетную запись.",
|
||||
"The visibility of existing history will be unchanged": "Видимость текущей истории не будет изменена",
|
||||
"this invitation?": "это приглашение?",
|
||||
"This room is not accessible by remote Matrix servers": "Это комната закрыта для других серверов Matrix",
|
||||
"To ban users": "Забанить пользователей",
|
||||
"to browse the directory": "просматривать директорию",
|
||||
"To configure the room": "Настроить комнату",
|
||||
"To invite users into the room": "Приглашать пользователей в комнату",
|
||||
"to join the discussion": "присоединиться к дискуссии",
|
||||
"To kick users": "Выгонять пользователей",
|
||||
"To link to a room it must have": "Для создания ссылки на комнату она должна иметь",
|
||||
"to make a room or": "создать комнату или",
|
||||
"To remove other users' messages": "Удалять сообщения других пользователей",
|
||||
"To reset your password, enter the email address linked to your account": "Чтобы сбросить ваш пароль введите адрес email, который используется аккаунтом",
|
||||
"to tag as %(tagName)s": "отметить как %(tagName)s",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Ошибка загрузки истории комнаты: недостаточно прав.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Ошибка загрузки истории комнаты: запрошенный элемент не найден.",
|
||||
"Unable to load device list": "Невозможно загрузить список устройств",
|
||||
"Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:",
|
||||
"Unmute": "Вкл. звук",
|
||||
"Unrecognised command:": "Неизвестная команда:",
|
||||
"Unrecognised room alias:": "Неизвестный псевдоним комнаты:",
|
||||
"Verified key": "Верифицированный ключ",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было верифицировано, однако ключи НЕ СОВПАДАЮТ!",
|
||||
"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!": "ВНИМАНИЕ: ОШИБКА ВЕРИФИКАЦИИ КЛЮЧЕЙ! Ключ для подписки устройства %(deviceId)s пользователя %(userId)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 или адрес email.",
|
||||
"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.": "Вы не сможете отменить это действие так как даете пользователю такой же уровень доступа как и у вас.",
|
||||
"Set a Display Name": "Установить отображаемое имя",
|
||||
"(~%(searchCount)s results)": "(~%(searchCount)s результатов)",
|
||||
"%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)s отозвали свои приглашения %(repeats)s раз",
|
||||
"%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)s отозвал свои приглашения %(repeats)s раз",
|
||||
"%(severalUsers)shad their invitations withdrawn": "%(severalUsers)s отозвали свои приглашения",
|
||||
"%(oneUser)shad their invitation withdrawn": "%(oneUser)s отозвал свое приглашение",
|
||||
"Please select the destination room for this message": "Выберите комнату назначения для этого сообщения",
|
||||
"Options": "Настройки",
|
||||
"Passphrases must match": "Пароли должны совпадать",
|
||||
"Passphrase must not be empty": "Пароль не должен быть пустым",
|
||||
"Export room keys": "Экспортировать ключи",
|
||||
"Enter passphrase": "Введите пароль",
|
||||
"Confirm passphrase": "Подтвердите пароль",
|
||||
"Import room keys": "Импортировать ключи",
|
||||
"File to import": "Файл для импорта",
|
||||
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Этот процесс позволяет вам экспортировать ключи для сообщений, которые вы получили в комнатах с шифрованием, в локальный файл. Вы сможете импортировать эти ключи в другой клиент Matrix чтобы расшифровать эти сообщения.",
|
||||
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Экспортированный файл позволит любому пользователю расшифровать и зашифровать сообщения, которые вы видите, поэтому вы должны быть крайне осторожны и держать файл в надежном месте. Чтобы поспособствовать этому вы должны ввести пароль, который будет использоваться для шифрования ключей. Вы сможете импортировать ключи только зная этот пароль.",
|
||||
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Этот процесс позволяем вам импортировать ключи шифрования, которые вы экспортировали ранее из клиента Matrix. После импорта вы сможете читать зашифрованную переписку и отправлять шифрованные сообщения.",
|
||||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Экспортированный файл защищен паролем. Вы должны ввести этот пароль для расшифровки.",
|
||||
"You must join the room to see its files": "Вы должны зайти в комнату для просмотра файлов",
|
||||
"Reject all %(invitedRooms)s invites": "Отклонить все %(invitedRooms)s приглашения",
|
||||
"Start new chat": "Начать новый чат",
|
||||
"Guest users can't invite users. Please register.": "Гости не могут приглашать пользователей. Пожалуйста, зарегистрируйтесь.",
|
||||
"Failed to invite": "Ошибка приглашения",
|
||||
"Failed to invite user": "Ошибка приглашения пользователя",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Ошибка приглашения следующих пользователей в %(roomName)s:",
|
||||
"Confirm Removal": "Подтвердите удаление",
|
||||
"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.": "Вы уверены, что хотите удалить этот эвент? Обратите внимание, что если это смена имени комнаты или топика, то удаление отменит это изменение.",
|
||||
"Unknown error": "Неизвестная ошибка",
|
||||
"Incorrect password": "Неправильный пароль",
|
||||
"This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Это сделает вашу учетную запись нерабочей. Вы не сможете зарегистрироваться снова с тем же ID.",
|
||||
"This action is irreversible.": "Это действие необратимо.",
|
||||
"To continue, please enter your password.": "Для продолжения введите ваш пароль.",
|
||||
"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:": "Для верификации устройства, пожалуйста, свяжитесь с владельцем используя другие методы коммуникации (например, лично или по телефону) и попросите его подтвердить, что он видит такой же ключ как написанный ниже:",
|
||||
"Device name": "Имя устройства",
|
||||
"Device key": "Ключ устройства",
|
||||
"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.": "Если совпадают, то нажмите кнопку верификации ниже. Если нет, то кто-то перехватил это устройство или ключ и вы, скорее всего, захотите внести его в черный список.",
|
||||
"In future this verification process will be more sophisticated.": "В будущем процесс верификации будет усложнен.",
|
||||
"Verify device": "Верифицировать устройство",
|
||||
"I verify that the keys match": "Я верифицирую - ключи совпадают",
|
||||
"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.": "Обнаружена ошибка при восстановлении вашей предыдущей сессии. Вам необходимо зайти снова, шифрованные сообщения будут нечитаемы.",
|
||||
"Unable to restore session": "Невозможно восстановить сессию",
|
||||
"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.": "Если вы использовали более новую версию Riot, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.",
|
||||
"Continue anyway": "Все равно продолжить",
|
||||
"Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Отображаемое имя - это то, как вы отображаетесь в чате. Какое имя вы хотите?",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Пока что вы вносите неверифицированные устройства в черный список автоматически. Для отправки сообщений на эти устройства вам необходимо их верифицировать.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Рекомендуется сначала верифицировать устройства для подтверждения их владения правильным пользователем, но вы можете отправить сообщение без верификации, если хотите.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неизвестные прежде устройства.",
|
||||
"Unknown Address": "Неизвестный адрес",
|
||||
"Unblacklist": "Удалить из черного списка",
|
||||
"Blacklist": "Черный список",
|
||||
"Unverify": "Убрать верификацию",
|
||||
"Verify...": "Верифицировать...",
|
||||
"ex. @bob:example.com": "например @bob:example.com",
|
||||
"Add User": "Добавить пользователя",
|
||||
"This Home Server would like to make sure you are not a robot": "Этот Home Server хочет удостовериться что вы не робот",
|
||||
"Sign in with CAS": "Войти с помощью CAS",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Вы можете использовать пользовательские настройки сервера для использования другого Home Server'а при помощи указания его URL.",
|
||||
"This allows you to use this app with an existing Matrix account on a different home server.": "Это позволяет использовать это приложение с существующей учетной записью на другом Home Server'е.",
|
||||
"You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете указать пользовательский сервер идентификации, но это обычно ломает возможность общаться с пользователями с помощью адреса email.",
|
||||
"Please check your email to continue registration.": "Проверьте свою почту для продолжения регистрации.",
|
||||
"Token incorrect": "Неправильный токен",
|
||||
"A text message has been sent to": "Текстовое сообщение было отправлено",
|
||||
"Please enter the code it contains:": "Введите содержащийся код:",
|
||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если вы не укажете адрес email, то вы не сможете сбросить свой пароль в будущем. Вы уверены?",
|
||||
"You are registering with %(SelectedTeamName)s": "Вы регистрируетесь на %(SelectedTeamName)s",
|
||||
"Default server": "Сервер по-умолчанию",
|
||||
"Custom server": "Пользовательский сервер",
|
||||
"Home server URL": "URL Home Server'а",
|
||||
"Identity server URL": "URL сервера идентификации",
|
||||
"What does this mean?": "Что это значит?",
|
||||
"Error decrypting audio": "Ошибка расшифровки аудио",
|
||||
"Error decrypting image": "Ошибка расшифровки изображения",
|
||||
"Image '%(Body)s' cannot be displayed.": "Изображение '%(Body)s' не может быть отображено.",
|
||||
"This image cannot be displayed.": "Это изображение не может быть отображено.",
|
||||
"Error decrypting video": "Ошибка расшифровки видео",
|
||||
"Add an Integration": "Добавить интеграцию",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Вы будете перенаправлены на внешний сайт, где вы сможете аутентифицировать свою учетную запись для использования с %(integrationsUrl)s. Вы хотите продолжить?",
|
||||
"Removed or unknown message type": "Удаленный или неизвестный тип сообщения",
|
||||
"Disable URL previews by default for participants in this room": "Отключить предпросмотр URL для участников этой комнаты по-умолчанию",
|
||||
"URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Предпросмотр URL %(globalDisableUrlPreview)s по-умолчанию для участников этой комнаты.",
|
||||
"URL Previews": "Предпросмотр URL",
|
||||
"Enable URL previews for this room (affects only you)": "Включить предпросмотр URL в этой комнате (только для вас)",
|
||||
"Drop file here to upload": "Перетащите файл сюда для загрузки",
|
||||
" (unsupported)": " (не поддерживается)",
|
||||
"Ongoing conference call%(supportedText)s.": "Идет конференц-звонок%(supportedText)s.",
|
||||
"for %(amount)ss": "уже %(amount)sс",
|
||||
"for %(amount)sm": "уже %(amount)sм",
|
||||
"for %(amount)sh": "уже %(amount)sч",
|
||||
"for %(amount)sd": "уже %(amount)sд",
|
||||
"Online": "В сети",
|
||||
"Idle": "Отошел",
|
||||
"Offline": "Не в сети",
|
||||
"Disable URL previews for this room (affects only you)": "Отключить предпросмотр URL в этой комнате (только для вас)",
|
||||
"$senderDisplayName changed the room avatar to <img/>": "$senderDisplayName сменил аватар комнаты на <img/>",
|
||||
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s удалил аватар комнаты.",
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s сменил аватар для %(roomName)s",
|
||||
"Create new room": "Создать новую комнату",
|
||||
"Room directory": "Каталог комнат",
|
||||
"Start chat": "Начать чат",
|
||||
"Welcome page": "Домашняя страница",
|
||||
"Add": "Добавить",
|
||||
"%(count)s new messages.one": "%(count)s новое сообщение",
|
||||
"%(count)s new messages.other": "%(count)s новых сообщений",
|
||||
"Error: Problem communicating with the given homeserver.": "Ошибка: проблема связи с указанным сервером.",
|
||||
"Failed to fetch avatar URL": "Ошибка получения аватара",
|
||||
"The phone number entered looks invalid": "Введенный номер телефона выглядит неправильным",
|
||||
"Uploading %(filename)s and %(count)s others.zero": "Загрузка %(filename)s",
|
||||
"Uploading %(filename)s and %(count)s others.one": "Загрузка %(filename)s и %(count)s другой файл",
|
||||
"Uploading %(filename)s and %(count)s others.other": "Загрузка %(filename)s и %(count)s других файлов",
|
||||
"Username invalid: %(errMessage)s": "Неверное имя пользователя: %(errMessage)s",
|
||||
"Searching known users": "Искать известных пользователей",
|
||||
"You must <a>register</a> to use this functionality": "Вы должны <a>зарегистрироваться</a> для использования этой функции",
|
||||
"<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.": "<a>Отослать снова</a> или <a>отменить отправку</a>. Вы также можете выбрать на отправку или отмену отдельные сообщения.",
|
||||
"New Password": "Новый пароль",
|
||||
"Start chatting": "Начать общение",
|
||||
"Start Chatting": "Начать общение",
|
||||
"Click on the button below to start chatting!": "Нажмите на кнопку ниже для того, чтобы начать общение!",
|
||||
"Create a new chat or reuse an existing one": "Создать новый чат или использовать уже существующий",
|
||||
"You already have existing direct chats with this user:": "У вас уже есть существующие приватные чаты с этим пользователем:",
|
||||
"Username available": "Имя пользователя доступно",
|
||||
"Username not available": "Имя пользователя недоступно",
|
||||
"Something went wrong!": "Что-то пошло не так!",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Это будет ваше имя пользователя на <span></span>, или вы можете выбрать <a>другой сервер</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Если вы уже имеете учетную запись Matrix, то вы можете <a>войти</a>.",
|
||||
"Home": "Старт",
|
||||
"a room": "комната",
|
||||
"Accept": "Принять",
|
||||
"Active call (%(roomName)s)": "Активный вызов (%(roomName)s)",
|
||||
"Admin tools": "Админ утилита",
|
||||
"And %(count)s more...": "И %(count)s больше...",
|
||||
"Alias (optional)": "Псевдоним (опционально)",
|
||||
"<a>Click here</a> to join the discussion!": "<a> Нажми здесь</a> чтоб присоединиться к обсуждению!",
|
||||
"Close": "Закрыть",
|
||||
"Disable Notifications": "Отключить оповещение",
|
||||
"Drop File Here": "Вставить сюда файл",
|
||||
"Enable Notifications": "Включить оповещение",
|
||||
"Encrypted by a verified device": "Шифрование с помощью проверенных устройств",
|
||||
"Encrypted by an unverified device": "Шифрование с помощью не проверенных устройств",
|
||||
"Encryption is enabled in this room": "Шифрование в этой комнате включено",
|
||||
"Encryption is not enabled in this room": "Шифрование в этой комнате не включено",
|
||||
"Failed to upload profile picture!": "Не удалось загрузить фото профиля!",
|
||||
"Incoming call from %(name)s": "Входящий вызов от %(name)s",
|
||||
"Incoming video call from %(name)s": "Входящий видио вызов от %(name)s",
|
||||
"Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Присоединен как <voiceText> голос</voiceText> или <videoText> видио </videoText>.",
|
||||
"Last seen": "В последний раз видели",
|
||||
"Level:": "Уровень:",
|
||||
"No display name": "Нет отображаемое имя",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Иначе , <a> нажать </a> 2 чтоб отослать отчет о ошибке.",
|
||||
"Private Chat": "Частный чат",
|
||||
"Public Chat": "Общественный чат",
|
||||
"Reason: %(reasonText)s": "Причина: %(reasonText)s",
|
||||
"Rejoin": "Пере-соединиться",
|
||||
"Set": "Вводить",
|
||||
"Start authentication": "Начать идентификацию",
|
||||
"This room": "Эта комната",
|
||||
"(~%(count)s results).other": "(~%(count) найдено)",
|
||||
"Device Name": "Имя устройства",
|
||||
"Custom": "Пользователь",
|
||||
"Decline": "Отклонить",
|
||||
"Room contains unknown devices": "Комната содержит неизвестное устройство",
|
||||
"%(roomName)s does not exist.": "%(roomName)s не существует.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s в данный момент не доступна.",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Отослать от %(userName)s в %(dateTime)s",
|
||||
"Send anyway": "Отправить в любом случае",
|
||||
"Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста",
|
||||
"This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес электронной почты, который не связан с этой учетной записью:",
|
||||
"To link to a room it must have <a>an address</a>.": "Для ссылки на комнату. Она должна иметь <a> адрес</a>.",
|
||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить, что адрес на который было отправлено это приглашение соответствует вашей учетной записи.",
|
||||
"Undecryptable": "Невозможно расшифровать",
|
||||
"Unencrypted message": "Незашифрованое послание",
|
||||
"unknown caller": "Звонящий неизвестен",
|
||||
"Unnamed Room": "Комната без имени",
|
||||
"Unverified": "Непроверенно",
|
||||
"Upload new:": "Загрузить новый:",
|
||||
"%(user)s is a": "%(user)s является",
|
||||
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)",
|
||||
"Verified": "Подтверждён",
|
||||
"Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?": "Хотели бы вы <acceptText>подтвердить</acceptText> это приглашение или <declineText>отклонить</declineText>?",
|
||||
"(~%(count)s results).one": "(~%(count)s Результат)",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш сертификат SSL <a>homeserver's SSL certificate</a> действителен, и расширение браузера не блокирует запросы.",
|
||||
"You have been banned from %(roomName)s by %(userName)s.": "%(userName) забанил Вас в % (roomName).",
|
||||
"You have been kicked from %(roomName)s by %(userName)s.": "%(userName) выгнал Вас из %(roomName).",
|
||||
"You may wish to login with a different account, or add this email to this account.": "Вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.",
|
||||
"Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами."
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue