Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/electron_settings

# Conflicts:
#	src/components/structures/UserSettings.js
#	src/i18n/strings/en_EN.json

First time using JetBrains Merge Tool, MAY HAVE GONE HORRIBLY WRONG

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2017-05-30 23:54:57 +01:00
commit dcd99ac3de
57 changed files with 1861 additions and 321 deletions

145
src/Analytics.js Normal file
View File

@ -0,0 +1,145 @@
/*
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
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 { getCurrentLanguage } from './languageHandler';
import MatrixClientPeg from './MatrixClientPeg';
import PlatformPeg from './PlatformPeg';
import SdkConfig from './SdkConfig';
function redact(str) {
return str.replace(/#\/(room|user)\/(.+)/, "#/$1/<redacted>");
}
const customVariables = {
'App Platform': 1,
'App Version': 2,
'User Type': 3,
'Chosen Language': 4,
};
class Analytics {
constructor() {
this._paq = null;
this.disabled = true;
this.firstPage = true;
}
/**
* Enable Analytics if initialized but disabled
* otherwise try and initalize, no-op if piwik config missing
*/
enable() {
if (this._paq || this._init()) {
this.disabled = false;
}
}
/**
* Disable Analytics calls, will not fully unload Piwik until a refresh,
* but this is second best, Piwik should not pull anything implicitly.
*/
disable() {
this.disabled = true;
}
_init() {
const config = SdkConfig.get();
if (!config || !config.piwik || !config.piwik.url || !config.piwik.siteId) return;
const url = config.piwik.url;
const siteId = config.piwik.siteId;
const self = this;
window._paq = this._paq = window._paq || [];
this._paq.push(['setTrackerUrl', url+'piwik.php']);
this._paq.push(['setSiteId', siteId]);
this._paq.push(['trackAllContentImpressions']);
this._paq.push(['discardHashTag', false]);
this._paq.push(['enableHeartBeatTimer']);
this._paq.push(['enableLinkTracking', true]);
const platform = PlatformPeg.get();
this._setVisitVariable('App Platform', platform.getHumanReadableName());
platform.getAppVersion().then((version) => {
this._setVisitVariable('App Version', version);
}).catch(() => {
this._setVisitVariable('App Version', 'unknown');
});
this._setVisitVariable('Chosen Language', getCurrentLanguage());
(function() {
const g = document.createElement('script');
const s = document.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=url+'piwik.js';
g.onload = function() {
console.log('Initialised anonymous analytics');
self._paq = window._paq;
};
s.parentNode.insertBefore(g, s);
})();
return true;
}
trackPageChange() {
if (this.disabled) return;
if (this.firstPage) {
// De-duplicate first page
// router seems to hit the fn twice
this.firstPage = false;
return;
}
this._paq.push(['setCustomUrl', redact(window.location.href)]);
this._paq.push(['trackPageView']);
}
trackEvent(category, action, name) {
if (this.disabled) return;
this._paq.push(['trackEvent', category, action, name]);
}
logout() {
if (this.disabled) return;
this._paq.push(['deleteCookies']);
}
login() { // not used currently
const cli = MatrixClientPeg.get();
if (this.disabled || !cli) return;
this._paq.push(['setUserId', `@${cli.getUserIdLocalpart()}:${cli.getDomain()}`]);
}
_setVisitVariable(key, value) {
this._paq.push(['setCustomVariable', customVariables[key], key, value, 'visit']);
}
setGuest(guest) {
if (this.disabled) return;
this._setVisitVariable('User Type', guest ? 'Guest' : 'Logged In');
}
}
if (!global.mxAnalytics) {
global.mxAnalytics = new Analytics();
}
module.exports = global.mxAnalytics;

View File

@ -29,6 +29,11 @@ export default class BasePlatform {
this.errorDidOccur = false;
}
// Used primarily for Analytics
getHumanReadableName(): string {
return 'Base Platform';
}
setNotificationCount(count: number) {
this.notificationCount = count;
}

View File

@ -83,7 +83,7 @@ module.exports = {
return this.formatFullDate(date);
},
formatFullDate: function(date) {
formatFullDate: function(date, showTwelveHour=false) {
const days = getDaysArray();
const months = getMonthsArray();
return _t('%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s', {
@ -91,7 +91,7 @@ module.exports = {
monthName: months[date.getMonth()],
day: date.getDate(),
fullYear: date.getFullYear(),
time: this.formatTime(date),
time: showTwelveHour ? twelveHourTime(date) : this.formatTime(date),
});
},

View File

@ -19,6 +19,7 @@ import q from 'q';
import Matrix from 'matrix-js-sdk';
import MatrixClientPeg from './MatrixClientPeg';
import Analytics from './Analytics';
import Notifier from './Notifier';
import UserActivity from './UserActivity';
import Presence from './Presence';
@ -276,6 +277,8 @@ export function initRtsClient(url) {
export function setLoggedIn(credentials) {
credentials.guest = Boolean(credentials.guest);
Analytics.setGuest(credentials.guest);
console.log(
"setLoggedIn: mxid:", credentials.userId,
"deviceId:", credentials.deviceId,
@ -403,6 +406,7 @@ export function onLoggedOut() {
}
function _clearLocalStorage() {
Analytics.logout();
if (!window.localStorage) {
return;
}

View File

@ -19,6 +19,7 @@ limitations under the License.
var React = require('react');
var ReactDOM = require('react-dom');
import Analytics from './Analytics';
import sdk from './index';
const DIALOG_CONTAINER_ID = "mx_Dialog_Container";
@ -104,6 +105,9 @@ class ModalManager {
}
createDialog(Element, props, className) {
if (props && props.title) {
Analytics.trackEvent('Modal', props.title, 'createDialog');
}
return this.createDialogAsync((cb) => {cb(Element);}, props, className);
}

View File

@ -18,6 +18,7 @@ limitations under the License.
import MatrixClientPeg from './MatrixClientPeg';
import PlatformPeg from './PlatformPeg';
import TextForEvent from './TextForEvent';
import Analytics from './Analytics';
import Avatar from './Avatar';
import dis from './dispatcher';
import sdk from './index';
@ -121,6 +122,9 @@ const Notifier = {
setEnabled: function(enable, callback) {
const plaf = PlatformPeg.get();
if (!plaf) return;
Analytics.trackEvent('Notifier', 'Set Enabled', enable);
// make sure that we persist the current setting audio_enabled setting
// before changing anything
if (global.localStorage) {
@ -199,6 +203,8 @@ const Notifier = {
setToolbarHidden: function(hidden, persistent = true) {
this.toolbarHidden = hidden;
Analytics.trackEvent('Notifier', 'Set Toolbar Hidden', hidden);
// XXX: why are we dispatching this here?
// this is nothing to do with notifier_enabled
dis.dispatch({

View File

@ -118,6 +118,9 @@ function textForTopicEvent(ev) {
function textForRoomNameEvent(ev) {
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
if (!ev.getContent().name || ev.getContent().name.trim().length === 0) {
return _t('%(senderDisplayName)s removed the room name.', {senderDisplayName: senderDisplayName});
}
return _t('%(senderDisplayName)s changed the room name to %(roomName)s.', {senderDisplayName: senderDisplayName, roomName: ev.getContent().name});
}

View File

@ -16,6 +16,7 @@ limitations under the License.
import FileSaver from 'file-saver';
import React from 'react';
import { _t } from '../../../languageHandler';
import * as Matrix from 'matrix-js-sdk';
import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption';
@ -52,11 +53,11 @@ export default React.createClass({
const passphrase = this.refs.passphrase1.value;
if (passphrase !== this.refs.passphrase2.value) {
this.setState({errStr: 'Passphrases must match'});
this.setState({errStr: _t('Passphrases must match')});
return false;
}
if (!passphrase) {
this.setState({errStr: 'Passphrase must not be empty'});
this.setState({errStr: _t('Passphrase must not be empty')});
return false;
}
@ -109,24 +110,28 @@ export default React.createClass({
return (
<BaseDialog className='mx_exportE2eKeysDialog'
onFinished={this.props.onFinished}
title="Export room keys"
title={_t("Export room keys")}
>
<form onSubmit={this._onPassphraseFormSubmit}>
<div className="mx_Dialog_content">
<p>
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.
{ _t(
'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.'
) }
</p>
<p>
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.
{ _t(
'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.'
) }
</p>
<div className='error'>
{this.state.errStr}
@ -135,7 +140,7 @@ export default React.createClass({
<div className='mx_E2eKeysDialog_inputRow'>
<div className='mx_E2eKeysDialog_inputLabel'>
<label htmlFor='passphrase1'>
Enter passphrase
{_t("Enter passphrase")}
</label>
</div>
<div className='mx_E2eKeysDialog_inputCell'>
@ -148,7 +153,7 @@ export default React.createClass({
<div className='mx_E2eKeysDialog_inputRow'>
<div className='mx_E2eKeysDialog_inputLabel'>
<label htmlFor='passphrase2'>
Confirm passphrase
{_t("Confirm passphrase")}
</label>
</div>
<div className='mx_E2eKeysDialog_inputCell'>

View File

@ -19,6 +19,7 @@ import React from 'react';
import * as Matrix from 'matrix-js-sdk';
import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
function readFileAsArrayBuffer(file) {
return new Promise((resolve, reject) => {
@ -112,20 +113,23 @@ export default React.createClass({
return (
<BaseDialog className='mx_importE2eKeysDialog'
onFinished={this.props.onFinished}
title="Import room keys"
title={_t("Import room keys")}
>
<form onSubmit={this._onFormSubmit}>
<div className="mx_Dialog_content">
<p>
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.
{ _t(
'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.'
) }
</p>
<p>
The export file will be protected with a passphrase.
You should enter the passphrase here, to decrypt the
file.
{ _t(
'The export file will be protected with a passphrase. ' +
'You should enter the passphrase here, to decrypt the file.'
) }
</p>
<div className='error'>
{this.state.errStr}
@ -134,7 +138,7 @@ export default React.createClass({
<div className='mx_E2eKeysDialog_inputRow'>
<div className='mx_E2eKeysDialog_inputLabel'>
<label htmlFor='importFile'>
File to import
{_t("File to import")}
</label>
</div>
<div className='mx_E2eKeysDialog_inputCell'>
@ -147,7 +151,7 @@ export default React.createClass({
<div className='mx_E2eKeysDialog_inputRow'>
<div className='mx_E2eKeysDialog_inputLabel'>
<label htmlFor='passphrase'>
Enter passphrase
{_t("Enter passphrase")}
</label>
</div>
<div className='mx_E2eKeysDialog_inputCell'>

View File

@ -45,10 +45,10 @@ const COMMANDS = [
command: '/ddg',
args: '<query>',
description: 'Searches DuckDuckGo for results',
}
},
];
let COMMAND_RE = /(^\/\w*)/g;
const COMMAND_RE = /(^\/\w*)/g;
let instance = null;
@ -62,15 +62,15 @@ export default class CommandProvider extends AutocompleteProvider {
async getCompletions(query: string, selection: {start: number, end: number}) {
let completions = [];
let {command, range} = this.getCurrentCommand(query, selection);
const {command, range} = this.getCurrentCommand(query, selection);
if (command) {
completions = this.fuse.search(command[0]).map(result => {
completions = this.fuse.search(command[0]).map((result) => {
return {
completion: result.command + ' ',
component: (<TextualCompletion
title={result.command}
subtitle={result.args}
description={ t_(result.description) }
description={ _t(result.description) }
/>),
range,
};
@ -84,8 +84,7 @@ export default class CommandProvider extends AutocompleteProvider {
}
static getInstance(): CommandProvider {
if (instance == null)
{instance = new CommandProvider();}
if (instance === null) instance = new CommandProvider();
return instance;
}

View File

@ -95,7 +95,7 @@ var FilePanel = React.createClass({
</div>;
} else if (this.noRoom) {
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
<div className="mx_RoomView_empty">You must join the room to see its files</div>
<div className="mx_RoomView_empty">{_t("You must join the room to see its files")}</div>
</div>;
}

View File

@ -20,6 +20,8 @@ import q from 'q';
import React from 'react';
import Matrix from "matrix-js-sdk";
import Analytics from "../../Analytics";
import UserSettingsStore from '../../UserSettingsStore';
import MatrixClientPeg from "../../MatrixClientPeg";
import PlatformPeg from "../../PlatformPeg";
import SdkConfig from "../../SdkConfig";
@ -189,6 +191,8 @@ module.exports = React.createClass({
componentWillMount: function() {
SdkConfig.put(this.props.config);
if (!UserSettingsStore.getLocalSetting('analyticsOptOut', false)) Analytics.enable();
// Used by _viewRoom before getting state from sync
this.firstSyncComplete = false;
this.firstSyncPromise = q.defer();
@ -699,9 +703,9 @@ module.exports = React.createClass({
modal.close();
console.error("Failed to leave room " + roomId + " " + err);
Modal.createDialog(ErrorDialog, {
title: "Failed to leave room",
title: _t("Failed to leave room"),
description: (err && err.message ? err.message :
"Server may be unavailable, overloaded, or you hit a bug."),
_t("Server may be unavailable, overloaded, or you hit a bug.")),
});
});
}
@ -1002,6 +1006,7 @@ module.exports = React.createClass({
if (this.props.onNewScreen) {
this.props.onNewScreen(screen);
}
Analytics.trackPageChange();
},
onAliasClick: function(event, alias) {

View File

@ -1502,8 +1502,7 @@ module.exports = React.createClass({
<Loader />
</div>
);
}
else {
} else {
var inviterName = undefined;
if (this.props.oobData) {
inviterName = this.props.oobData.inviterName;
@ -1622,13 +1621,15 @@ module.exports = React.createClass({
}
let aux = null;
if (this.state.forwardingEvent !== null) {
aux = <ForwardMessage onCancelClick={this.onCancelClick} currentRoomId={this.state.room.roomId} mxEvent={this.state.forwardingEvent} />;
} else if (this.state.editingRoomSettings) {
let hideCancel = false;
if (this.state.editingRoomSettings) {
aux = <RoomSettings ref="room_settings" onSaveClick={this.onSettingsSaveClick} onCancelClick={this.onCancelClick} room={this.state.room} />;
} else if (this.state.uploadingRoomSettings) {
aux = <Loader/>;
} else if (this.state.forwardingEvent !== null) {
aux = <ForwardMessage onCancelClick={this.onCancelClick} currentRoomId={this.state.room.roomId} mxEvent={this.state.forwardingEvent} />;
} else if (this.state.searching) {
hideCancel = true; // has own cancel
aux = <SearchBar ref="search_bar" searchInProgress={this.state.searchInProgress } onCancelClick={this.onCancelSearchClick} onSearch={this.onSearch}/>;
} else if (!myMember || myMember.membership !== "join") {
// We do have a room object for this room, but we're not currently in it.
@ -1641,6 +1642,7 @@ module.exports = React.createClass({
if (this.props.thirdPartyInvite) {
invitedEmail = this.props.thirdPartyInvite.invitedEmail;
}
hideCancel = true;
aux = (
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onForgetClick={ this.onForgetClick }
@ -1787,13 +1789,10 @@ module.exports = React.createClass({
onSearchClick={this.onSearchClick}
onSettingsClick={this.onSettingsClick}
onSaveClick={this.onSettingsSaveClick}
onCancelClick={aux ? this.onCancelClick : null}
onForgetClick={
(myMember && myMember.membership === "leave") ? this.onForgetClick : null
}
onLeaveClick={
(myMember && myMember.membership === "join") ? this.onLeaveClick : null
} />
onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null}
onForgetClick={(myMember && myMember.membership === "leave") ? this.onForgetClick : null}
onLeaveClick={(myMember && myMember.membership === "join") ? this.onLeaveClick : null}
/>
{ auxPanel }
{ topUnreadMessagesBar }
{ messagePanel }

View File

@ -28,6 +28,7 @@ const GeminiScrollbar = require('react-gemini-scrollbar');
const Email = require('../../email');
const AddThreepid = require('../../AddThreepid');
const SdkConfig = require('../../SdkConfig');
import Analytics from '../../Analytics';
import AccessibleButton from '../views/elements/AccessibleButton';
import { _t } from '../../languageHandler';
import * as languageHandler from '../../languageHandler';
@ -90,12 +91,25 @@ const SETTINGS_LABELS = [
*/
];
const ANALYTICS_SETTINGS_LABELS = [
{
id: 'analyticsOptOut',
label: 'Opt out of analytics',
fn: function(checked) {
Analytics[checked ? 'disable' : 'enable']();
},
},
];
// Warning: Each "label" string below must be added to i18n/strings/en_EN.json,
// since they will be translated when rendered.
const CRYPTO_SETTINGS_LABELS = [
{
id: 'blacklistUnverifiedDevices',
label: 'Never send encrypted messages to unverified devices from this device',
fn: function(checked) {
MatrixClientPeg.get().setGlobalBlacklistUnverifiedDevices(checked);
},
},
// XXX: this is here for documentation; the actual setting is managed via RoomSettings
// {
@ -207,7 +221,6 @@ module.exports = React.createClass({
const {ipcRenderer} = require('electron');
ipcRenderer.on('settings', this._electronSettings);
ipcRenderer.send('settings_get');
}
@ -616,7 +629,12 @@ module.exports = React.createClass({
<input id={ setting.id }
type="checkbox"
defaultChecked={ this._syncedSettings[setting.id] }
onChange={ (e) => UserSettingsStore.setSyncedSetting(setting.id, e.target.checked) }
onChange={
(e) => {
UserSettingsStore.setSyncedSetting(setting.id, e.target.checked);
if (setting.fn) setting.fn(e.target.checked);
}
}
/>
<label htmlFor={ setting.id }>
{ _t(setting.label) }
@ -692,7 +710,6 @@ module.exports = React.createClass({
},
_renderLocalSetting: function(setting) {
const client = MatrixClientPeg.get();
return <div className="mx_UserSettings_toggle" key={ setting.id }>
<input id={ setting.id }
type="checkbox"
@ -700,9 +717,7 @@ module.exports = React.createClass({
onChange={
(e) => {
UserSettingsStore.setLocalSetting(setting.id, e.target.checked);
if (setting.id === 'blacklistUnverifiedDevices') { // XXX: this is a bit ugly
client.setGlobalBlacklistUnverifiedDevices(e.target.checked);
}
if (setting.fn) setting.fn(e.target.checked);
}
}
/>
@ -739,6 +754,16 @@ module.exports = React.createClass({
);
},
_renderAnalyticsControl: function() {
return <div>
<h3>{ _t('Analytics') }</h3>
<div className="mx_UserSettings_section">
{_t('Riot collects anonymous analytics to allow us to improve the application.')}
{ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting )}
</div>
</div>;
},
_renderLabs: function() {
// default to enabled if undefined
if (this.props.enableLabs === false) return null;
@ -821,7 +846,7 @@ module.exports = React.createClass({
reject = (
<AccessibleButton className="mx_UserSettings_button danger"
onClick={this._onRejectAllInvitesClicked.bind(this, invitedRooms)}>
Reject all {invitedRooms.length} invites
{_t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length})}
</AccessibleButton>
);
}
@ -1061,6 +1086,8 @@ module.exports = React.createClass({
{PlatformPeg.get().isElectron() && this._renderElectronSettings()}
{this._renderAnalyticsControl()}
<h3>{ _t("Advanced") }</h3>
<div className="mx_UserSettings_section">

View File

@ -16,8 +16,8 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'CreateRoomButton',
propTypes: {
@ -36,7 +36,7 @@ module.exports = React.createClass({
render: function() {
return (
<button className="mx_CreateRoomButton" onClick={this.onClick}>Create Room</button>
<button className="mx_CreateRoomButton" onClick={this.onClick}>{_t("Create Room")}</button>
);
}
});

View File

@ -86,7 +86,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
<div className="mx_RoomTile_avatar">
<img src="img/create-big.svg" width="26" height="26" />
</div>
<div className={labelClasses}><i>Start new chat</i></div>
<div className={labelClasses}><i>{_("Start new chat")}</i></div>
</AccessibleButton>;
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');

View File

@ -27,14 +27,13 @@ import dis from '../../../dispatcher';
import Modal from '../../../Modal';
import AccessibleButton from '../elements/AccessibleButton';
import q from 'q';
import Fuse from 'fuse.js';
const TRUNCATE_QUERY_LIST = 40;
module.exports = React.createClass({
displayName: "ChatInviteDialog",
propTypes: {
title: React.PropTypes.string,
title: React.PropTypes.string.isRequired,
description: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.string,
@ -74,19 +73,6 @@ module.exports = React.createClass({
// Set the cursor at the end of the text input
this.refs.textinput.value = this.props.value;
}
// Create a Fuse instance for fuzzy searching this._userList
this._fuse = new Fuse(
// Use an empty list at first that will later be populated
// (see this._updateUserList)
[],
{
shouldSort: true,
location: 0, // The index of the query in the test string
distance: 5, // The distance away from location the query can be
// 0.0 = exact match, 1.0 = match anything
threshold: 0.3,
}
);
this._updateUserList();
},
@ -175,7 +161,7 @@ module.exports = React.createClass({
},
onQueryChanged: function(ev) {
const query = ev.target.value;
const query = ev.target.value.toLowerCase();
let queryList = [];
if (query.length < 2) {
@ -188,24 +174,27 @@ module.exports = React.createClass({
this.queryChangedDebouncer = setTimeout(() => {
// Only do search if there is something to search
if (query.length > 0 && query != '@') {
// Weighted keys prefer to match userIds when first char is @
this._fuse.options.keys = [{
name: 'displayName',
weight: query[0] === '@' ? 0.1 : 0.9,
},{
name: 'userId',
weight: query[0] === '@' ? 0.9 : 0.1,
}];
queryList = this._fuse.search(query).map((user) => {
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
return {
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
@ -283,8 +272,8 @@ module.exports = React.createClass({
if (MatrixClientPeg.get().isGuest()) {
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
Modal.createDialog(NeedToRegisterDialog, {
title: "Please Register",
description: "Guest users can't invite users. Please register."
title: _t("Please Register"),
description: _t("Guest users can't invite users. Please register."),
});
return;
}
@ -305,8 +294,8 @@ module.exports = React.createClass({
console.error(err.stack);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to invite",
description: ((err && err.message) ? err.message : "Operation failed"),
title: _t("Failed to invite"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
return null;
})
@ -318,8 +307,8 @@ module.exports = React.createClass({
console.error(err.stack);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to invite user",
description: ((err && err.message) ? err.message : "Operation failed"),
title: _t("Failed to invite user"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
return null;
})
@ -339,8 +328,8 @@ module.exports = React.createClass({
console.error(err.stack);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to invite",
description: ((err && err.message) ? err.message : "Operation failed"),
title: _t("Failed to invite"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
return null;
})
@ -351,7 +340,7 @@ module.exports = React.createClass({
this.props.onFinished(true, addrTexts);
},
_updateUserList: new rate_limited_func(function() {
_updateUserList: function() {
// Get all the users
this._userList = MatrixClientPeg.get().getUsers();
// Remove current user
@ -359,9 +348,7 @@ module.exports = React.createClass({
return u.userId === MatrixClientPeg.get().credentials.userId;
});
this._userList.splice(meIx, 1);
this._fuse.set(this._userList);
}, 500),
},
_isOnInviteList: function(uid) {
for (let i = 0; i < this.state.inviteList.length; i++) {
@ -398,7 +385,7 @@ module.exports = React.createClass({
if (errorList.length > 0) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to invite the following users to the " + room.name + " room:",
title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}),
description: errorList.join(", "),
});
}

View File

@ -17,6 +17,7 @@ limitations under the License.
import React from 'react';
import sdk from '../../../index';
import classnames from 'classnames';
import { _t } from '../../../languageHandler';
/*
* A dialog for confirming a redaction.
@ -42,7 +43,7 @@ export default React.createClass({
render: function() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const title = "Confirm Removal";
const title = _t("Confirm Removal");
const confirmButtonClass = classnames({
'mx_Dialog_primary': true,
@ -55,16 +56,16 @@ export default React.createClass({
title={title}
>
<div className="mx_Dialog_content">
Are you sure you wish to remove (delete) this event?
Note that if you delete a room name or topic change, it could undo the change.
{_t("Are you sure you wish to remove (delete) this event? " +
"Note that if you delete a room name or topic change, it could undo the change.")}
</div>
<div className="mx_Dialog_buttons">
<button className={confirmButtonClass} onClick={this.onOk}>
Remove
{_t("Remove")}
</button>
<button onClick={this.onCancel}>
Cancel
{_t("Cancel")}
</button>
</div>
</BaseDialog>

View File

@ -20,6 +20,7 @@ import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import * as Lifecycle from '../../../Lifecycle';
import Velocity from 'velocity-vector';
import { _t } from '../../../languageHandler';
export default class DeactivateAccountDialog extends React.Component {
constructor(props, context) {
@ -56,10 +57,10 @@ export default class DeactivateAccountDialog extends React.Component {
Lifecycle.onLoggedOut();
this.props.onFinished(false);
}, (err) => {
let errStr = 'Unknown error';
let errStr = _t('Unknown error');
// https://matrix.org/jira/browse/SYN-744
if (err.httpStatus == 401 || err.httpStatus == 403) {
errStr = 'Incorrect password';
errStr = _t('Incorrect password');
Velocity(this._passwordField, "callout.shake", 300);
}
this.setState({
@ -91,23 +92,23 @@ export default class DeactivateAccountDialog extends React.Component {
let cancelButton = null;
if (!this.state.busy) {
cancelButton = <button onClick={this._onCancel} autoFocus={true}>
Cancel
{_t("Cancel")}
</button>;
}
return (
<div className="mx_DeactivateAccountDialog">
<div className="mx_Dialog_title danger">
Deactivate Account
{_t("Deactivate Account")}
</div>
<div className="mx_Dialog_content">
<p>This will make your account permanently unusable. You will not be able to re-register the same user ID.</p>
<p>{_t("This will make your account permanently unusable. You will not be able to re-register the same user ID.")}</p>
<p>This action is irreversible.</p>
<p>{_t("This action is irreversible.")}</p>
<p>To continue, please enter your password.</p>
<p>{_t("To continue, please enter your password.")}</p>
<p>Password:</p>
<p>{_t("Password")}:</p>
<input
type="password"
onChange={this._onPasswordFieldChange}

View File

@ -19,6 +19,7 @@ import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from '../../../index';
import * as FormattingUtils from '../../../utils/FormattingUtils';
import { _t } from '../../../languageHandler';
export default function DeviceVerifyDialog(props) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
@ -27,25 +28,25 @@ export default function DeviceVerifyDialog(props) {
const body = (
<div>
<p>
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:
{_t("To verify that this device can be trusted, please contact its " +
"owner using some other means (e.g. in person or a phone call) " +
"and ask them whether the key they see in their User Settings " +
"for this device matches the key below:")}
</p>
<div className="mx_UserSettings_cryptoSection">
<ul>
<li><label>Device name:</label> <span>{ props.device.getDisplayName() }</span></li>
<li><label>Device ID:</label> <span><code>{ props.device.deviceId}</code></span></li>
<li><label>Device key:</label> <span><code><b>{ key }</b></code></span></li>
<li><label>{_t("Device name")}:</label> <span>{ props.device.getDisplayName() }</span></li>
<li><label>{_t("Device ID")}:</label> <span><code>{ props.device.deviceId}</code></span></li>
<li><label>{_t("Device key")}:</label> <span><code><b>{ key }</b></code></span></li>
</ul>
</div>
<p>
If it matches, press the verify button below.
If it doesnt, then someone else is intercepting this device
and you probably want to press the blacklist button instead.
{_t("If it matches, press the verify button below. " +
"If it doesn't, then someone else is intercepting this device " +
"and you probably want to press the blacklist button instead.")}
</p>
<p>
In future this verification process will be more sophisticated.
{_t("In future this verification process will be more sophisticated.")}
</p>
</div>
);
@ -61,9 +62,9 @@ export default function DeviceVerifyDialog(props) {
return (
<QuestionDialog
title="Verify device"
title={_t("Verify device")}
description={body}
button="I verify that the keys match"
button={_t("I verify that the keys match")}
onFinished={onFinished}
/>
);

View File

@ -18,6 +18,7 @@ import React from 'react';
import sdk from '../../../index';
import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal';
import { _t } from '../../../languageHandler';
export default React.createClass({
@ -51,21 +52,21 @@ export default React.createClass({
return (
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
title='Unable to restore session'>
title={_t('Unable to restore session')}>
<div className="mx_Dialog_content">
<p>We encountered an error trying to restore your previous session. If
you continue, you will need to log in again, and encrypted chat
history will be unreadable.</p>
<p>{_t("We encountered an error trying to restore your previous session. If " +
"you continue, you will need to log in again, and encrypted chat " +
"history will be unreadable.")}</p>
<p>If you have previously used a more recent version of Riot, your session
may be incompatible with this version. Close this window and return
to the more recent version.</p>
<p>{_t("If you have previously used a more recent version of Riot, your session " +
"may be incompatible with this version. Close this window and return " +
"to the more recent version.")}</p>
{bugreport}
</div>
<div className="mx_Dialog_buttons">
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
Continue anyway
{_t("Continue anyway")}
</button>
</div>
</BaseDialog>

View File

@ -64,11 +64,11 @@ export default React.createClass({
return (
<BaseDialog className="mx_SetDisplayNameDialog"
onFinished={this.props.onFinished}
title="Set a Display Name"
title={_t("Set a Display Name")}
>
<div className="mx_Dialog_content">
Your display name is how you'll appear to others when you speak in rooms.<br/>
What would you like it to be?
{_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">

View File

@ -20,6 +20,7 @@ import dis from '../../../dispatcher';
import MatrixClientPeg from '../../../MatrixClientPeg';
import GeminiScrollbar from 'react-gemini-scrollbar';
import Resend from '../../../Resend';
import { _t } from '../../../languageHandler';
function DeviceListEntry(props) {
const {userId, device} = props;
@ -120,17 +121,17 @@ export default React.createClass({
if (blacklistUnverified) {
warning = (
<h4>
You are currently blacklisting unverified devices; to send
messages to these devices you must verify them.
{_t("You are currently blacklisting unverified devices; to send " +
"messages to these devices you must verify them.")}
</h4>
);
} else {
warning = (
<div>
<p>
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.
{_t("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.")}
</p>
</div>
);
@ -149,10 +150,10 @@ export default React.createClass({
>
<GeminiScrollbar autoshow={false} className="mx_Dialog_content">
<h4>
"{this.props.room.name}" contains devices that you haven't seen before.
{_t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name})}
</h4>
{ warning }
Unknown devices:
{_t("Unknown devices")}:
<UnknownDeviceList devices={this.props.devices} />
</GeminiScrollbar>

View File

@ -16,12 +16,13 @@ limitations under the License.
'use strict';
var React = require('react');
var classNames = require('classnames');
var sdk = require("../../../index");
var Invite = require("../../../Invite");
var MatrixClientPeg = require("../../../MatrixClientPeg");
var Avatar = require('../../../Avatar');
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
// an address that can be invited to a room (which
@ -142,7 +143,7 @@ export default React.createClass({
});
info = (
<div className={unknownClasses}>Unknown Address</div>
<div className={unknownClasses}>{_t("Unknown Address")}</div>
);
}

View File

@ -18,6 +18,7 @@ import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from '../../../index';
import Modal from '../../../Modal';
import { _t } from '../../../languageHandler';
export default React.createClass({
displayName: 'DeviceVerifyButtons',
@ -82,14 +83,14 @@ export default React.createClass({
blacklistButton = (
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_unblacklist"
onClick={this.onUnblacklistClick}>
Unblacklist
{_t("Unblacklist")}
</button>
);
} else {
blacklistButton = (
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_blacklist"
onClick={this.onBlacklistClick}>
Blacklist
{_t("Blacklist")}
</button>
);
}
@ -98,14 +99,14 @@ export default React.createClass({
verifyButton = (
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_unverify"
onClick={this.onUnverifyClick}>
Unverify
{_t("Unverify")}
</button>
);
} else {
verifyButton = (
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_verify"
onClick={this.onVerifyClick}>
Verify...
{_t("Verify...")}
</button>
);
}

View File

@ -17,6 +17,7 @@ limitations under the License.
import React from 'react';
import classnames from 'classnames';
import AccessibleButton from './AccessibleButton';
import { _t } from '../../../languageHandler';
class MenuOption extends React.Component {
constructor(props) {
@ -255,7 +256,7 @@ export default class Dropdown extends React.Component {
});
if (options.length === 0) {
return [<div key="0" className="mx_Dropdown_option">
No results
{_t("No results")}
</div>];
}
return options;

View File

@ -16,7 +16,8 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'UserSelector',
@ -59,9 +60,9 @@ module.exports = React.createClass({
return <li key={user_id}>{user_id} - <span onClick={function() {self.removeUser(user_id);}}>X</span></li>;
})}
</ul>
<input type="text" ref="user_id_input" defaultValue="" className="mx_UserSelector_userIdInput" placeholder="ex. @bob:example.com"/>
<input type="text" ref="user_id_input" defaultValue="" className="mx_UserSelector_userIdInput" placeholder={_t("ex. @bob:example.com")}/>
<button onClick={this.onAddUserId} className="mx_UserSelector_AddUserId">
Add User
{_t("Add User")}
</button>
</div>
);

View File

@ -16,7 +16,9 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import { _t } from '../../../languageHandler';
var DIV_ID = 'mx_recaptcha';
/**
@ -117,7 +119,7 @@ module.exports = React.createClass({
return (
<div ref="recaptchaContainer">
This Home Server would like to make sure you are not a robot
{_t("This Home Server would like to make sure you are not a robot")}
<br/>
<div id={DIV_ID}></div>
{error}

View File

@ -16,7 +16,8 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'CasLogin',
@ -28,7 +29,7 @@ module.exports = React.createClass({
render: function() {
return (
<div>
<button onClick={this.props.onSubmit}>Sign in with CAS</button>
<button onClick={this.props.onSubmit}>{_t("Sign in with CAS")}</button>
</div>
);
}

View File

@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
var React = require("react");
import React from 'react';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'CustomServerDialog',
@ -23,24 +24,24 @@ module.exports = React.createClass({
return (
<div className="mx_ErrorDialog">
<div className="mx_Dialog_title">
Custom Server Options
{_t("Custom Server Options")}
</div>
<div className="mx_Dialog_content">
<span>
You can use the custom server options to sign into other Matrix
servers by specifying a different Home server URL.
{_t("You can use the custom server options to sign into other Matrix " +
"servers by specifying a different Home server URL.")}
<br/>
This allows you to use this app with an existing Matrix account on
a different home server.
{_t("This allows you to use this app with an existing Matrix account on " +
"a different home server.")}
<br/>
<br/>
You can also set a custom identity server but this will typically prevent
interaction with users based on email address.
{_t("You can also set a custom identity server but this will typically prevent " +
"interaction with users based on email address.")}
</span>
</div>
<div className="mx_Dialog_buttons">
<button onClick={this.props.onFinished} autoFocus={true}>
Dismiss
{_t("Dismiss")}
</button>
</div>
</div>

View File

@ -20,6 +20,7 @@ import url from 'url';
import classnames from 'classnames';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
/* This file contains a collection of components which are used by the
* InteractiveAuth to prompt the user to enter the information needed
@ -255,8 +256,8 @@ export const EmailIdentityAuthEntry = React.createClass({
} else {
return (
<div>
<p>An email has been sent to <i>{this.props.inputs.emailAddress}</i></p>
<p>Please check your email to continue registration.</p>
<p>{_t("An email has been sent to")} <i>{this.props.inputs.emailAddress}</i></p>
<p>{_t("Please check your email to continue registration.")}</p>
</div>
);
}
@ -348,7 +349,7 @@ export const MsisdnAuthEntry = React.createClass({
});
} else {
this.setState({
errorText: "Token incorrect",
errorText: _t("Token incorrect"),
});
}
}).catch((e) => {
@ -369,8 +370,8 @@ export const MsisdnAuthEntry = React.createClass({
});
return (
<div>
<p>A text message has been sent to +<i>{this._msisdn}</i></p>
<p>Please enter the code it contains:</p>
<p>{_t("A text message has been sent to")} +<i>{this._msisdn}</i></p>
<p>{_t("Please enter the code it contains:")}</p>
<div className="mx_InteractiveAuthEntryComponents_msisdnWrapper">
<form onSubmit={this._onFormSubmit}>
<input type="text"

View File

@ -16,7 +16,7 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
module.exports = React.createClass({
displayName: 'LoginFooter',
@ -24,7 +24,7 @@ module.exports = React.createClass({
render: function() {
return (
<div className="mx_Login_links">
<a href="https://matrix.org">powered by Matrix</a>
<a href="https://matrix.org">{_t("powered by Matrix")}</a>
</div>
);
}

View File

@ -21,6 +21,7 @@ import sdk from '../../../index';
import Email from '../../../email';
import { looksValid as phoneNumberLooksValid } from '../../../phonenumber';
import Modal from '../../../Modal';
import { _t } from '../../../languageHandler';
const FIELD_EMAIL = 'field_email';
const FIELD_PHONE_COUNTRY = 'field_phone_country';
@ -103,10 +104,10 @@ module.exports = React.createClass({
title: "Warning!",
description:
<div>
If you don't specify an email address, you won't be able to reset your password.<br/>
Are you sure?
{_t("If you don't specify an email address, you won't be able to reset your password. " +
"Are you sure?")}
</div>,
button: "Continue",
button: _t("Continue"),
onFinished: function(confirmed) {
if (confirmed) {
self._doSubmit();
@ -304,7 +305,7 @@ module.exports = React.createClass({
} else if (this.state.selectedTeam) {
belowEmailSection = (
<p className="mx_Login_support">
You are registering with {this.state.selectedTeam.name}
{_t("You are registering with %(SelectedTeamName)s", {SelectedTeamName: this.state.selectedTeam.name})}
</p>
);
}

View File

@ -19,6 +19,7 @@ limitations under the License.
var React = require('react');
var Modal = require('../../../Modal');
var sdk = require('../../../index');
import { _t } from '../../../languageHandler';
/**
* A pure UI component which displays the HS and IS to use.
@ -136,14 +137,14 @@ module.exports = React.createClass({
checked={!this.state.configVisible}
onChange={this.onServerConfigVisibleChange.bind(this, false)} />
<label className="mx_Login_label" htmlFor="basic">
Default server
{_t("Default server")}
</label>
&nbsp;&nbsp;
<input className="mx_Login_radio" id="advanced" name="configVisible" type="radio"
checked={this.state.configVisible}
onChange={this.onServerConfigVisibleChange.bind(this, true)} />
<label className="mx_Login_label" htmlFor="advanced">
Custom server
{_t("Custom server")}
</label>
</div>
);
@ -155,7 +156,7 @@ module.exports = React.createClass({
<div style={serverConfigStyle}>
<div className="mx_ServerConfig">
<label className="mx_Login_label mx_ServerConfig_hslabel" htmlFor="hsurl">
Home server URL
{_t("Home server URL")}
</label>
<input className="mx_Login_field" id="hsurl" type="text"
placeholder={this.props.defaultHsUrl}
@ -163,7 +164,7 @@ module.exports = React.createClass({
value={this.state.hs_url}
onChange={this.onHomeserverChanged} />
<label className="mx_Login_label mx_ServerConfig_islabel" htmlFor="isurl">
Identity server URL
{_t("Identity server URL")}
</label>
<input className="mx_Login_field" id="isurl" type="text"
placeholder={this.props.defaultIsUrl}
@ -171,7 +172,7 @@ module.exports = React.createClass({
value={this.state.is_url}
onChange={this.onIdentityServerChanged} />
<a className="mx_ServerConfig_help" href="#" onClick={this.showHelpPopup}>
What does this mean?
{_t("What does this mean?")}
</a>
</div>
</div>

View File

@ -22,6 +22,7 @@ import MFileBody from './MFileBody';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from '../../../index';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import { _t } from '../../../languageHandler';
export default class MAudioBody extends React.Component {
constructor(props) {
@ -77,7 +78,7 @@ export default class MAudioBody extends React.Component {
return (
<span className="mx_MAudioBody" ref="body">
<img src="img/warning.svg" width="16" height="16"/>
Error decrypting audio
{_t("Error decrypting audio")}
</span>
);
}

View File

@ -26,6 +26,7 @@ import dis from '../../../dispatcher';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import q from 'q';
import UserSettingsStore from '../../../UserSettingsStore';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'MImageBody',
@ -56,7 +57,7 @@ module.exports = React.createClass({
const ImageView = sdk.getComponent("elements.ImageView");
const params = {
src: httpUrl,
name: content.body && content.body.length > 0 ? content.body : 'Attachment',
name: content.body && content.body.length > 0 ? content.body : _t('Attachment'),
mxEvent: this.props.mxEvent,
};
@ -191,7 +192,7 @@ module.exports = React.createClass({
return (
<span className="mx_MImageBody" ref="body">
<img src="img/warning.svg" width="16" height="16"/>
Error decrypting image
{_t("Error decrypting image")}
</span>
);
}
@ -238,13 +239,13 @@ module.exports = React.createClass({
} else if (content.body) {
return (
<span className="mx_MImageBody">
Image '{content.body}' cannot be displayed.
{_t("Image '%(Body)s' cannot be displayed.", {Body: content.body})}
</span>
);
} else {
return (
<span className="mx_MImageBody">
This image cannot be displayed.
{_t("This image cannot be displayed.")}
</span>
);
}

View File

@ -24,6 +24,7 @@ import sdk from '../../../index';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import q from 'q';
import UserSettingsStore from '../../../UserSettingsStore';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'MVideoBody',
@ -128,7 +129,7 @@ module.exports = React.createClass({
return (
<span className="mx_MVideoBody" ref="body">
<img src="img/warning.svg" width="16" height="16"/>
Error decrypting video
{_t("Error decrypting video")}
</span>
);
}

View File

@ -28,6 +28,7 @@ import ScalarAuthClient from '../../../ScalarAuthClient';
import Modal from '../../../Modal';
import SdkConfig from '../../../SdkConfig';
import dis from '../../../dispatcher';
import { _t } from '../../../languageHandler';
linkifyMatrix(linkify);
@ -230,14 +231,14 @@ module.exports = React.createClass({
let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
let integrationsUrl = SdkConfig.get().integrations_ui_url;
Modal.createDialog(QuestionDialog, {
title: "Add an Integration",
title: _t("Add an Integration"),
description:
<div>
You are about to be taken to a third-party site so you can
authenticate your account for use with {integrationsUrl}.<br/>
Do you wish to continue?
{_t("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: integrationsUrl })}
</div>,
button: "Continue",
button: _t("Continue"),
onFinished: function(confirmed) {
if (!confirmed) {
return;

View File

@ -16,7 +16,8 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'UnknownBody',
@ -24,7 +25,7 @@ module.exports = React.createClass({
render: function() {
const text = this.props.mxEvent.getContent().body;
return (
<span className="mx_UnknownBody" title="Removed or unknown message type">
<span className="mx_UnknownBody" title={_t("Removed or unknown message type")}>
{text}
</span>
);

View File

@ -20,6 +20,7 @@ var MatrixClientPeg = require('../../../MatrixClientPeg');
var sdk = require("../../../index");
var Modal = require("../../../Modal");
var UserSettingsStore = require('../../../UserSettingsStore');
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
@ -120,19 +121,19 @@ module.exports = React.createClass({
<input type="checkbox" ref="globalDisableUrlPreview"
onChange={ this.onGlobalDisableUrlPreviewChange }
checked={ this.state.globalDisableUrlPreview } />
Disable URL previews by default for participants in this room
{_t("Disable URL previews by default for participants in this room")}
</label>;
}
else {
disableRoomPreviewUrls =
<label>
URL previews are { this.state.globalDisableUrlPreview ? "disabled" : "enabled" } by default for participants in this room.
{_t("URL previews are %(globalDisableUrlPreview)s by default for participants in this room.", {globalDisableUrlPreview: this.state.globalDisableUrlPreview ? _t("disabled") : _t("enabled")})}
</label>;
}
return (
<div className="mx_RoomSettings_toggles">
<h3>URL Previews</h3>
<h3>{_t("URL Previews")}</h3>
<label>
You have <a href="#/settings">{ UserSettingsStore.getUrlPreviewsDisabled() ? 'disabled' : 'enabled' }</a> URL previews by default.
@ -142,13 +143,13 @@ module.exports = React.createClass({
<input type="checkbox" ref="userEnableUrlPreview"
onChange={ this.onUserEnableUrlPreviewChange }
checked={ this.state.userEnableUrlPreview } />
Enable URL previews for this room (affects only you)
{_t("Enable URL previews for this room (affects only you)")}
</label>
<label>
<input type="checkbox" ref="userDisableUrlPreview"
onChange={ this.onUserDisableUrlPreviewChange }
checked={ this.state.userDisableUrlPreview } />
Disable URL previews for this room (affects only you)
{_t("Disable URL previews for this room (affects only you)")}
</label>
</div>
);

View File

@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
var React = require('react');
var MatrixClientPeg = require("../../../MatrixClientPeg");
var sdk = require('../../../index');
var dis = require("../../../dispatcher");
var ObjectUtils = require('../../../ObjectUtils');
import React from 'react';
import MatrixClientPeg from "../../../MatrixClientPeg";
import sdk from '../../../index';
import dis from "../../../dispatcher";
import ObjectUtils from '../../../ObjectUtils';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'AuxPanel',
@ -79,7 +81,7 @@ module.exports = React.createClass({
title="Drop File Here">
<TintableSvg src="img/upload-big.svg" width="45" height="59"/>
<br/>
Drop file here to upload
{_t("Drop file here to upload")}
</div>
</div>
);
@ -89,7 +91,7 @@ module.exports = React.createClass({
if (this.props.displayConfCallNotification) {
var supportedText, joinText;
if (!MatrixClientPeg.get().supportsVoip()) {
supportedText = " (unsupported)";
supportedText = _t(" (unsupported)");
}
else {
joinText = (<span>
@ -101,7 +103,7 @@ module.exports = React.createClass({
}
conferenceCallNotification = (
<div className="mx_RoomView_ongoingConfCallNotification">
Ongoing conference call{ supportedText }. { joinText }
{_t("Ongoing conference call%(supportedText)s. %(joinText)s", {supportedText: supportedText, joinText: joinText})}
</div>
);
}

View File

@ -121,7 +121,7 @@ export default class MessageComposer extends React.Component {
title: _t('Upload Files'),
description: (
<div>
<p>{ _t('Are you sure you want upload the following files?') }</p>
<p>{ _t('Are you sure you want to upload the following files?') }</p>
<ul style={{listStyle: 'none', textAlign: 'left'}}>
{fileList}
</ul>

View File

@ -16,10 +16,12 @@ limitations under the License.
'use strict';
var React = require('react');
import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
var MatrixClientPeg = require('../../../MatrixClientPeg');
var sdk = require('../../../index');
module.exports = React.createClass({
displayName: 'PresenceLabel',
@ -67,9 +69,9 @@ module.exports = React.createClass({
},
getPrettyPresence: function(presence) {
if (presence === "online") return "Online";
if (presence === "unavailable") return "Idle"; // XXX: is this actually right?
if (presence === "offline") return "Offline";
if (presence === "online") return _t("Online");
if (presence === "unavailable") return _t("Idle"); // XXX: is this actually right?
if (presence === "offline") return _t("Offline");
return "Unknown";
},

View File

@ -69,7 +69,7 @@
"Anyone who knows the room's link, including guests": "Alle der kender link til rummet, inklusiv gæster",
"Are you sure you want to leave the room?": "Er du sikker på du vil forlade rummet?",
"Are you sure you want to reject the invitation?": "Er du sikker på du vil afvise invitationen?",
"Are you sure you want upload the following files?": "Er du sikker på du vil sende de følgende filer?",
"Are you sure you want to upload the following files?": "Er du sikker på du vil sende de følgende filer?",
"banned": "bortvist",
"Banned users": "Bortviste brugere",
"Bug Report": "Fejlrapport",

View File

@ -20,14 +20,14 @@
"Verification": "Verifizierung",
"Ed25519 fingerprint": "Ed25519 Fingerprint",
"User ID": "Benutzer ID",
"Curve25519 identity key": "Curve25519 Identity Schlüssel",
"Curve25519 identity key": "Curve25519-Identitäts-Schlüssel",
"Claimed Ed25519 fingerprint key": "Geforderter Ed25519 Fingerprint Schlüssel",
"none": "keiner",
"Algorithm": "Algorithmus",
"unencrypted": "unverschlüsselt",
"Decryption error": "Entschlüsselungs Fehler",
"Session ID": "Sitzungs-ID",
"End-to-end encryption information": "Ende-zu-Ende Verschlüsselungs Informationen",
"End-to-end encryption information": "Ende-zu-Ende-Verschlüsselungs-Informationen",
"Event information": "Ereignis Informationen",
"Sender device information": "Absender Geräte Informationen",
"Displays action": "Zeigt Aktionen an",
@ -64,7 +64,7 @@
"Anyone who knows the room's link, including guests": "Jeder der den Raum-Link kennt - auch Gäste",
"Are you sure you want to leave the room?": "Bist du sicher, dass du den Raum verlassen willst?",
"Are you sure you want to reject the invitation?": "Bist du sicher, dass die die Einladung ablehnen willst?",
"Are you sure you want upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen willst?",
"Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen willst?",
"banned": "gebannt",
"Banned users": "Gebannte Nutzer",
"Bug Report": "Fehlerbericht",
@ -98,7 +98,7 @@
"Account": "Konto",
"Add phone number": "Füge Telefonnummer hinzu",
"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 keine Benachrichtigungen an anderen Geräten empfangen bis du dich dort erneut anmeldest",
"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",
"all room members, from the point they are invited": "Alle Raum-Mitglieder, ab dem Zeitpunkt, an dem sie eingeladen werden",
"answered the call.": "beantwortete den Anruf.",
@ -113,7 +113,7 @@
"Export E2E room keys": "Exportiere E2E-Raum-Schlüssel",
"Failed to change password. Is your password correct?": "Passwort-Änderung schlug fehl. Ist dein Passwort korrekt?",
"Failed to forget room": "Vergessen des Raums schlug fehl",
"Failed to leave room": "Fehler beim Verlassen des Raums",
"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 unban": "Entbannen fehlgeschlagen",
@ -177,14 +177,14 @@
"Privacy warning": "Datenschutzwarnung",
"Privileged Users": "Privilegierte Nutzer",
"Profile": "Profil",
"Refer a friend to Riot:": "Lade eine(n) Freund(in) zu Riot ein",
"Refer a friend to Riot:": "Freunde zu Riot einladen:",
"rejected": "abgeleht",
"Once you&#39;ve followed the link it contains, click below": "Nachdem du dem Link gefolgt bist, klicke unten",
"rejected the invitation.": "lehnte die Einladung ab.",
"Reject invitation": "Einladung ablehnen",
"Remove Contact Information?": "Lösche Kontakt-Informationen?",
"removed their display name": "löschte den eigenen Anzeigenamen",
"Remove": "Entferne",
"Remove": "Entfernen",
"requested a VoIP conference": "hat eine VoIP-Konferenz angefordert",
"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.": "Eine Passwortänderung sorgt aktuell dafür, dass alle Ende-zu-Ende-Schlüssel von allen Geräten zurückgesetzt werden. Dadurch wird die verschlüsselte Chat-Historie unlesbar, es sei denn Sie exportieren vorher Ihre Raum-Schlüssel und importieren sie nachher wieder. In Zukunft wird dies verbessert.",
"restore": "Zum zurücksetzen",
@ -251,7 +251,7 @@
"uploaded a file": "lud eine Datei hoch",
"Upload Files": "Dateien hochladen",
"Upload file": "Datei hochladen",
"User Interface": "Nutzerschnittstelle",
"User Interface": "Benutzeroberfläche",
"User name": "Nutzername",
"Users": "Nutzer",
"User": "Nutzer",
@ -288,7 +288,7 @@
"Conference calls are not supported in this client": "Konferenzgespräche sind in diesem Client nicht unterstützt",
"Existing Call": "Existierender Anruf",
"Failed to set up conference call": "Aufbau des Konferenzgesprächs fehlgeschlagen",
"Failed to verify email address: make sure you clicked the link in the email": "Verifizierung der E-Mail-Adresse fehlgeschlagen: Stelle sicher, dass du den Link in der E-Mail anklicktest",
"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 anklickt 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",
"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",
@ -307,7 +307,7 @@
"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 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üsselungscodes für dieses Gerät zu generieren und den öffentl. Schlüssel an deinen Homeserver zu senden. Dies muss einmal gemacht werden. Entschuldige die Unannehmlichkeit.",
"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",
"Sun": "So",
"Mon": "Mo",
@ -334,10 +334,10 @@
"Upload an avatar:": "Lade einen Avatar hoch:",
"This server does not support authentication with a phone number.": "Dieser Server unterstützt keine Authentifizierung mittels Telefonnummer.",
"Missing password.": "Fehlendes Passwort.",
"Passwords don't match.": "Passwörter passen nicht zusammen.",
"Passwords don't match.": "Passwörter stimmen nicht überein.",
"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 sieht nicht nach einer validen E-Mail-Adresse aus.",
"This doesn't look like a valid phone number.": "Dies sieht nicht nach einer validen Telefonnummer aus.",
"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.",
"I already have an account": "Ich habe bereits einen Account",
@ -376,7 +376,7 @@
"New Composer & Autocomplete": "Neuer Eingabeverarbeiter & Autovervollständigung",
"(not supported by this browser)": "(nicht von diesem Browser unterstützt)",
"%(senderName)s placed a %(callType)s call.": "%(senderName)s startete einen %(callType)s-Anruf.",
"Power level must be positive integer.": "Berechtigungslevel muss eine positive Zahl sein.",
"Power level must be positive integer.": "Berechtigungslevel muss eine positive ganze Zahl sein.",
"Reason": "Grund",
"%(targetName)s rejected the invitation.": "%(targetName)s lehnte die Einladung ab.",
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s löschte den Anzeigenamen (%(oldDisplayName)s).",
@ -445,7 +445,7 @@
"ar-qa": "Arabisch (Qatar)",
"ar-sa": "Arabisch (Saudi Arabien)",
"ar-sy": "Arabisch (Syrien)",
"ar-tn": "Arabisch (Tunisien)",
"ar-tn": "Arabisch (Tunesien)",
"ar-ye": "Arabisch (Yemen)",
"be": "Weißrussisch",
"bg": "Bulgarisch",
@ -458,7 +458,7 @@
"en-au": "Englisch (Australien)",
"en-bz": "Englisch (Belize)",
"en-ca": "Englisch (Kanada)",
"en-gb": "Englisch (Vereintes Königreich)",
"en-gb": "Englisch (Vereinigtes Königreich)",
"en-ie": "Englisch (Irland)",
"en-jm": "Englisch (Jamaika)",
"en-nz": "Englisch (Neuseeland)",
@ -502,9 +502,9 @@
"it": "Italienisch",
"ja": "Japanisch",
"ji": "Jiddisch",
"ko": "Koreanisch (Johab)",
"ko": "Koreanisch",
"lt": "Litauisch",
"lv": "lettisch",
"lv": "Lettisch",
"mk": "Mazedonisch (FYROM)",
"ms": "Malaysisch",
"mt": "Maltesisch",
@ -517,11 +517,11 @@
"ro-mo": "Rumänisch (Republik von Moldavien)",
"ro": "Romanian",
"ru-mo": "Russisch",
"sb": "Sorbian",
"sb": "Sorbisch",
"sk": "Slowakisch",
"sl": "Slowenisch",
"sq": "Albanisch",
"sr": "Serbisch (lateinisch)",
"sr": "Serbisch",
"sv-fi": "Schwedisch (Finnland)",
"sv": "Schwedisch",
"sx": "Sutu",
@ -539,8 +539,8 @@
"zh-sg": "Chinesisch (Singapur)",
"zh-tw": "Chinesisch (Taiwan)",
"zu": "Zulu",
"ca": "katalanisch",
"fi": "Finnish",
"ca": "Katalanisch",
"fi": "Finnisch",
"fo": "Färöisch",
"ga": "Irisch",
"hi": "Hindi",
@ -583,7 +583,7 @@
"Failed to save settings": "Einstellungen speichern fehlgeschlagen",
"Failed to set display name": "Anzeigenamen zu ändern fehlgeschlagen",
"Fill screen": "Fülle Bildschirm",
"Guest users can't upload files. Please register to upload": "Gäste können Dateien nicht hochlagen. Bitte registrieren um hochzuladen",
"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": "Verifikationscode inkorrekt",
"Invalid alias format": "Ungültiges Alias-Format",
@ -628,8 +628,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 nicht in der Lage sein, diese Änderung zu ändern da den Nutzer auf dasselbe Berechtigungslevel wie du hebst",
"Make Moderator": "Mache zum Moderator",
"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",
"Room": "Raum",
"(~%(searchCount)s results)": "(~%(searchCount)s Ergebnisse)",
"Cancel": "Abbrechen",
@ -660,13 +660,13 @@
"%(oneUser)sjoined": "%(oneUser)strat bei",
"%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sgingen %(repeats)s mal",
"%(oneUser)sleft %(repeats)s times": "%(oneUser)sging %(repeats)s mal",
"%(severalUsers)sleft": "%(severalUsers)sgingen",
"%(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)sleft and rejoined %(repeats)s times": "%(severalUsers)s gingen und traten erneut bei - %(repeats)s mal",
"%(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 left and rejoined": "%(oneUser)sging und trat erneut bei",
@ -718,7 +718,7 @@
"Report it": "Melde es",
"riot-web version:": "Version von riot-web:",
"Scroll to bottom of page": "Zum Ende der Seite springen",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeige Zeitstempel im 12-Stunden format",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeige Zeitstempel im 12-Stunden-Format (z. B. 2:30pm)",
"to tag as %(tagName)s": "um als \"%(tagName)s\" zu markieren",
"Email address": "E-Mail-Adresse",
"Error decrypting attachment": "Fehler beim Entschlüsseln des Anhangs",
@ -726,5 +726,98 @@
"Operation failed": "Aktion fehlgeschlagen",
"You need to enter a user name.": "Du musst einen Benutzernamen eingeben.",
"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"
"Unmute": "Stummschalten aufheben",
"Invalid file%(extra)s": "Ungültige Datei%(extra)s",
"Remove %(threePid)s?": "Entferne %(threePid)s?",
"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.",
"Passphrases must match": "Passphrase muss übereinstimmen",
"Passphrase must not be empty": "Passphrase darf nicht leer sein",
"Export room keys": "Exportiere Raum-Schlüssel",
"Enter passphrase": "Gebe Passphrase ein",
"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 seine Dateien zu sehen",
"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": "Lehne alle %(invitedRooms)s Einladungen ab",
"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",
"Confirm Removal": "Entfernen bestätigen",
"Unknown error": "Unbekannter Fehler",
"Incorrect password": "Inkorrektes Passwort",
"This action is irreversible.": "Diese Aktion ist irreversibel.",
"To continue, please enter your password.": "Zum fortfahren bitte Passwort eingeben.",
"Device name": "Geräte-Name",
"Device key": "Geräte-Schlüssel",
"In future this verification process will be more sophisticated.": "In Zukunft wird der Verifikationsprozess eleganter.",
"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 dein Name der anderen gezeigt wird, wenn du in Räumen sprichst. Wie möchtest du ihn haben?",
"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 must 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.",
"Unknown devices": "Unbekannte Geräte",
"Unknown Address": "Unbekannte Adresse",
"Verify...": "Verifizieren...",
"ex. @bob:example.com": "z.B. @bob:example.com",
"Add User": "Nutzer hinzufügen",
"Sign in with CAS": "Mit CAS anmelden",
"Custom Server Options": "Erweiterte Server-Optionen",
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Du kannst die erweiterten Server-Optionen nutzen um dich an anderen Matrix-Servern anzumelden indem die eine andere Heimserver-URL angibst.",
"This allows you to use this app with an existing Matrix account on a different home server.": "Dies erlaubt dir diese App mit einem existierenden Matrix-Konto auf einem anderen Heimserver zu verwenden.",
"Dismiss": "Ablehnen",
"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",
"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?",
"You are registering with %(SelectedTeamName)s": "Du registrierst dich mit %(SelectedTeamName)s",
"Default server": "Standard-Server",
"Custom server": "Angepasster Server",
"Home server URL": "Heimserver-URL",
"Identity server URL": "Identitätsserver-URL",
"What does this mean?": "Was bedeutet es?",
"Error decrypting audio": "Audio-Entschlüsselung fehlgeschlagen",
"Error decrypting image": "Bild-Entschlüsselung fehlgeschlagen",
"Image '%(Body)s' cannot be displayed.": "Das Bild '%(Body)s' kann nicht angezeigt werden.",
"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",
"Failed to invite the following users to the %(roomName)s room:": "Einladen folgender Nutzer in den Raum \"%(roomName)s\" schlug fehl:",
"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.",
"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 dir die Schlüssel für in verschlüsselten Räumen empfangene Nachrichten in eine lokale Datei zu exportieren. In Zukunft wirst du diese Datei in einen anderen Matrix-Client importieren können, 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 Analyse verweigern",
"Riot collects anonymous analytics to allow us to improve the application.": "Riot sammeln anonyme Daten damit wir die Anwendung verbessern können.",
"Add an Integration": "Eine Integration hinzufügen",
"Removed or unknown message type": "Gelöschte oder unbekannter Nachrichten-Typ",
"Disable URL previews by default for participants in this room": "Deaktiviere standardmäßig die URL-Vorschau für Teilnehmer dieses Raumes",
"URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "URL-Vorschau ist standardmäßig %(globalDisableUrlPreview)s für Teilnehmer dieses Raumes.",
"URL Previews": "URL-Vorschau",
"Enable URL previews for this room (affects only you)": "Aktiviere die URL-Vorschau in diesem Raum (betrifft nur dich)",
"Offline": "Offline",
"Online": "Online",
" (unsupported)": " (nicht unterstützt)",
"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.": "Diese Vorgehensweise erlaubt es dir, die zuvor von einem anderen Matrix-Client exportierten Verschlüsselungs-Schlüssel zu importieren. Danach kannst du alle Nachrichten entschlüsseln, die auch bereits auf dem anderen Client entschlüsselt werden konnten.",
"This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dies wird dein Konto permanent unbenutzbar machen. Du wirst dich nicht mit derselben Nutzer-ID erneut registrieren können.",
"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:": "Um zu bestätigen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer über einen anderen Weg (z.B. Telefon-Anruf) und frage, ob der Schlüssel, den sie in den Nutzer-Einstellungen für dieses Gerät sehen dem folgenden gleicht:",
"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.": "Wenn er passt, betätige den Bestätigen-Button unten. Wenn nicht, fängt jemand anderes dieses Gerät ab und du möchtest wahrscheinlich lieber den Blacklist-Button betätigen.",
"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.": "Wir sind auf einen Fehler gestoßen während wir deine vorherige Sitzung wiederherstellen wollten. Wenn du fortfährst, wirst du dich erneut anmelden müssen und die verschlüsselte Chat-Historie wir unlesbar sein.",
"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 vorher eine aktuellere Version von Riot verwendet hast, ist deine Sitzung wohlmöglich inkompatibel mit dieser Version. Schließe dieses Fenster und kehre zur aktuelleren Version zurück.",
"Blacklist": "Blockieren",
"Unblacklist": "Entblockieren",
"Unverify": "Entverifizieren",
"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": "inaktiv",
"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",
"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 eine Drittanbieter-Website weitergeleitet, damit du dein Konto authentifizieren kannst für die Verwendung mit %(integrationsUrl)s. Möchtest du fortfahren?"
}

View File

@ -155,7 +155,7 @@
"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 reject the invitation?": "Are you sure you want to reject the invitation?",
"Are you sure you want upload the following files?": "Are you sure you want upload the following files?",
"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.",
@ -174,6 +174,7 @@
"%(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",
@ -675,5 +676,95 @@
"%(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"
"Desktop specific": "Desktop specific",
"Analytics": "Analytics",
"Opt out of analytics": "Opt out of analytics",
"Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.",
"Please select the destination room for this message": "Please select the destination room for this message",
"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",
"Enter passphrase": "Enter passphrase",
"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", "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.",
"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. %(joinText)s": "Ongoing conference call%(supportedText)s. %(joinText)s",
"Online": "Online",
"Idle": "Idle",
"Offline": "Offline",
"Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)"
}

331
src/i18n/strings/es.json Normal file
View File

@ -0,0 +1,331 @@
{
"af": "Africano",
"ar-ae": "Árabe (Emiratos Árabes Unidos)",
"ar-bh": "Árabe (Baréin)",
"ar-dz": "Árabe (Argelia)",
"ar-eg": "Árabe (Egipto)",
"ar-iq": "Árabe (Irak)",
"ar-jo": "Árabe (Jordania)",
"ar-kw": "Árabe (Kuwait)",
"ar-lb": "Árabe (Líbano)",
"ar-ly": "Árabe (Libia)",
"ar-ma": "Árabe (Marruecos)",
"ar-om": "Árabe (Omán)",
"ar-qa": "Árabe (Catar)",
"ar-sa": "Árabe (Arabia Saudita)",
"ar-sy": "Árabe (Siria)",
"ar-tn": "Árabe (Túnez)",
"ar-ye": "Árabe (Yemen)",
"be": "Bielorrusia",
"bg": "Bulgaria",
"ca": "Catalán",
"cs": "Checo",
"da": "Danés",
"de-at": "Alemán (Austria)",
"de-ch": "Alemán (Suiza)",
"de": "Alemán",
"de-li": "Alemán (Liechtenstein)",
"de-lu": "Alemán (Luxemburgo)",
"el": "Griego",
"en-au": "Inglés (Australia)",
"en-bz": "Inglés (Belice)",
"en-ca": "Inglés (Canadá)",
"en": "Inglés",
"en-gb": "Inglés (Reino Unido)",
"en-ie": "Inglés (Irlanda)",
"en-jm": "Inglés (Jamaica)",
"en-nz": "Inglés (Nueva Zelanda)",
"en-tt": "Inglés (Trinidad y Tobago)",
"en-us": "Inglés (Estados Unidos)",
"en-za": "Inglés (Sudáfrica)",
"es-ar": "Español (Argentina)",
"es-bo": "Español (Bolivia)",
"es-cl": "Español (Chile)",
"es-co": "Español (Colombia)",
"es-cr": "Español (Costa Rica)",
"es-do": "Español (República Dominicana)",
"es-ec": "Español (Ecuador)",
"es-gt": "Español (Guatemala)",
"es-hn": "Español (Honduras)",
"es-mx": "Español (México)",
"es-ni": "Español (Nicaragua)",
"es-pa": "Español (Panamá)",
"es-pe": "Español (Perú)",
"es-pr": "Español (Puerto Rico)",
"es-py": "Español (Paraguay)",
"es": "Español (España)",
"es-sv": "Español (El Salvador)",
"es-uy": "Español (Uruguay)",
"es-ve": "Español (Venezuela)",
"et": "Estonio",
"eu": "Vasco",
"fa": "Persa",
"fi": "Finés",
"fo": "Feroés",
"fr-be": "Francés (Bélgica)",
"fr-ca": "Francés (Canadá)",
"fr-ch": "Francés (Suiza)",
"fr": "Francés",
"fr-lu": "Francés (Luxemburgo)",
"ga": "Irlandés",
"gd": "Gaélico (Escocia)",
"he": "Hebreo",
"hi": "Hindi",
"hr": "Croata",
"hu": "Húngaro",
"id": "Indonesio",
"is": "Islandés",
"it-ch": "Italiano (Suiza)",
"it": "Italiano",
"ja": "Japonés",
"ji": "Yidis",
"ko": "Coreano",
"lt": "Lituano",
"lv": "Letón",
"mk": "Macedonio",
"ms": "Malayo",
"mt": "Maltés",
"nl-be": "Holandés (Bélgica)",
"nl": "Holandés",
"no": "Noruego",
"pl": "Polaco",
"pt-br": "Portugués (Brasil)",
"pt": "Portugués",
"rm": "Retorrománico",
"ro-mo": "Rumano (República de Moldavia)",
"ro": "Rumano",
"ru-mo": "Ruso (República de Moldavia)",
"ru": "Ruso",
"sb": "Sorbio",
"sk": "Eslovaco",
"sl": "Esloveno",
"sq": "Albanés",
"sr": "Serbio",
"sv-fi": "Sueco (Finlandia)",
"sv": "Sueco",
"sx": "Sotho",
"sz": "Sami (Lapón)",
"th": "Tailandés",
"tn": "Setsuana",
"tr": "Turco",
"ts": "Songa",
"uk": "Ucraniano",
"ur": "Urdú",
"ve": "Venda",
"vi": "Vietnamita",
"xh": "Josa",
"zh-cn": "Chino Mandarín",
"zh-hk": "Chino (Hong Kong RAE)",
"zh-sg": "Chino (Singapur)",
"zh-tw": "Chino (Taiwanés)",
"zu": "Zulú",
"A registered account is required for this action": "Una cuenta registrada es necesaria para esta acción",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Un mensaje de texto ha sido enviado a +%(msisdn)s. Por favor ingrese el código de verificación que lo contiene",
"accept": "Aceptar",
"%(targetName)s accepted an invitation.": "%(targetName)s ha aceptado una invitación.",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s ha aceptado la invitación para %(displayName)s.",
"Account": "Cuenta",
"Access Token:": "Token de Acceso:",
"Add email address": "Agregar correo eléctronico",
"Add phone number": "Agregar número telefónico",
"Admin": "Administrador",
"Advanced": "Avanzado",
"Algorithm": "Algoritmo",
"Always show message timestamps": "Siempre mostrar la hora del mensaje",
"Authentication": "Autenticación",
"all room members": "Todos los miembros de la sala",
"all room members, from the point they are invited": "Todos los miembros de la sala, desde el momento en que son invitados",
"all room members, from the point they joined": "Todos los miembros de la sala, desde el momento en que se han unido",
"an address": "una dirección",
"and": "y",
"%(items)s and %(remaining)s others": "%(items)s y %(remaining)s otros",
"%(items)s and one other": "%(items)s y otro",
"%(items)s and %(lastItem)s": "%(items)s y %(lastItem)s",
"and %(overflowCount)s others...": "y %(overflowCount)s otros...",
"and one other...": "y otro...",
"%(names)s and %(lastPerson)s are typing": "%(names)s y %(lastPerson)s están escribiendo",
"%(names)s and one other are typing": "%(names)s y otro están escribiendo",
"%(names)s and %(count)s others are typing": "%(names)s y %(count)s otros están escribiendo",
"An email has been sent to": "Un correo ha sido enviado a",
"A new password must be entered.": "Una nueva clave debe ser ingresada.",
"%(senderName)s answered the call.": "%(senderName)s atendió la llamada.",
"anyone": "nadie",
"An error has occurred.": "Un error ha ocurrido.",
"Anyone who knows the room's link, apart from guests": "Nadie quien sepa el enlace de la sala, aparte de los invitados",
"Anyone who knows the room's link, including guests": "Nadie quien sepa del enlace de la sala, incluyendo los invitados",
"Are you sure?": "¿Estás seguro?",
"Are you sure you want to reject the invitation?": "¿Estás seguro que quieres rechazar la invitación?",
"Are you sure you want upload the following files?": "¿Estás seguro que quieres subir los siguientes archivos?",
"Attachment": "Adjunto",
"Autoplay GIFs and videos": "Reproducir automáticamente GIFs y videos",
"%(senderName)s banned %(targetName)s.": "%(senderName)s ha bloqueado a %(targetName)s.",
"Ban": "Bloquear",
"Banned users": "Usuarios bloqueados",
"Bans user with given id": "Bloquear usuario por ID",
"Blacklisted": "En lista negra",
"Bug Report": "Reporte de error",
"Bulk Options": "Opciones masivas",
"Call Timeout": "Tiempo de espera de la llamada",
"Can't connect to homeserver - please check your connectivity and ensure your %(urlStart)s homeserver's SSL certificate %(urlEnd)s is trusted": "No se puede conectar con el servidor - Por favor verifique su conexión y asegúrese de que su %(urlStart)s certificado SSL del servidor %(urlEnd)s sea confiable",
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or %(urlStart)s enable unsafe scripts %(urlEnd)s": "No se puede conectar al servidor via HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o %(urlStart)s habilitando los scripts inseguros %(urlEnd)s",
"Can't load user settings": "No se puede cargar las configuraciones del usuario",
"Change Password": "Cambiar clave",
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ha cambiado su nombre de %(oldDisplayName)s a %(displayName)s.",
"%(senderName)s changed their profile picture.": "%(senderName)s ha cambiado su foto de perfil.",
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha cambiado el nivel de acceso de %(powerLevelDiffText)s.",
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ha cambiado el nombre de la sala a %(roomName)s.",
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s ha cambiado el tema de la sala a \"%(topic)s\".",
"Changes to who can read history will only apply to future messages in this room": "Cambios para quien pueda leer el historial solo serán aplicados a futuros mensajes en la sala",
"Changes your display nickname": "Cambia la visualización de tu apodo",
"changing room on a RoomView is not supported": "cambiando la sala en un RoomView no esta soportado",
"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.": "El cambio de contraseña restablecerá actualmente todas las claves de cifrado de extremo a extremo de todos los dispositivos, haciendo que el historial de chat cifrado sea ilegible, a menos que primero exporte las claves de la habitación y vuelva a importarlas después. En el futuro esto será mejorado.",
"Claimed Ed25519 fingerprint key": "Clave Ed25519 es necesaria",
"Clear Cache and Reload": "Borrar caché y recargar",
"Clear Cache": "Borrar caché",
"Click here": "Haz clic aquí",
"Click here to fix": "Haz clic aquí para arreglar",
"Click to mute audio": "Haz clic para silenciar audio",
"Click to mute video": "Haz clic para silenciar video",
"click to reveal": "Haz clic para ver",
"Click to unmute video": "Haz clic para activar sonido del video",
"Click to unmute audio": "Haz clic para activar sonido de audio",
"Command error": "Error de comando",
"Commands": "Comandos",
"Conference call failed": "La llamada de conferencia falló",
"Conference calling is in development and may not be reliable": "La llamada en conferencia esta en desarrollo y no podría ser segura",
"Conference calls are not supported in encrypted rooms": "Las llamadas en conferencia no son soportadas en salas encriptadas",
"Conference calls are not supported in this client": "Las llamadas en conferencia no son soportadas en este navegador",
"Confirm password": "Confirmar clave",
"Confirm your new password": "Confirma tu nueva clave",
"Continue": "Continuar",
"Could not connect to the integration server": "No se pudo conectar al servidor de integración",
"Create an account": "Crear una cuenta",
"Create Room": "Crear una sala",
"Cryptography": "Criptografía",
"Current password": "Clave actual",
"Curve25519 identity key": "Clave de identidad Curve25519",
"/ddg is not a command": "/ddg no es un comando",
"Deactivate Account": "Desactivar Cuenta",
"Deactivate my account": "Desactivar mi cuenta",
"decline": "rechazar",
"Decrypt %(text)s": "Descifrar %(text)s",
"Decryption error": "Error al decifrar",
"Delete": "Eliminar",
"demote": "degradar",
"Deops user with given id": "Deops usuario con ID dado",
"Default": "Por defecto",
"Device ID": "ID del dispositivo",
"Devices": "Dispositivos",
"Devices will not yet be able to decrypt history from before they joined the room": "Los dispositivos aun no serán capaces de descifrar el historial antes de haberse unido a la sala",
"Direct Chat": "Conversación directa",
"Direct chats": "Conversaciones directas",
"Disable inline URL previews by default": "Deshabilitar previsualizacón de enlaces por defecto",
"Disinvite": "Deshacer invitación",
"Display name": "Nombre para mostrar",
"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 to tag %(section)s": "Suelta aquí para etiquetar %(section)s",
"Ed25519 fingerprint": "Clave de cifrado Ed25519",
"Email": "Correo electrónico",
"Email address": "Dirección de correo electrónico",
"Email, name or matrix ID": "Correo electrónico, nombre o Matrix ID",
"Emoji": "Emoticones",
"Enable encryption": "Habilitar encriptación",
"Encrypted messages will not be visible on clients that do not yet implement encryption": "Los mensajes encriptados no serán visibles en navegadores que no han implementado aun la encriptación",
"Encrypted room": "Sala encriptada",
"%(senderName)s ended the call.": "%(senderName)s terminó la llamada.",
"End-to-end encryption information": "Información de encriptación de extremo a extremo",
"End-to-end encryption is in beta and may not be reliable": "Encriptación de extremo a extremo, esta en version beta y no podría ser confiable",
"Enter Code": "Ingresar Código",
"Error": "Error",
"Error decrypting attachment": "Error al descifrar adjunto",
"Event information": "Información del evento",
"Existing Call": "Llamada existente",
"Export E2E room keys": "Exportar claves E2E de la sala",
"Failed to ban user": "Bloqueo del usuario falló",
"Failed to change password. Is your password correct?": "Falló al cambiar la clave, ¿Está correcta tu clave?",
"Failed to change power level": "Falló al cambiar de nivel de acceso",
"Failed to delete device": "Falló al borrar el dispositivo",
"Failed to forget room %(errCode)s": "Falló al olvidar la sala %(errCode)s",
"Failed to join room": "Falló al unirse a la sala",
"Failed to join the room": "Falló al unirse a la sala",
"Failed to kick": "Falló al expulsar",
"Failed to leave room": "Falló al dejar la sala",
"Failed to load timeline position": "Falló al cargar el historico",
"Failed to lookup current room": "Falló al buscar la actual sala",
"Failed to mute user": "Falló al silenciar el usuario",
"Failed to reject invite": "Falló al rechazar invitación",
"Failed to reject invitation": "Falló al rechazar la invitación",
"Failed to save settings": "Falló al guardar la configuración",
"Failed to send email": "Falló al enviar el correo",
"Failed to send request.": "Falló al enviar la solicitud.",
"Failed to set avatar.": "Falló al establecer el avatar.",
"Failed to set display name": "Falló al establecer el nombre a mostrar",
"Failed to set up conference call": "Falló al configurar la llamada en conferencia",
"Failed to toggle moderator status": "Falló al cambiar estatus de moderador",
"Failed to unban": "Falló al desbloquear",
"Failed to upload file": "Falló al subir archivo",
"Failed to verify email address: make sure you clicked the link in the email": "Falló al verificar el correo electrónico: Asegúrese hacer clic en el enlace del correo",
"Failure to create room": "Falló al crear sala",
"Favourite": "Favorito",
"favourite": "favorito",
"Favourites": "Favoritos",
"Fill screen": "Llenar pantalla",
"Filter room members": "Filtrar los miembros de la sala",
"Forget room": "Olvidar sala",
"Forgot your password?": "¿Olvidaste tu clave?",
"For security, this session has been signed out. Please sign in again.": "Por seguridad, esta sesión ha sido cerrada. Por favor inicia sesión nuevamente.",
"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.": "Por seguridad, al cerrar la sesión borrará cualquier clave de encriptación de extremo a extremo en este navegador. Si quieres ser capaz de descifrar tu historial de conversación, para las futuras sesiones en Riot, por favor exporta las claves de la sala para protegerlas.",
"Found a bug?": "¿Encontraste un error?",
"%(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",
"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",
"Hangup": "Colgar",
"Hide read receipts": "Ocultar mensajes leídos",
"Hide Text Formatting Toolbar": "Ocultar barra de herramientas de formato de texto",
"Historical": "Histórico",
"Homeserver is": "El servidor es",
"Identity Server is": "La identidad del servidor es",
"I have verified my email address": "He verificado mi dirección de correo electrónico",
"Import E2E room keys": "Importar claves E2E de la sala",
"Incorrect verification code": "Verificación de código incorrecta",
"Interface Language": "Idioma de la interfaz",
"Invalid alias format": "Formato de alias inválido",
"Invalid address format": "Formato de dirección inválida",
"Invalid Email Address": "Dirección de correo electrónico inválida",
"Invalid file%(extra)s": "Archivo inválido %(extra)s",
"%(senderName)s invited %(targetName)s.": "%(senderName)s ha invitado a %(targetName)s.",
"Invite new room members": "Invitar nuevos miembros a la sala",
"Invites": "Invitar",
"Invites user with given id to current room": "Invitar a usuario con ID dado a esta sala",
"is a": "es un",
"'%(alias)s' is not a valid format for an address": "'%(alias)s' no es un formato válido para una dirección",
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' no es un formato válido para un alias",
"%(displayName)s is typing": "%(displayName)s esta escribiendo",
"I want to sign in with": "Quiero iniciar sesión con",
"Join Room": "Unirte a la sala",
"joined and left": "unido y dejado",
"joined": "unido",
"%(targetName)s joined the room.": "%(targetName)s se ha unido a la sala.",
"Joins room with given alias": "Unirse a la sala con el alias dado",
"%(senderName)s kicked %(targetName)s.": "%(senderName)s ha expulsado a %(targetName)s.",
"Kick": "Expulsar",
"Kicks user with given id": "Expulsar usuario con ID dado",
"Labs": "Laboratorios",
"Leave room": "Dejar sala",
"left and rejoined": "dejado y reunido",
"left": "dejado",
"%(targetName)s left the room.": "%(targetName)s ha dejado la sala.",
"Level": "Nivel",
"Local addresses for this room:": "Direcciones locales para esta sala:",
"Logged in as:": "Sesión iniciada como:",
"Login as guest": "Iniciar sesión como invitado",
"Logout": "Cerrar Sesión",
"Low priority": "Baja prioridad"
}

View File

@ -139,7 +139,7 @@
"Encrypted room": "Salon encrypté",
"%(senderName)s ended the call.": "%(senderName)s a terminé lappel.",
"End-to-end encryption information": "Information sur l'encryption bout-en-bout",
"End-to-end encryption is in beta and may not be reliable": "Lencryption bout-en-bout est en béta et risque de ne pas être fiable",
"End-to-end encryption is in beta and may not be reliable": "Lencryption bout-en-bout est en bêta et risque de ne pas être fiable",
"Enter Code": "Entrer le code",
"Error": "Erreur",
"Event information": "Event information",
@ -152,10 +152,10 @@
"Failed to forget room %(errCode)s": "Echec lors de l'oublie du salon %(errCode)s",
"Please Register": "Veuillez vous enregistrer",
"Remove": "Supprimer",
"was banned": "banned",
"was invited": "invited",
"was kicked": "kicked",
"was unbanned": "unbanned",
"was banned": "a été banni(e)",
"was invited": "a été invité(e)",
"was kicked": "a été expulsé(e)",
"was unbanned": "a été amnistié(e)",
"Monday": "Lundi",
"Tuesday": "Mardi",
"Wednesday": "Mercredi",
@ -195,11 +195,11 @@
"%(names)s and %(count)s others are typing": "%(names)s et %(count)s d'autres sont en train de taper",
"An email has been sent to": "Un e-mail a été envoyé à",
"A new password must be entered.": "Un nouveau mot de passe doit être entré.",
"Anyone who knows the room's link, apart from guests": "Tout ceux qui connaissent le lien du salon, à part les invités",
"Anyone who knows the room's link, including guests": "Tout ceux qui connaissent le lien du salon, y compris les invités",
"Anyone who knows the room's link, apart from guests": "Tout ceux qui connaissent le lien du salon, à part les visiteurs",
"Anyone who knows the room's link, including guests": "Tout ceux qui connaissent le lien du salon, y compris les visiteurs",
"Are you sure?": "Êtes-vous sûr ?",
"Are you sure you want to reject the invitation?": "Êtes-vous sûr de vouloir rejeter l'invitation ?",
"Are you sure you want upload the following files?": "Êtes-vous sûr de vouloir télécharger les fichiers suivants ?",
"Are you sure you want to upload the following files?": "Êtes-vous sûr de vouloir télécharger les fichiers suivants ?",
"Attachment": "Pièce jointe",
"Autoplay GIFs and videos": "Jouer automatiquement les GIFs et vidéos",
"%(senderName)s banned %(targetName)s.": "%(senderName)s a banni %(targetName)s.",
@ -221,7 +221,7 @@
"Changes to who can read history will only apply to future messages in this room": "Les changements de visibilité de lhistorique de ce salon ne sappliquent quaux messages futurs",
"Changes your display nickname": "Change votre nom d'affichage",
"Claimed Ed25519 fingerprint key": "Clé empreinte Ed25519 revendiquée",
"Clear Cache and Reload": "Vider le cache et recharger",
"Clear Cache and Reload": "Vider le cache et rafraîchir",
"Clear Cache": "Vider le cache",
"Click here": "Cliquer ici",
"Click here to fix": "Cliquer ici pour réparer",
@ -268,7 +268,7 @@
"Failed to reject invitation": "Échec lors du rejet de l'invitation",
"Failed to save settings": "Échec lors de la sauvegarde des paramètres",
"Failed to send email": "Échec lors de lenvoi de le-mail",
"Failed to send request.": "Échec lors de lenvoi de la requête.",
"Failed to send request.": "Erreur lors de l'envoi de la requête.",
"Failed to set display name": "Échec lors de l'enregistrement du nom d'affichage",
"Failed to set up conference call": "Échec lors de létablissement de lappel",
"Failed to toggle moderator status": "Échec lors de létablissement du statut de modérateur",
@ -280,7 +280,6 @@
"%(senderName)s answered the call.": "%(senderName)s a répondu à lappel.",
"An error has occurred.": "Une erreur est survenue.",
"Email": "E-mail",
"Failed to send request.": "Erreur lors de l'envoi de la requête.",
"Failed to unban": "Échec de l'amnistie",
"Failed to upload file": "Échec du téléchargement",
"Failed to verify email address: make sure you clicked the link in the email": "Échec de la vérification de ladresse e-mail: vérifiez que vous avez bien cliqué sur le lien dans le-mail",
@ -294,8 +293,8 @@
"For security, this session has been signed out. Please sign in again.": "Par sécurité, la session a expiré. Merci de vous authentifer à nouveau.",
"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 utilisateurs invités 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 utilisateurs invités ne peuvent telécharger de fichiers. Merci de vous enregistrer pour télécharger",
"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",
"had": "avait",
"Hangup": "Raccrocher",
"Hide read receipts": "Cacher les accusés de réception",
@ -335,7 +334,7 @@
"Level": "Niveau",
"Local addresses for this room:": "Adresse locale pour ce salon :",
"Logged in as:": "Identifié en tant que :",
"Login as guest": "Identifié en tant que qu'invité",
"Login as guest": "S'identifier en tant que visiteur",
"Logout": "Se déconnecter",
"Low priority": "Priorité basse",
"%(senderName)s made future room history visible to": "%(senderName)s a rendu l'historique visible de",
@ -350,7 +349,7 @@
"Mobile phone number": "Numéro de téléphone mobile",
"Moderator": "Modérateur",
"Must be viewing a room": "Doit être en train de visualiser un salon",
"my Matrix ID": "mon Matrix ID",
"my Matrix ID": "mon identifiant Matrix",
"Name": "Nom",
"Never send encrypted messages to unverified devices from this device": "Ne jamais envoyer de message encryptés aux appareils non-vérifiés depuis cet appareil",
"Never send encrypted messages to unverified devices in this room": "Ne jamais envoyer de message encryptés aux appareils non-vérifiés dans ce salon",
@ -376,7 +375,333 @@
"or": "ou",
"Password": "Mot de passe",
"Passwords can't be empty": "Le mot de passe ne peut pas être vide",
"People": "Personne",
"People": "Personnes",
"Permissions": "Permissions",
"Phone": "Téléphone"
"Phone": "Numéro de téléphone",
"Operation failed": "L'opération a échoué",
"Bulk Options": "Option en vrac",
"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.": "Changer le mot de passe actuellement réinitialise les clés dencryption sur tous les appareils, rendant lhistorique encrypté illisible, à moins dexporter les clés du salon en avance de phase puis de les ré-importer. Ceci sera amélioré prochainement.",
"Default": "Défaut",
"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 dencryption de cet explorateur. Si vous voulez être capable de décrypter lhistorique de votre conversation lors de sessions futures de Riot, merci dexporter 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.",
"Invalid file%(extra)s": "Fichier %(extra)s invalide",
"Mute": "Couper le son",
"No users have specific privileges in this room": "Aucun utilisateur na de privilège spécifique dans ce salon",
"olm version:": "Version de olm :",
"Once you&#39;ve followed the link it contains, click below": "Une fois que vous aurez suivi le lien quil contient, cliquez ci-dessous",
"%(senderName)s placed a %(callType)s call.": "%(senderName)s a placé un appel %(callType)s.",
"Please check your email and click on the link it contains. Once this is done, click continue.": "Merci de vérifier vos e-mail et cliquer sur le lien quil contient. Une fois que cela est fait, cliquez sur continuer.",
"Power level must be positive integer.": "Le niveau de pouvoir doit être un entier positif.",
"Press": "Cliquer",
"Privacy warning": "Alerte vie privée",
"Privileged Users": "Utilisateur Privilégié",
"Profile": "Profil",
"Reason": "Raison",
"Revoke Moderator": "Révoquer le Modérateur",
"Refer a friend to Riot:": "Recommander Riot à un ami :",
"Registration required": "Inscription requise",
"rejected": "rejeté",
"%(targetName)s rejected the invitation.": "%(targetName)s a rejeté linvitation.",
"Reject invitation": "Rejeter l'invitation",
"Remove Contact Information?": "Supprimer les informations du contact ?",
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s a supprimé son nom daffichage (%(oldDisplayName)s).",
"%(senderName)s removed their profile picture.": "%(senderName)s a supprimé sa photo de profil.",
"Remove %(threePid)s?": "Supprimer %(threePid)s ?",
"%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une conférence audio.",
"Report it": "Le rapporter",
"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.": "Réinitialiser le mot de passe va réinitialiser les clés dencryption sur tous les appareils, rendant lhistorique encrypté illisible, à moins que vous ayez exporté les clés du salon en avance de phase puis que vous les ayez ré-importées. Cela sera amélioré prochainement.",
"restore": "restorer",
"Return to app": "Retourner à lapplication",
"Return to login screen": "Retourner à lécran didentification",
"Riot does not have permission to send you notifications - please check your browser settings": "Riot na pas la permission de vous envoyer des notifications - Merci de vérifier les paramètres de votre explorateur",
"Riot was not given permission to send notifications - please try again": "Riot na pas reçu la permission de vous envoyer des notifications - Merci dessayer à nouveau",
"riot-web version:": "Version de riot-web :",
"Room %(roomId)s not visible": "Le salon %(roomId)s n'est pas visible",
"Room Colour": "Couleur du salon",
"Room name (optional)": "Nom du salon (optionnel)",
"Rooms": "Salons",
"Scroll to bottom of page": "Défiler jusquau bas de la page",
"Scroll to unread messages": "Défiler jusquaux messages non-lus",
"Search": "Rechercher",
"Search failed": "Erreur lors de la recherche",
"Searches DuckDuckGo for results": "Recherche des résultats dans DuckDuckGo",
"Send a message (unencrypted)": "Envoyer un message (non-encrypté)",
"Send an encrypted message": "Envoyer un message non-encrypté",
"Sender device information": "Information de l'appareil de l'expéditeur",
"Send Invites": "Envoyer les invitations",
"Send Reset Email": "Envoyer l'e-mail de réinitialisation",
"sent an image": "envoyer une image",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s a envoyé une image.",
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s a invité %(targetDisplayName)s à rejoindre le salon.",
"sent a video": "a envoyé une vidéo",
"Server error": "Erreur du serveur",
"Server may be unavailable or overloaded": "Le serveur semble être inaccessible ou surchargé",
"Server may be unavailable, overloaded, or search timed out :(": "Le serveur semble être inaccessible, surchargé ou la recherche a expiré :(",
"Server may be unavailable, overloaded, or the file too big": "Le serveur semble être inaccessible, surchargé ou le fichier trop important",
"Server may be unavailable, overloaded, or you hit a bug": "Le serveur semble être inaccessible, surchargé ou vous avez rencontré un problème",
"Server unavailable, overloaded, or something else went wrong": "Le serveur semble être inaccessible, surchargé ou quelque chose s'est mal passé",
"Session ID": "Identifiant de session",
"%(senderName)s set a profile picture.": "%(senderName)s a défini une photo de profil.",
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a défini son nom daffichage comme %(displayName)s.",
"Show panel": "Dévoiler le panneau",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Afficher lheure au format am/pm (par ex. 2:30pm)",
"Signed Out": "Déconnecté",
"Sign in": "S'identifier",
"Sign out": "Se Déconnecter",
"since the point in time of selecting this option": "depuis le moment où cette option a été sélectionnée",
"since they joined": "depuis quils ont rejoint le salon",
"since they were invited": "depuis quils ont été invités",
"Some of your messages have not been sent": "Certains de vos messages nont 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 nest pas reconnu ",
"Start a chat": "Démarrer une conversation",
"Start Chat": "Démarrer une conversation",
"Submit": "Soumettre",
"Success": "Succès",
"tag as %(tagName)s": "marquer comme %(tagName)s",
"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 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 na pas été trouvée",
"%(actionVerb)s this person?": "%(actionVerb)s cette personne ?",
"The email address linked to your account must be entered.": "Ladresse e-mail liée à votre compte doit être entrée.",
"The file '%(fileName)s' exceeds this home server's size limit for uploads": "Le fichier '%(fileName)s' dépasse la taille limite autorisée pour les téléchargements sur ce homeserver",
"The file '%(fileName)s' failed to upload": "Le fichier '%(fileName)s' na pas pu être téléchargé",
"The remote side failed to pick up": "Le correspondant na 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 lhistorique existant sera inchangée",
"This doesn't appear to be a valid email address": "Cette adresse na pas lair dêtre valide",
"this invitation?": "cette invitation ?",
"This is a preview of this room. Room interactions have been disabled": "Ceci est un aperçu du salon. Les interactions avec le salon ont été désactivées",
"This phone number is already in use": "Ce numéro de téléphone est déja utilisé",
"This room is not accessible by remote Matrix servers": "Ce salon nest pas accessible par les serveurs Matrix distants",
"This room's internal ID is": "L'identifiant interne de ce salon est",
"times": "fois",
"To ban users": "Pour bannir des utilisateurs",
"to browse the directory": "pour parcourir le répertoire",
"To configure the room": "Pour configurer le salon",
"to demote": "pour réduire la priorité",
"to favourite": "pour marquer comme favori",
"To invite users into the room": "Pour inviter des utilisateurs dans le salon",
"to join the discussion": "pour rejoindre la discussion",
"To kick users": "Pour expulser des utilisateurs",
"To link to a room it must have": "Pour avoir un lien vers un salon, il doit avoir",
"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 dentrer ladresse email liée à votre compte",
"to restore": "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 quelquun",
"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 lutiliser, attendez simplement que les résultats de lauto-complétion saffichent 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 dun point donné dans la chronologie de ce salon a été effectuée, mais vous navez 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 dun point donné dans la chronologie de ce salon a été effectuée, mais il na pas été 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é lencryption bout-en-bout (algorithme %(algorithm)s).",
"Unable to add email address": "Impossible d'ajouter l'adresse e-mail",
"Unable to remove contact information": "Impossible de supprimer les informations du contact",
"Unable to restore previous session": "Impossible de rétablir la session précédente",
"Unable to verify email address.": "Impossible de vérifier ladresse e-mail.",
"Unban": "Amnistier (annuler le bannissement)",
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s a amnistié %(targetName)s.",
"Unable to capture screen": "Impossible de capturer l'écran",
"Unable to enable Notifications": "Impossible d'activer les notifications",
"Unable to load device list": "Impossible de charger la liste d'appareils",
"Unencrypted room": "Salon non-encrypté",
"unencrypted": "non-encrypté",
"Unknown command": "Commande inconnue",
"unknown device": "appareil inconnu",
"Unknown room %(roomId)s": "Salon inconnu %(roomId)s",
"unknown": "inconnu",
"Unmute": "Activer le son",
"uploaded a file": "télécharger un fichier",
"Upload avatar": "Télécharger une photo de profil",
"Upload Failed": "Erreur lors du téléchargement",
"Upload Files": "Télécharger les fichiers",
"Upload file": "Télécharger le fichier",
"Usage": "Utilisation",
"Use with caution": "Utiliser avec prudence",
"User ID": "Identifiant d'utilisateur",
"User Interface": "Interface utilisateur",
"User name": "Nom d'utilisateur",
"Users": "Utilisateurs",
"User": "Utilisateur",
"Verification Pending": "Vérification en cours",
"Verification": "Vérification",
"verified": "vérifié",
"Video call": "Appel vidéo",
"Voice call": "Appel audio",
"VoIP conference finished.": "Conférence audio terminée.",
"VoIP conference started.": "Conférence audio démarrée.",
"VoIP is unsupported": "Appels voix non supportés",
"(warning: cannot be disabled again!)": "(attention: ne peut être désactivé !)",
"Warning!": "Attention !",
"Who can access this room?": "Qui peut accéder au salon ?",
"Who can read history?": "Qui peut lire l'historique ?",
"Who would you like to add to this room?": "Qui voulez-vous inviter dans ce salon ?",
"Who would you like to communicate with?": "Avec qui voulez-vous communiquer ?",
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a révoqué linvitation de %(targetName)s.",
"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 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 navez pas la permission de poster dans ce salon",
"You have been invited to join this room by %(inviterName)s": "Vous avez été invité à joindre ce salon par %(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": "Vous avez été déconnecté de tous vos appareils et ne recevrez plus de notifications. Pour réactiver les notificationsm identifiez vous à nouveau sur tous les appareils",
"You have no visible notifications": "Vous n'avez pas de notifications visibles",
"you must be a": "vous devez être un",
"You need to be able to invite users to do that.": "Vous devez être capable dinviter des utilisateurs pour faire ça.",
"You need to be logged in.": "Vous devez être connecté.",
"You need to enter a user name.": "Vous devez entrer un nom dutilisateur.",
"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.": "Vous devez vous connecter à nouveau pour générer les clés dencryption pour cet appareil, et soumettre la clé publique à votre homeserver. Cette action ne se reproduira pas; veuillez nous excuser pour la gêne occasionnée.",
"Your email address does not appear to be associated with a Matrix ID on this Homeserver": "Votre adresse e-mail ne semble pas associée à un identifiant Matrix sur ce homeserver",
"Your password has been reset": "Votre mot de passe a été réinitialisé",
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Votre mot de passe a été mis à jour avec succès. Vous ne recevrez plus de notification sur vos appareils jusquà ce que vous vous identifiez à nouveau",
"You seem to be in a call, are you sure you want to quit?": "Vous semblez avoir un appel en cours, êtes-vous sûr(e) de vouloir quitter ?",
"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 lutilisateur aux mêmes pouvoirs que vous",
"Sun": "Dim",
"Mon": "Lun",
"Tue": "Mar",
"Wed": "Mer",
"Thu": "Jeu",
"Fri": "Ven",
"Sat": "Sam",
"Jan": "Jan",
"Feb": "Fev",
"Mar": "Mar",
"Apr": "Avr",
"May": "Mai",
"Jun": "Jun",
"Jul": "Jul",
"Aug": "Aou",
"Sep": "Sep",
"Oct": "Oct",
"Nov": "Nov",
"Dec": "Dec",
"%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s %(day)s %(monthName)s %(time)s",
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s %(time)s",
"%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s",
"Set a display name:": "Définir un nom daffichage :",
"Upload an avatar:": "Télécharger une photo de profil :",
"This server does not support authentication with a phone number.": "Ce serveur ne supporte pas lidentification avec un numéro de téléphone.",
"Missing password.": "Mot de passe manquant.",
"Passwords don't match.": "Les mots de passe ne correspondent pas.",
"Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Mot de passe trop court (min %(MIN_PASSWORD_LENGTH)s).",
"This doesn't look like a valid email address.": "Cela ne semble pas être une adresse e-mail valide.",
"This doesn't look like a valid phone number.": "Cela ne semble pas être un numéro de téléphone valide.",
"User names may only contain letters, numbers, dots, hyphens and underscores.": "Les noms dutilisateurs 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": "Jai déjà un compte",
"An error occured: %(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é",
"Share message history with new users": "Partager lhistorique des messages avec les nouveaux utilisateurs",
"Encrypt room": "Encrypter le salon",
"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.",
"Auto-complete": "Auto-complétion",
"Resend all": "Tout renvoyer",
"(~%(searchCount)s results)": "(~%(searchCount)s résultats)",
"Cancel": "Annuler",
"cancel all": "tout annuler",
"now. You can also select individual messages to resend or cancel.": "maintenant. Vous pouvez aussi sélectionner individuellement les messages que vous voulez renvoyer ou annuler.",
"Active call": "Appel en cours",
"code": "code",
"quote": "citer",
"bullet": "puce",
"numbullet": "liste numérotée",
"%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sont rejoint le salon %(repeats)s fois",
"%(oneUser)sjoined %(repeats)s times": "%(oneUser)sa rejoint le salon %(repeats)s fois",
"%(severalUsers)sjoined": "%(severalUsers)sont rejoint le salon",
"%(oneUser)sjoined": "%(oneUser)sa rejoint le salon",
"%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sont quitté le salon %(repeats)s fois",
"%(oneUser)sleft %(repeats)s times": "%(oneUser)sa quitté le salon %(repeats)s fois",
"%(severalUsers)sleft": "%(severalUsers)sont quitté le salon",
"%(oneUser)sleft": "%(oneUser)sont quitté le salon",
"%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sont rejoint et quitté le salon %(repeats)s fois",
"%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sa rejoint et quitté le salon%(repeats)s fois",
"%(severalUsers)sjoined and left": "%(severalUsers)sont rejoint et quitté le salon",
"%(oneUser)sjoined and left": "%(oneUser)sa rejoint et quitté le salon",
"%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sont quitté et à nouveau joint le salon %(repeats)s fois",
"%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sa quitté et à nouveau joint le salon %(repeats)s fois",
"%(severalUsers)sleft and rejoined": "%(severalUsers)sont quitté et à nouveau joint le salon",
"%(oneUser)sleft and rejoined": "%(oneUser)sa quitté et à nouveau joint le salon",
"%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)sotn rejeté leurs invitations %(repeats)s fois",
"%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)sa rejeté son invitation %(repeats)s fois",
"%(severalUsers)srejected their invitations": "%(severalUsers)sont rejeté leurs invitations",
"%(oneUser)srejected their invitation": "%(oneUser)sa rejeté son invitation",
"%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)sont vu leurs invitations rétractées %(repeats)s fois",
"%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)sa vu son invitation rétractée %(repeats)s fois",
"%(severalUsers)shad their invitations withdrawn": "%(severalUsers)sont vu leurs invitations rétractées",
"%(oneUser)shad their invitation withdrawn": "%(oneUser)sa vu son invitation rétractée",
"were invited %(repeats)s times": "ont été invité(e)s %(repeats)s fois",
"was invited %(repeats)s times": "a été invité(e) %(repeats)s fois",
"were invited": "ont été invité(e)s",
"were banned %(repeats)s times": "ont été banni(e)s %(repeats)s fois",
"was banned %(repeats)s times": "été banni(e) %(repeats)s fois",
"were banned": "ont été banni(e)s",
"were unbanned %(repeats)s times": "ont été amnistié(e)s %(repeats)s fois",
"was unbanned %(repeats)s times": "a été amnistié(e) %(repeats)s fois",
"were unbanned": "ont été amnistié(e)s",
"were kicked %(repeats)s times": "ont été expulsé(e)s %(repeats)s fois",
"was kicked %(repeats)s times": "a été expulsé(e) %(repeats)s fois",
"were kicked": "ont été expulsé(e)s",
"%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)sont changé leur nom %(repeats)s fois",
"%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sa changé son nom %(repeats)s times",
"%(severalUsers)schanged their name": "%(severalUsers)sont changé leur nom",
"%(oneUser)schanged their name": "%(oneUser)sa changé son nom",
"%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)sont changé leur photo de profil %(repeats)s fois",
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sa changé sa photo de profil %(repeats)s fois",
"%(severalUsers)schanged their avatar": "%(severalUsers)sont changé leur photo de profil",
"%(oneUser)schanged their avatar": "%(oneUser)sa changé sa photo de profil",
"Please select the destination room for this message": "Merci de sélectionner un salon de destination pour ce message",
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s a supprimé le nom du salon.",
"Analytics": "Outils d'analyse",
"Opt out of analytics": "Refus de participation",
"Riot collects anonymous analytics to allow us to improve the application.": "Riot recueille des données anonymes qui nous permettent danalyser et améliorer lapplication.",
"Passphrases must match": "Les phrases secrètes doivent être identiques",
"Passphrase must not be empty": "La phrase secrète ne doit pas être vide",
"Export room keys": "Exporter les clés du salon",
"Enter passphrase": "Entrer la phrase secrète",
"Confirm passphrase": "Confirmer la phrase secrète",
"Import room keys": "Importer les clés du salon",
"File to import": "Fichier à importer",
"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.": "Ce processus vous permet dexporter dans un fichier local les clés pour les messages que vous avez reçus dans des salons encryptés. Il sera ensuite possible dimporter ce fichier dans un autre client Matrix, afin de permettre à ce client de pouvoir décrypter ces 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.": "Le fichier exporté permettra à tout ceux qui peuvent le lire de décrypter tous les messages encrypté auxquels vous avez accès, vous devez donc être vigilant et le stocker dans un endroit sûr. Afin de protéger ce fichier, entrez ci-dessous une phrase secrète qui sera utilisée pour encrypter les données exportées. Seule lutilisation de la même phrase secrète permettra de décrypter et importer les données.",
"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.": "Ce processus vous permet dimporter les clés dencryption que vous avez précédemment exportées depuis un autre client Matrix. Vous serez alors capable de décrypter nimporte quel messages que lautre client peut décrypter.",
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Le fichier exporté est protégé par une phrase secrète. Vous devez entrer cette phrase secrète ici pour décrypter le fichier.",
"You must join the room to see its files": "Vous devez joindre le salon pour voir ses fichiers",
"Server may be unavailable, overloaded, or you hit a bug.": "Le serveur semble être indisponible, surchargé, ou vous avez rencontré un problème.",
"Reject all %(invitedRooms)s invites": "Rejeter la totalité des %(invitedRooms)s invitations",
"Start new Chat": "Démarrer une nouvelle conversation",
"Guest users can't invite users. Please register.": "Les visiteurs ne peuvent inviter dautres utilisateurs. Merci de vous enregistrer.",
"Failed to invite": "Echec de l'invitation",
"Failed to invite user": "Echec lors de l'invitation de l'utilisateur",
"Failed to invite the following users to the %(roomName)s room:": "Echec lors de linvitation des utilisateurs suivants dans le salon %(roomName)s :",
"Confirm Removal": "Confirmer la suppression",
"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.": "Êtes vous sûr de vouloir supprimer cet événement ? Notez que si vous supprimez le changement de nom dun salon ou la mise a jour du sujet dun salon, il est possible que le changement soit annulé.",
"Unknown error": "Erreur inconnue",
"Incorrect password": "Mot de passe incorrect",
"This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ceci rendra votre compte inutilisable de manière permanente. Vous ne pourrez pas enregistrer à nouveau le même identifiant utilisateur."
}

View File

@ -1,4 +1,202 @@
{
"af": "Afrikaans",
"ar-ae": "Arabisch (U.A.E.)"
"ar-ae": "Arabisch (U.A.E.)",
"Direct Chat": "Privé gesprek",
"ar-bh": "Arabisch (Bahrain)",
"ar-dz": "Arabisch (Algerije)",
"ar-eg": "Arabisch (Egypte)",
"ar-iq": "Arabisch (Irak)",
"ar-jo": "Arabisch (Jordanië)",
"ar-kw": "Arabisch (Koeweit)",
"ar-lb": "Arabisch (Libanon)",
"ar-ly": "Arabisch (Libië)",
"ar-ma": "Arabisch (Marokko)",
"ar-om": "Arabisch (Oman)",
"ar-qa": "Arabisch (Katar)",
"ar-sa": "Arabisch (Saoedi-Arabië)",
"ar-sy": "Arabisch (Syrië)",
"ar-tn": "Arabisch (Tunesië)",
"ar-ye": "Arabisch (Jemen)",
"be": "Wit-Russisch",
"bg": "Bulgaars",
"ca": "Catalaans",
"cs": "Tsjechisch",
"da": "Deens",
"de-at": "Duits (Oostenrijk)",
"de-ch": "Duits (Zwitserland)",
"de": "Duits",
"de-li": "Duits (Liechtenstein)",
"de-lu": "Duits (Luxemburg)",
"el": "Grieks",
"en-au": "Engels (Australië)",
"en-bz": "Engels (Belize)",
"en-ca": "Engels (Canada)",
"en": "Engels",
"en-gb": "Engels (Verenigd Koningkrijk)",
"en-ie": "Engels (Ierland)",
"en-jm": "Engels (Jamaica)",
"en-nz": "Engels (Nieuw Zeeland)",
"en-tt": "Engels (Trinidad)",
"en-us": "Engels (Verenigde Staten)",
"en-za": "Engels (Zuid-Afrika)",
"es-ar": "Spaans (Argentinië)",
"es-bo": "Spaans (Bolivië)",
"es-cl": "Spaans (Chili)",
"es-co": "Spaans (Colombia)",
"es-cr": "Spaans (Costa Rica)",
"es-do": "Spaans (Dominicaanse Republiek)",
"es-ec": "Spaans (Ecuador)",
"es-gt": "Spaans (Guatemala)",
"es-hn": "Spaans (Honduras)",
"es-mx": "Spaans (Mexico)",
"es-ni": "Spaans (Nicaragua)",
"es-pa": "Spaans (Panama)",
"es-pe": "Spaans (Peru)",
"es-pr": "Spaans (Puerto Rico)",
"es-py": "Spaans (Paraguay)",
"es": "Spaans (Spanje)",
"es-sv": "Spaans (El Salvador)",
"es-uy": "Spaans (Uruguay)",
"es-ve": "Spaans (Venezuela)",
"et": "Estlands",
"eu": "Baskisch (Bask)",
"fa": "Farsi",
"fi": "Fins",
"fo": "Faeroesisch",
"fr-be": "Frans (België)",
"fr-ca": "Frans (Canada)",
"fr-ch": "Frans (Zwitserland)",
"fr": "Frans",
"fr-lu": "Frans (Luxemburg)",
"ga": "Iers",
"gd": "Keltisch (Schotland)",
"he": "Hebreeuws",
"hi": "Hindi",
"hr": "Kroatisch",
"hu": "Hongaars",
"id": "Indonesisch",
"is": "IJslands",
"it-ch": "Italiaans (Zwitserland)",
"it": "Italiaans",
"ja": "Japans",
"ji": "Jiddisch",
"ko": "Koreaans",
"lt": "Litouws",
"lv": "Lets",
"mk": "Macedonië (FYROM)",
"ms": "Maleisisch",
"mt": "Maltees",
"nl-be": "Nederlands (België)",
"nl": "Nederlands",
"no": "Noors",
"pl": "Pools",
"pt-br": "Braziliaans Portugees",
"pt": "Portugees",
"rm": "Rhetoromaans",
"ro-mo": "Roemeens (Moldavië)",
"ro": "Roemeens",
"ru-mo": "Russisch (Moldavië)",
"ru": "Russisch",
"sb": "Sorbisch",
"sk": "Slovaaks",
"sl": "Sloveens",
"sq": "Albanees",
"sr": "Servisch",
"sv-fi": "Zweeds (Finland)",
"sv": "Zweeds",
"sx": "Sutu",
"sz": "Sami (Lapland)",
"th": "Thais",
"tn": "Tswana",
"tr": "Turks",
"ts": "Tsonga",
"uk": "Oekraïens",
"ur": "Urdu",
"ve": "Venda",
"vi": "Vietnamees",
"xh": "Xhosa",
"zh-cn": "Chinees (PRC)",
"zh-hk": "Chinees (Hong Kong SAR)",
"zh-sg": "Chinees (Singapore)",
"zh-tw": "Chinees (Taiwan)",
"zu": "Zulu",
"A registered account is required for this action": "Voor deze actie is een geregistreerd account nodig",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Voer alsjeblieft de verificatiecode in die is verstuurd naar +%(msisdn)s",
"accept": "accepteer",
"%(targetName)s accepted an invitation.": "%(targetName)s heeft een uitnodiging geaccepteerd.",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s heeft de uitnodiging voor %(displayName)s geaccepteerd.",
"Account": "Account",
"Access Token:": "Toegangstoken:",
"Add email address": "Voeg een email address toe",
"Add phone number": "Voeg een telefoonnummer toe",
"Admin": "Beheerder",
"Advanced": "Geavanceerd",
"Algorithm": "Algoritme",
"Always show message timestamps": "Laat altijd tijdstempels van berichten zien",
"Authentication": "Authenticatie",
"all room members": "alle kamer leden",
"all room members, from the point they are invited": "alle kamer leden, vanaf het moment dat ze uitgenodigt zijn",
"all room members, from the point they joined": "alle kamer leden, vanaf het moment dat ze toegetreden zijn",
"an address": "een adres",
"and": "en",
"%(items)s and %(remaining)s others": "%(items)s en %(remaining)s andere",
"%(items)s and one other": "%(items)s en één andere",
"%(items)s and %(lastItem)s": "%(items)s en %(lastItem)s",
"and %(overflowCount)s others...": "en %(overflowCount)s andere...",
"and one other...": "en één andere...",
"%(names)s and %(lastPerson)s are typing": "%(names)s en %(lastPerson)s zijn aan het typen",
"%(names)s and one other are typing": "%(names)s en één andere zijn aan het typen",
"%(names)s and %(count)s others are typing": "%(names)s en %(count)s andere zijn aan het typen",
"An email has been sent to": "Er is een email verzonden naar",
"A new password must be entered.": "Er moet een nieuw wachtwoord worden ingevoerd.",
"%(senderName)s answered the call.": "%(senderName)s heeft deelgenomen aan het audio gesprek.",
"anyone": "iedereen",
"An error has occurred.": "Er is een fout opgetreden.",
"Anyone who knows the room's link, apart from guests": "Iedereen die de kamer link weet, behalve gasten",
"Anyone who knows the room's link, including guests": "Iedereen die de kamer link weet, inclusief gasten",
"Are you sure?": "Weet je het zeker?",
"Are you sure you want to reject the invitation?": "Weet je zeker dat je de uitnodiging wilt weigeren?",
"Are you sure you want upload the following files?": "Weet je zeker dat je de volgende bestanden wilt uploaden?",
"Attachment": "Bijlage",
"Autoplay GIFs and videos": "Start GIFs en videos automatisch",
"%(senderName)s banned %(targetName)s.": "%(senderName)s heeft %(targetName)s verbannen.",
"Ban": "Verban",
"Banned users": "Verbannen gebruikers",
"Bans user with given id": "Verbant de gebruiker met de gegeven id",
"Blacklisted": "Op de zwarte lijst",
"Bug Report": "Bug report",
"Bulk Options": "Bulk opties",
"Call Timeout": "Gesprek time-out",
"Can't connect to homeserver - please check your connectivity and ensure your %(urlStart)s homeserver's SSL certificate %(urlEnd)s is trusted": "Kan niet met de homeserver verbinden - controleer alsjeblieft je verbinding en wees zeker dat je %(urlStart)s homeserver's SSL certificaat %(urlEnd)s vertrouwd wordt",
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or %(urlStart)s enable unsafe scripts %(urlEnd)s": "Kan niet met de homeserver verbinden via HTTP wanneer er een HTTPS URL in je browser balk staat. Gebruik HTTPS of %(urlStart)s activeer onveilige scripts %(urlEnd)s",
"Can't load user settings": "Kan de gebruiker instellingen niet laden",
"Change Password": "Wachtwoord veranderen",
"%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s heeft zijn of haar weergave naam veranderd van %(oldDisplayName)s naar %(displayName)s.",
"%(senderName)s changed their profile picture.": "%(senderName)s heeft zijn of haar profiel foto veranderd.",
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s heeft de rank van %(powerLevelDiffText)s gewijzigd.",
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s heeft de kamer naam van %(roomName)s gewijzigd.",
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s heeft het onderwerp gewijzigd naar \"%(topic)s\".",
"Changes to who can read history will only apply to future messages in this room": "Veranderingen aan wie de historie kan lezen worden alleen maar toegepast op toekomstige berichten in deze kamer",
"Changes your display nickname": "Verandert jouw weergavenaam",
"changing room on a RoomView is not supported": "veranderen van een kamer in een RoomView wordt niet ondersteund",
"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.": "Het veranderen van het wachtwoord zal op het moment alle eind-tot-eind encryptie sleutels resetten, wat alle versleutelde chat geschiedenis onleesbaar zou maken, behalve als je eerst je kamer sleutels exporteert en achteraf opnieuw importeert. Dit zal worden verbeterd in de toekomst.",
"Clear Cache and Reload": "Legen cache en herlaad",
"Clear Cache": "Legen cache",
"Click here": "Klik hier",
"Click here to fix": "Klik hier om op te lossen",
"Click to mute audio": "Klik om audio te dempen",
"Click to mute video": "Klik om de video te dempen",
"click to reveal": "klik om te laten zien",
"Click to unmute video": "Klik om de demping van de video op te heffen",
"Click to unmute audio": "Klik om het dempen van het geluid op te heffen",
"Command error": "Opdracht fout",
"Commands": "Opdrachten",
"Conference call failed": "Conferentie gesprek mislukt",
"Conference calling is in development and may not be reliable": "Conferentie gesprekken zijn nog in ontwikkelingen en kunnen onbetrouwbaar zijn",
"Conference calls are not supported in encrypted rooms": "Conferentie gesprekken worden niet ondersteunt in versleutelde kamers",
"Conference calls are not supported in this client": "Conferentie gesprekken worden niet ondersteunt in deze client",
"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"
}

View File

@ -20,7 +20,7 @@
"Anyone who knows the room's link, including guests": "Qualquer pessoa que tenha o link da sala, incluindo visitantes",
"Are you sure you want to leave the room?": "Você tem certeza que deseja sair da sala?",
"Are you sure you want to reject the invitation?": "Você tem certeza que deseja rejeitar este convite?",
"Are you sure you want upload the following files?": "Você tem certeza que deseja enviar os seguintes arquivos?",
"Are you sure you want to upload the following files?": "Você tem certeza que deseja enviar os seguintes arquivos?",
"banned": "baniu",
"Banned users": "Usuárias/os banidas/os",
"Bans user with given id": "Banir usuários com o identificador informado",

View File

@ -21,7 +21,7 @@
"Anyone who knows the room's link, including guests": "Qualquer pessoa que tenha o link da sala, incluindo visitantes",
"Are you sure you want to leave the room?": "Você tem certeza que deseja sair da sala?",
"Are you sure you want to reject the invitation?": "Você tem certeza que deseja rejeitar este convite?",
"Are you sure you want upload the following files?": "Você tem certeza que deseja enviar os seguintes arquivos?",
"Are you sure you want to upload the following files?": "Você tem certeza que deseja enviar os seguintes arquivos?",
"banned": "baniu",
"Banned users": "Usuárias/os banidas/os",
"Bans user with given id": "Banir usuários com o identificador informado",
@ -699,5 +699,52 @@
"%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)salteraram sua imagem pública %(repeats)s vezes",
"%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)salterou sua imagem pública %(repeats)s vezes",
"%(severalUsers)schanged their avatar": "%(severalUsers)salteraram sua imagem pública",
"Ban": "Banir"
"Ban": "Banir",
"A registered account is required for this action": "Uma conta registrada é necessária para esta ação",
"Access Token:": "Token de acesso:",
"Always show message timestamps": "Sempre mostrar as datas das mensagens",
"Authentication": "Autenticação",
"An error has occurred.": "Ocorreu um erro.",
"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.": "Alterar a senha irá atualmente apagar todas as chaves de criptografia ponta-a-ponta em todos os dispositivos, fazendo com que o histórico da conversa fique ilegível, a não ser que você exporte antes as chaves de sala e então as reimporte depois. No futuro, isso vai melhorar.",
"Email": "Email",
"Email address": "Endereço de email",
"Error decrypting attachment": "Erro ao descriptografar o anexo",
"Interface Language": "Idioma da interface",
"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",
"olm version:": "versão do olm:",
"Operation failed": "A operação falhou",
"Registration required": "Registro obrigatório",
"Remove %(threePid)s?": "Remover %(threePid)s?",
"Report it": "Reportar",
"riot-web version:": "versão do riot-web:",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar os horários em formato de 12h (p.ex: 2:30pm)",
"Unmute": "Tirar do mudo",
"Warning!": "Atenção!",
"You need to enter a user name.": "Você precisa inserir um nome de usuária(o).",
"Please select the destination room for this message": "Por favor, escolha a sala para onde quer encaminhar esta mensagem",
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s apagou o nome da sala.",
"Analytics": "Análise",
"Opt out of analytics": "Sair da ferramenta de análise",
"Riot collects anonymous analytics to allow us to improve the application.": "Riot coleta informações anônimas de uso para nos permitir melhorar o sistema.",
"Passphrases must match": "As senhas têm que ser iguais",
"Passphrase must not be empty": "A senha não pode estar vazia",
"Export room keys": "Exportar chaves de sala",
"Enter passphrase": "Entre com a senha",
"Confirm passphrase": "Confirme a senha",
"Import room keys": "Importar chaves de sala",
"File to import": "Arquivo para importar",
"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.": "Este processo permite que você exporte as chaves para mensagens que você recebeu em salas criptografadas para um arquivo local. Você poderá então importar o arquivo para outro cliente Matrix no futuro, de modo que este cliente também poderá descriptografar suas mensagens.",
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "O arquivo exportado será protegido com uma senha. Você deverá inserir a senha aqui para poder descriptografar o arquivo futuramente.",
"You must join the room to see its files": "Você precisa ingressar na sala para ver seus arquivos",
"Server may be unavailable, overloaded, or you hit a bug.": "O servidor pode estar indisponível ou sobrecarregado, ou então você encontrou uma falha no sistema.",
"Reject all %(invitedRooms)s invites": "Rejeitar todos os %(invitedRoom)s convites",
"Start new Chat": "Iniciar nova conversa",
"Guest users can't invite users. Please register.": "Visitantes não podem convidar usuárias(os) registradas(os). Favor registrar.",
"Failed to invite": "Falha ao enviar o convite",
"Failed to invite user": "Falha ao convidar a(o) usuária(o)",
"Failed to invite the following users to the %(roomName)s room:": "Falha ao convidar as(os) seguintes usuárias(os) para a sala %(roomName)s:",
"Confirm Removal": "Confirmar a remoção"
}

View File

@ -20,7 +20,7 @@
"Anyone who knows the room's link, apart from guests": "Любой, кто знает ссылку на комнату, кроме гостей",
"Anyone who knows the room's link, including guests": "Любой, кто знает ссылку комнаты, включая гостей",
"Are you sure you want to reject the invitation?": "Вы уверены что вы хотите отклонить приглашение?",
"Are you sure you want upload the following files?": "Вы уверены что вы хотите закачать следующий файл?",
"Are you sure you want to upload the following files?": "Вы уверены что вы хотите закачать следующий файл?",
"banned": "banned",
"Banned users": "Запрещенный пользователь",
"Bans user with given id": "Запретить пользователя с определенным id",

3
src/i18n/strings/te.json Normal file
View File

@ -0,0 +1,3 @@
{
"was invited": "తనని ఆహ్వానించారు"
}

View File

@ -0,0 +1,158 @@
{
"Create an account": "创建新账号",
"Create Room": "创建聊天室",
"Cryptography": "加密",
"Current password": "当前密码",
"/ddg is not a command": "/ddg 不是一个命令",
"Deactivate Account": "销毁账号",
"Deactivate my account": "销毁我的账号",
"decline": "拒绝",
"Decrypt %(text)s": "解密 %(text)s",
"Decryption error": "解密出错",
"Delete": "删除",
"Default": "默认",
"Device ID": "设备识别码",
"Devices": "设备列表",
"Devices will not yet be able to decrypt history from before they joined the room": "新加入聊天室的设备不能解密加入之前的聊天记录",
"Direct Chat": "私聊",
"Direct chats": "私聊",
"Disable inline URL previews by default": "默认禁用自动网址预览",
"Disinvite": "取消邀请",
"Display name": "显示名称",
"Displays action": "显示操作",
"Don't send typing notifications": "不要发送我的打字状态",
"Download %(text)s": "下载 %(text)s",
"Drop here %(toAction)s": "拖拽到这里 %(toAction)s",
"Email": "电子邮箱",
"Email address": "电子邮箱地址",
"Email, name or matrix ID": "电子邮箱姓名或者matrix ID",
"Emoji": "Emoji",
"Enable encryption": "启用加密",
"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 is in beta and may not be reliable": "端到端加密现为测试版,不一定可靠",
"Enter Code": "输入代码",
"Error": "错误",
"Error decrypting attachment": "解密附件时出错",
"Event information": "事件信息",
"Existing Call": "现有通话",
"Export E2E room keys": "导出聊天室的端到端加密密钥",
"Failed to ban user": "封禁用户失败",
"Failed to change password. Is your password correct?": "修改密码失败。确认原密码输入正确吗?",
"Failed to delete device": "删除设备失败",
"Failed to forget room %(errCode)s": "无法忘记聊天室 %(errCode)s",
"Failed to join room": "无法加入聊天室",
"Failed to join the room": "无法加入此聊天室",
"Failed to kick": "踢人失败",
"Failed to leave room": "无法离开聊天室",
"Failed to load timeline position": "无法加载时间轴位置",
"Failed to lookup current room": "找不到当前聊天室",
"Failed to mute user": "禁言用户失败",
"Failed to reject invite": "拒绝邀请失败",
"Failed to reject invitation": "拒绝邀请失败",
"Failed to save settings": "保存设置失败",
"Failed to send email": "发送邮件失败",
"Failed to send request.": "发送请求失败。",
"Failed to set avatar.": "设置头像失败。",
"Failed to set display name": "设置昵称失败",
"Failed to set up conference call": "无法启动群组通话",
"Failed to toggle moderator status": "无法切换管理员权限",
"Failed to unban": "解除封禁失败",
"Failed to upload file": "上传文件失败",
"Failed to verify email address: make sure you clicked the link in the email": "邮箱验证失败: 请确保你已点击邮件中的链接",
"Failure to create room": "创建聊天室失败",
"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.": "出于安全考虑,用户注销时会清除浏览器里的端到端加密密钥。如果你想要下次登录 Riot 时能解密过去的聊天记录,请导出你的聊天室密钥。",
"Found a bug?": "发现漏洞?",
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s 从 %(fromPowerLevel)s 变为 %(toPowerLevel)s",
"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 upload files. Please register to upload": "游客不能上传文件。请注册以上传文件",
"Guests can't use labs features. Please register.": "游客不能使用实验性功能。请注册。",
"Guests cannot join this room even if explicitly invited.": "游客不能加入此聊天室,即使有人主动邀请。",
"had": "已经",
"Hangup": "挂断",
"Hide read receipts": "隐藏已读回执",
"Hide Text Formatting Toolbar": "隐藏格式工具栏",
"Historical": "历史",
"Homeserver is": "主服务器是",
"Identity Server is": "身份认证服务器是",
"I have verified my email address": "我已经验证了我的邮箱地址",
"Import E2E room keys": "导入聊天室端对端加密密钥",
"Incorrect verification code": "验证码错误",
"Interface Language": "界面语言",
"Invalid alias format": "别名格式错误",
"Invalid address format": "地址格式错误",
"Invalid Email Address": "邮箱地址格式错误",
"Invalid file%(extra)s": "非法文件%(extra)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.": "重设密码会导致所有设备上的端到端加密密钥被重置,使得加密的聊天记录不可读,除非你事先导出密钥,修改密码后再导入。此问题将来会得到改善。",
"restore": "恢复",
"Return to app": "返回 App",
"Return to login screen": "返回登录页面",
"Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允许向你推送消息 - 请检查浏览器设置",
"Riot was not given permission to send notifications - please try again": "Riot 未被允许推送消息通知 - 请重试",
"riot-web version:": "riot-网页版:",
"Room %(roomId)s not visible": "聊天室 %(roomId)s 已隐藏",
"Room Colour": "聊天室颜色",
"Room name (optional)": "聊天室名称 (可选)",
"Rooms": "聊天室",
"Scroll to bottom of page": "滚动到页面底部",
"Scroll to unread messages": "滚动到未读消息",
"Search": "搜索",
"Search failed": "搜索失败",
"Searches DuckDuckGo for results": "搜索 DuckDuckGo",
"Send a message (unencrypted)": "发送消息 (非加密)",
"Send an encrypted message": "发送加密消息",
"Sender device information": "发送者的设备信息",
"Send Invites": "发送邀请",
"Send Reset Email": "发送密码重设邮件",
"sent an image": "发了一张图片",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s 发了一张图片。",
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s 向 %(targetDisplayName)s 发了加入聊天室的邀请。",
"sent a video": "发了一个视频",
"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。",
"Settings": "设置",
"Show panel": "显示侧边栏",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "用12小时制显示时间戳 (如:下午 2:30",
"Signed Out": "已退出登录",
"Sign in": "登录",
"Sign out": "注销",
"since the point in time of selecting this option": "从选择此选项起",
"since they joined": "从他们加入时起",
"since they were invited": "从他们被邀请时起",
"Some of your messages have not been sent": "部分消息发送失败",
"Someone": "某个用户",
"Sorry, this homeserver is using a login which is not recognised ": "很抱歉,无法识别此主服务器使用的登录方式 ",
"Start a chat": "创建聊天",
"Start Chat": "开始聊天",
"Submit": "提交",
"Success": "成功",
"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 email address is already in use": "此邮箱地址已经被使用",
"This email address was not found": "未找到此邮箱地址",
"%(actionVerb)s this person?": "%(actionVerb)s 这个用户?",
"The email address linked to your account must be entered.": "必须输入和你账号关联的邮箱地址。",
"The file '%(fileName)s' exceeds this home server's size limit for uploads": "文件 '%(fileName)s' 超过了此主服务器的上传大小限制",
"The file '%(fileName)s' failed to upload": "文件 '%(fileName)s' 上传失败",
"Guests can't use labs features. Please register.": "游客不能使用实验性功能。请注册。"
}

View File

@ -7,7 +7,7 @@
"Anyone who knows the room's link, including guests": "任何知道房間連結的人,包括訪客",
"Are you sure?": "您確認嗎?",
"Are you sure you want to reject the invitation?": "您確認要謝絕邀請嗎?",
"Are you sure you want upload the following files?": "您確認要上傳以下文件嗎?",
"Are you sure you want to upload the following files?": "您確認要上傳以下文件嗎?",
"Attachment": "附件",
"Autoplay GIFs and videos": "自動播放GIF和影片",
"%(senderName)s banned %(targetName)s.": "%(senderName)s 封禁了 %(targetName)s。",

View File

@ -18,6 +18,7 @@ limitations under the License.
import request from 'browser-request';
import counterpart from 'counterpart';
import q from 'q';
import sanitizeHtml from "sanitize-html";
import UserSettingsStore from './UserSettingsStore';
@ -37,6 +38,80 @@ export function _t(...args) {
return counterpart.translate(...args);
}
/*
* Translates stringified JSX into translated JSX. E.g
* _tJsx(
* "click <a href=''>here</a> now",
* /<a href=''>(.*?)<\/a>/,
* (sub) => { return <a href=''>{ sub }</a>; }
* );
*
* @param {string} jsxText The untranslated stringified JSX e.g "click <a href=''>here</a> now".
* This will be translated by passing the string through to _t(...)
*
* @param {RegExp|RegExp[]} patterns A regexp to match against the translated text.
* The captured groups from the regexp will be fed to 'sub'.
* Only the captured groups will be included in the output, the match itself is discarded.
* If multiple RegExps are provided, the function at the same position will be called. The
* match will always be done from left to right, so the 2nd RegExp will be matched against the
* remaining text from the first RegExp.
*
* @param {Function|Function[]} subs A function which will be called
* with multiple args, each arg representing a captured group of the matching regexp.
* This function must return a JSX node.
*
* @return A list of strings/JSX nodes.
*/
export function _tJsx(jsxText, patterns, subs) {
// convert everything to arrays
if (patterns instanceof RegExp) {
patterns = [patterns];
}
if (subs instanceof Function) {
subs = [subs];
}
// sanity checks
if (subs.length !== patterns.length || subs.length < 1) {
throw new Error(`_tJsx: programmer error. expected number of RegExps == number of Functions: ${subs.length} != ${patterns.length}`);
}
for (let i = 0; i < subs.length; i++) {
if (!patterns[i] instanceof RegExp) {
throw new Error(`_tJsx: programmer error. expected RegExp for text: ${jsxText}`);
}
if (!subs[i] instanceof Function) {
throw new Error(`_tJsx: programmer error. expected Function for text: ${jsxText}`);
}
}
// tJsxText may be unsafe if malicious translators try to inject HTML.
// Run this through sanitize-html and bail if the output isn't identical
const tJsxText = _t(jsxText);
const sanitized = sanitizeHtml(tJsxText, { allowedTags: sanitizeHtml.defaults.allowedTags.concat([ 'span' ]) });
if (tJsxText !== sanitized) {
throw new Error(`_tJsx: translator error. untrusted HTML supplied. '${tJsxText}' != '${sanitized}'`);
}
let output = [tJsxText];
for (let i = 0; i < patterns.length; i++) {
// convert the last element in 'output' into 3 elements (pre-text, sub function, post-text).
// Rinse and repeat for other patterns (using post-text).
let inputText = output.pop();
let match = inputText.match(patterns[i]);
if (!match) {
throw new Error(`_tJsx: translator error. expected translation to match regexp: ${patterns[i]}`);
}
let capturedGroups = match.slice(1);
// Return the raw translation before the *match* followed by the return value of sub() followed
// by the raw translation after the *match* (not captured group).
output.push(inputText.substr(0, match.index));
output.push(subs[i].apply(null, capturedGroups));
output.push(inputText.substr(match.index + match[0].length));
}
return output;
}
// Allow overriding the text displayed when no translation exists
// Currently only use din unit tests to avoid having to load
// the translations in riot-web
@ -87,10 +162,10 @@ export function getAllLanguageKeysFromJson() {
}
export function getLanguagesFromBrowser() {
if (navigator.languages) return navigator.languages;
if (navigator.language) return [navigator.language]
if (navigator.languages && navigator.languages.length) return navigator.languages;
if (navigator.language) return [navigator.language];
return [navigator.userLanguage];
};
}
/**
* Turns a language string, normalises it,