Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
d305f8aacb
39 changed files with 277 additions and 125 deletions
|
@ -6,7 +6,6 @@ src/autocomplete/Autocompleter.js
|
|||
src/autocomplete/Components.js
|
||||
src/autocomplete/DuckDuckGoProvider.js
|
||||
src/autocomplete/EmojiProvider.js
|
||||
src/autocomplete/RoomProvider.js
|
||||
src/autocomplete/UserProvider.js
|
||||
src/CallHandler.js
|
||||
src/component-index.js
|
||||
|
@ -35,7 +34,6 @@ src/components/views/create_room/RoomAlias.js
|
|||
src/components/views/dialogs/ChatCreateOrReuseDialog.js
|
||||
src/components/views/dialogs/DeactivateAccountDialog.js
|
||||
src/components/views/dialogs/InteractiveAuthDialog.js
|
||||
src/components/views/dialogs/SetMxIdDialog.js
|
||||
src/components/views/dialogs/UnknownDeviceDialog.js
|
||||
src/components/views/elements/AccessibleButton.js
|
||||
src/components/views/elements/ActionButton.js
|
||||
|
@ -89,7 +87,6 @@ src/components/views/rooms/MemberList.js
|
|||
src/components/views/rooms/MemberTile.js
|
||||
src/components/views/rooms/MessageComposer.js
|
||||
src/components/views/rooms/MessageComposerInput.js
|
||||
src/components/views/rooms/MessageComposerInputOld.js
|
||||
src/components/views/rooms/PresenceLabel.js
|
||||
src/components/views/rooms/ReadReceiptMarker.js
|
||||
src/components/views/rooms/RoomList.js
|
||||
|
@ -100,7 +97,6 @@ src/components/views/rooms/RoomTile.js
|
|||
src/components/views/rooms/RoomTopicEditor.js
|
||||
src/components/views/rooms/SearchableEntityList.js
|
||||
src/components/views/rooms/SearchResultTile.js
|
||||
src/components/views/rooms/TabCompleteBar.js
|
||||
src/components/views/rooms/TopUnreadMessagesBar.js
|
||||
src/components/views/rooms/UserTile.js
|
||||
src/components/views/settings/AddPhoneNumber.js
|
||||
|
@ -128,8 +124,6 @@ src/Roles.js
|
|||
src/Rooms.js
|
||||
src/ScalarAuthClient.js
|
||||
src/ScalarMessaging.js
|
||||
src/TabComplete.js
|
||||
src/TabCompleteEntries.js
|
||||
src/TextForEvent.js
|
||||
src/Tinter.js
|
||||
src/UiEffects.js
|
||||
|
@ -142,7 +136,7 @@ src/utils/Receipt.js
|
|||
src/Velociraptor.js
|
||||
src/VelocityBounce.js
|
||||
src/WhoIsTyping.js
|
||||
src/wrappers/WithMatrixClient.js
|
||||
src/wrappers/withMatrixClient.js
|
||||
test/all-tests.js
|
||||
test/components/structures/login/Registration-test.js
|
||||
test/components/structures/MessagePanel-test.js
|
||||
|
|
73
CHANGELOG.md
73
CHANGELOG.md
|
@ -1,3 +1,76 @@
|
|||
Changes in [0.10.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.2) (2017-08-24)
|
||||
=====================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.1...v0.10.2)
|
||||
|
||||
* Force update on timelinepanel when event decrypted
|
||||
[\#1334](https://github.com/matrix-org/matrix-react-sdk/pull/1334)
|
||||
* Dispatch incoming_call synchronously
|
||||
[\#1337](https://github.com/matrix-org/matrix-react-sdk/pull/1337)
|
||||
* Fix React crying on machines without internet due to return undefined
|
||||
[\#1335](https://github.com/matrix-org/matrix-react-sdk/pull/1335)
|
||||
* Catch the promise rejection if scalar fails
|
||||
[\#1333](https://github.com/matrix-org/matrix-react-sdk/pull/1333)
|
||||
* Update from Weblate.
|
||||
[\#1329](https://github.com/matrix-org/matrix-react-sdk/pull/1329)
|
||||
|
||||
Changes in [0.10.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.1) (2017-08-23)
|
||||
=====================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.1-rc.1...v0.10.1)
|
||||
|
||||
* [No changes]
|
||||
|
||||
Changes in [0.10.1-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.1-rc.1) (2017-08-22)
|
||||
===============================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.0-rc.2...v0.10.1-rc.1)
|
||||
|
||||
* Matthew/multiple widgets
|
||||
[\#1327](https://github.com/matrix-org/matrix-react-sdk/pull/1327)
|
||||
* Fix proptypes on UserPickerDialog
|
||||
[\#1326](https://github.com/matrix-org/matrix-react-sdk/pull/1326)
|
||||
* AppsDrawer: Remove unnecessary bind
|
||||
[\#1325](https://github.com/matrix-org/matrix-react-sdk/pull/1325)
|
||||
* Position add app widget link
|
||||
[\#1322](https://github.com/matrix-org/matrix-react-sdk/pull/1322)
|
||||
* Remove app tile beta tag.
|
||||
[\#1323](https://github.com/matrix-org/matrix-react-sdk/pull/1323)
|
||||
* Add missing translation.
|
||||
[\#1324](https://github.com/matrix-org/matrix-react-sdk/pull/1324)
|
||||
* Note that apps are not E2EE
|
||||
[\#1319](https://github.com/matrix-org/matrix-react-sdk/pull/1319)
|
||||
* Only render appTile body (including warnings) if drawer shown.
|
||||
[\#1321](https://github.com/matrix-org/matrix-react-sdk/pull/1321)
|
||||
* Timeline improvements
|
||||
[\#1320](https://github.com/matrix-org/matrix-react-sdk/pull/1320)
|
||||
* Add a space between widget name and "widget" in widget event tiles
|
||||
[\#1318](https://github.com/matrix-org/matrix-react-sdk/pull/1318)
|
||||
* Move manage integrations button from settings page to room header as a
|
||||
stand-alone component
|
||||
[\#1286](https://github.com/matrix-org/matrix-react-sdk/pull/1286)
|
||||
* Don't apply case logic to app names
|
||||
[\#1316](https://github.com/matrix-org/matrix-react-sdk/pull/1316)
|
||||
* Stop integ manager opening on every room switch
|
||||
[\#1315](https://github.com/matrix-org/matrix-react-sdk/pull/1315)
|
||||
* Add behaviour to toggle app draw on app tile header click
|
||||
[\#1313](https://github.com/matrix-org/matrix-react-sdk/pull/1313)
|
||||
* Change OOO so that MELS generation will continue over hidden events
|
||||
[\#1308](https://github.com/matrix-org/matrix-react-sdk/pull/1308)
|
||||
* Implement TextualEvent tiles for im.vector.modular.widgets
|
||||
[\#1312](https://github.com/matrix-org/matrix-react-sdk/pull/1312)
|
||||
* Don't show widget security warning to the person that added it to the room
|
||||
[\#1314](https://github.com/matrix-org/matrix-react-sdk/pull/1314)
|
||||
* remove unused strings introduced by string change
|
||||
[\#1311](https://github.com/matrix-org/matrix-react-sdk/pull/1311)
|
||||
* hotfix bad fn signature regression
|
||||
[\#1310](https://github.com/matrix-org/matrix-react-sdk/pull/1310)
|
||||
* Show a dialog if the maximum number of widgets allowed has been reached.
|
||||
[\#1291](https://github.com/matrix-org/matrix-react-sdk/pull/1291)
|
||||
* Fix Robot translation
|
||||
[\#1309](https://github.com/matrix-org/matrix-react-sdk/pull/1309)
|
||||
* Refactor ChatInviteDialog to be UserPickerDialog
|
||||
[\#1300](https://github.com/matrix-org/matrix-react-sdk/pull/1300)
|
||||
* Update Link to Translation status
|
||||
[\#1302](https://github.com/matrix-org/matrix-react-sdk/pull/1302)
|
||||
|
||||
Changes in [0.9.7](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.7) (2017-06-22)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.6...v0.9.7)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "matrix-react-sdk",
|
||||
"version": "0.9.7",
|
||||
"version": "0.10.2",
|
||||
"description": "SDK for matrix.org using React",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
|
@ -66,7 +66,7 @@
|
|||
"isomorphic-fetch": "^2.2.1",
|
||||
"linkifyjs": "^2.1.3",
|
||||
"lodash": "^4.13.1",
|
||||
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-js-sdk": "0.8.2",
|
||||
"optimist": "^0.6.1",
|
||||
"prop-types": "^15.5.8",
|
||||
"react": "^15.4.0",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -33,9 +34,16 @@ import Modal from './Modal';
|
|||
* }
|
||||
*/
|
||||
|
||||
const MAX_PENDING_ENCRYPTED = 20;
|
||||
|
||||
const Notifier = {
|
||||
notifsByRoom: {},
|
||||
|
||||
// A list of event IDs that we've received but need to wait until
|
||||
// they're decrypted until we decide whether to notify for them
|
||||
// or not
|
||||
pendingEncryptedEventIds: [],
|
||||
|
||||
notificationMessageForEvent: function(ev) {
|
||||
return TextForEvent.textForEvent(ev);
|
||||
},
|
||||
|
@ -89,17 +97,18 @@ const Notifier = {
|
|||
_playAudioNotification: function(ev, room) {
|
||||
const e = document.getElementById("messageAudio");
|
||||
if (e) {
|
||||
e.load();
|
||||
e.play();
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
|
||||
this.boundOnEvent = this.onEvent.bind(this);
|
||||
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
|
||||
this.boundOnRoomReceipt = this.onRoomReceipt.bind(this);
|
||||
MatrixClientPeg.get().on('Room.timeline', this.boundOnRoomTimeline);
|
||||
this.boundOnEventDecrypted = this.onEventDecrypted.bind(this);
|
||||
MatrixClientPeg.get().on('event', this.boundOnEvent);
|
||||
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
|
||||
MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted);
|
||||
MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange);
|
||||
this.toolbarHidden = false;
|
||||
this.isSyncing = false;
|
||||
|
@ -107,8 +116,9 @@ const Notifier = {
|
|||
|
||||
stop: function() {
|
||||
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) {
|
||||
MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
|
||||
MatrixClientPeg.get().removeListener('Event', this.boundOnEvent);
|
||||
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
|
||||
MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted);
|
||||
MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange);
|
||||
}
|
||||
this.isSyncing = false;
|
||||
|
@ -237,23 +247,30 @@ const Notifier = {
|
|||
}
|
||||
},
|
||||
|
||||
onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) {
|
||||
if (toStartOfTimeline) return;
|
||||
if (!room) return;
|
||||
onEvent: function(ev) {
|
||||
if (!this.isSyncing) return; // don't alert for any messages initially
|
||||
if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return;
|
||||
if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return;
|
||||
|
||||
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
|
||||
if (actions && actions.notify) {
|
||||
if (this.isEnabled()) {
|
||||
this._displayPopupNotification(ev, room);
|
||||
}
|
||||
if (actions.tweaks.sound && this.isAudioEnabled()) {
|
||||
PlatformPeg.get().loudNotification(ev, room);
|
||||
this._playAudioNotification(ev, room);
|
||||
// If it's an encrypted event and the type is still 'm.room.encrypted',
|
||||
// it hasn't yet been decrypted, so wait until it is.
|
||||
if (ev.isBeingDecrypted() || ev.isDecryptionFailure()) {
|
||||
this.pendingEncryptedEventIds.push(ev.getId());
|
||||
// don't let the list fill up indefinitely
|
||||
while (this.pendingEncryptedEventIds.length > MAX_PENDING_ENCRYPTED) {
|
||||
this.pendingEncryptedEventIds.shift();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._evaluateEvent(ev);
|
||||
},
|
||||
|
||||
onEventDecrypted: function(ev) {
|
||||
const idx = this.pendingEncryptedEventIds.indexOf(ev.getId());
|
||||
if (idx === -1) return;
|
||||
|
||||
this.pendingEncryptedEventIds.splice(idx, 1);
|
||||
this._evaluateEvent(ev);
|
||||
},
|
||||
|
||||
onRoomReceipt: function(ev, room) {
|
||||
|
@ -273,6 +290,20 @@ const Notifier = {
|
|||
delete this.notifsByRoom[room.roomId];
|
||||
}
|
||||
},
|
||||
|
||||
_evaluateEvent: function(ev) {
|
||||
const room = MatrixClientPeg.get().getRoom(ev.getRoomId());
|
||||
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
|
||||
if (actions && actions.notify) {
|
||||
if (this.isEnabled()) {
|
||||
this._displayPopupNotification(ev, room);
|
||||
}
|
||||
if (actions.tweaks.sound && this.isAudioEnabled()) {
|
||||
PlatformPeg.get().loudNotification(ev, room);
|
||||
this._playAudioNotification(ev, room);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!global.mxNotifier) {
|
||||
|
|
|
@ -244,15 +244,16 @@ function textForPowerEvent(event) {
|
|||
}
|
||||
return _t('%(senderName)s changed the power level of %(powerLevelDiffText)s.', {
|
||||
senderName: senderName,
|
||||
powerLevelDiffText: diff.join(", ")
|
||||
powerLevelDiffText: diff.join(", "),
|
||||
});
|
||||
}
|
||||
|
||||
function textForWidgetEvent(event) {
|
||||
const senderName = event.sender ? event.sender.name : event.getSender();
|
||||
const previousContent = event.getPrevContent() || {};
|
||||
const senderName = event.getSender();
|
||||
const {name: prevName, type: prevType, url: prevUrl} = event.getPrevContent();
|
||||
const {name, type, url} = event.getContent() || {};
|
||||
let widgetName = name || previousContent.name || type || previousContent.type || '';
|
||||
|
||||
let widgetName = name || prevName || type || prevType || '';
|
||||
// Apply sentence case to widget name
|
||||
if (widgetName && widgetName.length > 0) {
|
||||
widgetName = widgetName[0].toUpperCase() + widgetName.slice(1) + ' ';
|
||||
|
@ -261,9 +262,15 @@ function textForWidgetEvent(event) {
|
|||
// If the widget was removed, its content should be {}, but this is sufficiently
|
||||
// equivalent to that condition.
|
||||
if (url) {
|
||||
return _t('%(widgetName)s widget added by %(senderName)s', {
|
||||
widgetName, senderName,
|
||||
});
|
||||
if (prevUrl) {
|
||||
return _t('%(widgetName)s widget modified by %(senderName)s', {
|
||||
widgetName, senderName,
|
||||
});
|
||||
} else {
|
||||
return _t('%(widgetName)s widget added by %(senderName)s', {
|
||||
widgetName, senderName,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return _t('%(widgetName)s widget removed by %(senderName)s', {
|
||||
widgetName, senderName,
|
||||
|
|
|
@ -1068,10 +1068,13 @@ module.exports = React.createClass({
|
|||
self.setState({ready: true});
|
||||
});
|
||||
cli.on('Call.incoming', function(call) {
|
||||
// we dispatch this synchronously to make sure that the event
|
||||
// handlers on the call are set up immediately (so that if
|
||||
// we get an immediate hangup, we don't get a stuck call)
|
||||
dis.dispatch({
|
||||
action: 'incoming_call',
|
||||
call: call,
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
cli.on('Session.logged_out', function(call) {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
|
|
|
@ -65,7 +65,7 @@ module.exports = React.createClass({
|
|||
suppressFirstDateSeparator: React.PropTypes.bool,
|
||||
|
||||
// whether to show read receipts
|
||||
manageReadReceipts: React.PropTypes.bool,
|
||||
showReadReceipts: React.PropTypes.bool,
|
||||
|
||||
// true if updates to the event list should cause the scroll panel to
|
||||
// scroll down when we are at the bottom of the window. See ScrollPanel
|
||||
|
@ -491,7 +491,7 @@ module.exports = React.createClass({
|
|||
var scrollToken = mxEv.status ? undefined : eventId;
|
||||
|
||||
var readReceipts;
|
||||
if (this.props.manageReadReceipts) {
|
||||
if (this.props.showReadReceipts) {
|
||||
readReceipts = this._getReadReceiptsForEvent(mxEv);
|
||||
}
|
||||
ret.push(
|
||||
|
|
|
@ -20,6 +20,8 @@ limitations under the License.
|
|||
// - Drag and drop
|
||||
// - File uploading - uploadFile()
|
||||
|
||||
import shouldHideEvent from "../../shouldHideEvent";
|
||||
|
||||
var React = require("react");
|
||||
var ReactDOM = require("react-dom");
|
||||
import Promise from 'bluebird';
|
||||
|
@ -143,6 +145,8 @@ module.exports = React.createClass({
|
|||
MatrixClientPeg.get().on("RoomMember.membership", this.onRoomMemberMembership);
|
||||
MatrixClientPeg.get().on("accountData", this.onAccountData);
|
||||
|
||||
this._syncedSettings = UserSettingsStore.getSyncedSettings();
|
||||
|
||||
// Start listening for RoomViewStore updates
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._onRoomViewStoreUpdate(true);
|
||||
|
@ -497,8 +501,7 @@ module.exports = React.createClass({
|
|||
// update unread count when scrolled up
|
||||
if (!this.state.searchResults && this.state.atEndOfLiveTimeline) {
|
||||
// no change
|
||||
}
|
||||
else {
|
||||
} else if (!shouldHideEvent(ev, this._syncedSettings)) {
|
||||
this.setState((state, props) => {
|
||||
return {numUnreadMessages: state.numUnreadMessages + 1};
|
||||
});
|
||||
|
@ -1716,7 +1719,8 @@ module.exports = React.createClass({
|
|||
var messagePanel = (
|
||||
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
||||
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
||||
manageReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||
showReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||
manageReadReceipts={true}
|
||||
manageReadMarkers={true}
|
||||
hidden={hideMessagePanel}
|
||||
highlightedEventId={highlightedEventId}
|
||||
|
|
|
@ -59,6 +59,7 @@ var TimelinePanel = React.createClass({
|
|||
// that room.
|
||||
timelineSet: React.PropTypes.object.isRequired,
|
||||
|
||||
showReadReceipts: React.PropTypes.bool,
|
||||
// Enable managing RRs and RMs. These require the timelineSet to have a room.
|
||||
manageReadReceipts: React.PropTypes.bool,
|
||||
manageReadMarkers: React.PropTypes.bool,
|
||||
|
@ -197,6 +198,7 @@ var TimelinePanel = React.createClass({
|
|||
MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt);
|
||||
MatrixClientPeg.get().on("Room.localEchoUpdated", this.onLocalEchoUpdated);
|
||||
MatrixClientPeg.get().on("Room.accountData", this.onAccountData);
|
||||
MatrixClientPeg.get().on("Event.decrypted", this.onEventDecrypted);
|
||||
MatrixClientPeg.get().on("sync", this.onSync);
|
||||
|
||||
this._initTimeline(this.props);
|
||||
|
@ -266,6 +268,7 @@ var TimelinePanel = React.createClass({
|
|||
client.removeListener("Room.receipt", this.onRoomReceipt);
|
||||
client.removeListener("Room.localEchoUpdated", this.onLocalEchoUpdated);
|
||||
client.removeListener("Room.accountData", this.onAccountData);
|
||||
client.removeListener("Event.decrypted", this.onEventDecrypted);
|
||||
client.removeListener("sync", this.onSync);
|
||||
}
|
||||
},
|
||||
|
@ -341,9 +344,16 @@ var TimelinePanel = React.createClass({
|
|||
newState[canPaginateOtherWayKey] = true;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
|
||||
return r;
|
||||
// Don't resolve until the setState has completed: we need to let
|
||||
// the component update before we consider the pagination completed,
|
||||
// otherwise we'll end up paginating in all the history the js-sdk
|
||||
// has in memory because we never gave the component a chance to scroll
|
||||
// itself into the right place
|
||||
return new Promise((resolve) => {
|
||||
this.setState(newState, () => {
|
||||
resolve(r);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -503,6 +513,18 @@ var TimelinePanel = React.createClass({
|
|||
}, this.props.onReadMarkerUpdated);
|
||||
},
|
||||
|
||||
onEventDecrypted: function(ev) {
|
||||
// Need to update as we don't display event tiles for events that
|
||||
// haven't yet been decrypted. The event will have just been updated
|
||||
// in place so we just need to re-render.
|
||||
// TODO: We should restrict this to only events in our timeline,
|
||||
// but possibly the event tile itself should just update when this
|
||||
// happens to save us re-rendering the whole timeline.
|
||||
if (ev.getRoomId() === this.props.timelineSet.room.roomId) {
|
||||
this.forceUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
onSync: function(state, prevState, data) {
|
||||
this.setState({clientSyncState: state});
|
||||
},
|
||||
|
@ -1126,8 +1148,8 @@ var TimelinePanel = React.createClass({
|
|||
readMarkerEventId={ this.state.readMarkerEventId }
|
||||
readMarkerVisible={ this.state.readMarkerVisible }
|
||||
suppressFirstDateSeparator={ this.state.canBackPaginate }
|
||||
showUrlPreview = { this.props.showUrlPreview }
|
||||
manageReadReceipts = { this.props.manageReadReceipts }
|
||||
showUrlPreview={ this.props.showUrlPreview }
|
||||
showReadReceipts={ this.props.showReadReceipts }
|
||||
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
||||
stickyBottom={ stickyBottom }
|
||||
onScroll={ this.onMessageListScroll }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -136,16 +137,15 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
onHsUrlChanged: function(newHsUrl) {
|
||||
this.setState({
|
||||
enteredHomeserverUrl: newHsUrl
|
||||
});
|
||||
},
|
||||
|
||||
onIsUrlChanged: function(newIsUrl) {
|
||||
this.setState({
|
||||
enteredIdentityServerUrl: newIsUrl
|
||||
});
|
||||
onServerConfigChange: function(config) {
|
||||
const newState = {};
|
||||
if (config.hsUrl !== undefined) {
|
||||
newState.enteredHomeserverUrl = config.hsUrl;
|
||||
}
|
||||
if (config.isUrl !== undefined) {
|
||||
newState.enteredIdentityServerUrl = config.isUrl;
|
||||
}
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
showErrorDialog: function(body, title) {
|
||||
|
@ -170,7 +170,7 @@ module.exports = React.createClass({
|
|||
else if (this.state.progress === "sent_email") {
|
||||
resetPasswordJsx = (
|
||||
<div>
|
||||
{ _t('An email has been sent to') } {this.state.email}. { _t('Once you've followed the link it contains, click below') }.
|
||||
{ _t('An email has been sent to') } {this.state.email}. { _t("Once you've followed the link it contains, click below") }.
|
||||
<br />
|
||||
<input className="mx_Login_submit" type="button" onClick={this.onVerify}
|
||||
value={ _t('I have verified my email address') } />
|
||||
|
@ -221,8 +221,7 @@ module.exports = React.createClass({
|
|||
defaultIsUrl={this.props.defaultIsUrl}
|
||||
customHsUrl={this.props.customHsUrl}
|
||||
customIsUrl={this.props.customIsUrl}
|
||||
onHsUrlChanged={this.onHsUrlChanged}
|
||||
onIsUrlChanged={this.onIsUrlChanged}
|
||||
onServerConfigChange={this.onServerConfigChange}
|
||||
delayTimeMs={0}/>
|
||||
<div className="mx_Login_error">
|
||||
</div>
|
||||
|
|
|
@ -72,8 +72,17 @@ export default React.createClass({
|
|||
|
||||
// Returns true if props.url is a scalar URL, typically https://scalar.vector.im/api
|
||||
isScalarUrl: function() {
|
||||
const scalarUrl = SdkConfig.get().integrations_rest_url;
|
||||
return scalarUrl && this.props.url.startsWith(scalarUrl);
|
||||
let scalarUrls = SdkConfig.get().integrations_widgets_urls;
|
||||
if (!scalarUrls || scalarUrls.length == 0) {
|
||||
scalarUrls = [SdkConfig.get().integrations_rest_url];
|
||||
}
|
||||
|
||||
for (let i = 0; i < scalarUrls.length; i++) {
|
||||
if (this.props.url.startsWith(scalarUrls[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
isMixedContent: function() {
|
||||
|
|
|
@ -75,7 +75,7 @@ export default class ManageIntegsButton extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
let integrationsButton;
|
||||
let integrationsButton = <div />;
|
||||
let integrationsError;
|
||||
if (this.scalarClient !== null) {
|
||||
if (this.state.showIntegrationsError && this.state.scalarError) {
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
var DIV_ID = 'mx_recaptcha';
|
||||
|
@ -66,11 +67,10 @@ module.exports = React.createClass({
|
|||
// * jumping straight to a hosted captcha page (but we don't support that yet)
|
||||
// * embedding the captcha in an iframe (if that works)
|
||||
// * using a better captcha lib
|
||||
warning.innerHTML = _tJsx(
|
||||
"Robot check is currently unavailable on desktop - please use a <a>web browser</a>",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return "<a href='https://riot.im/app'>{ sub }</a>"; }
|
||||
);
|
||||
ReactDOM.render(_tJsx(
|
||||
"Robot check is currently unavailable on desktop - please use a <a>web browser</a>",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }), warning);
|
||||
this.refs.recaptchaContainer.appendChild(warning);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -53,14 +53,14 @@ module.exports = React.createClass({
|
|||
this.scalarClient = null;
|
||||
if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) {
|
||||
this.scalarClient = new ScalarAuthClient();
|
||||
this.scalarClient.connect().done(() => {
|
||||
this.scalarClient.connect().then(() => {
|
||||
this.forceUpdate();
|
||||
// TODO -- Handle Scalar errors
|
||||
// },
|
||||
// (err) => {
|
||||
// this.setState({
|
||||
// scalar_error: err,
|
||||
// });
|
||||
}).catch((e) => {
|
||||
console.log("Failed to connect to integrations server");
|
||||
// TODO -- Handle Scalar errors
|
||||
// this.setState({
|
||||
// scalar_error: err,
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,6 @@ export default class Autocomplete extends React.Component {
|
|||
return null;
|
||||
}
|
||||
this.setSelection(selectionOffset);
|
||||
return selectionOffset === COMPOSER_SELECTED ? null : this.state.completionList[selectionOffset - 1];
|
||||
}
|
||||
|
||||
// called from MessageComposerInput
|
||||
|
@ -155,7 +154,6 @@ export default class Autocomplete extends React.Component {
|
|||
return null;
|
||||
}
|
||||
this.setSelection(selectionOffset);
|
||||
return selectionOffset === COMPOSER_SELECTED ? null : this.state.completionList[selectionOffset - 1];
|
||||
}
|
||||
|
||||
onEscape(e): boolean {
|
||||
|
@ -201,6 +199,9 @@ export default class Autocomplete extends React.Component {
|
|||
|
||||
setSelection(selectionOffset: number) {
|
||||
this.setState({selectionOffset, hide: false});
|
||||
if (this.props.onSelectionChange) {
|
||||
this.props.onSelectionChange(this.state.completionList[selectionOffset - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
|
|
@ -949,8 +949,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
};
|
||||
|
||||
moveAutocompleteSelection = (up) => {
|
||||
const completion = up ? this.autocomplete.onUpArrow() : this.autocomplete.onDownArrow();
|
||||
return this.setDisplayedCompletion(completion);
|
||||
up ? this.autocomplete.onUpArrow() : this.autocomplete.onDownArrow();
|
||||
};
|
||||
|
||||
onEscape = async (e) => {
|
||||
|
@ -1133,6 +1132,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
<Autocomplete
|
||||
ref={(e) => this.autocomplete = e}
|
||||
onConfirm={this.setDisplayedCompletion}
|
||||
onSelectionChange={this.setDisplayedCompletion}
|
||||
query={this.getAutocompleteQuery(content)}
|
||||
selection={selection}/>
|
||||
</div>
|
||||
|
|
|
@ -123,7 +123,19 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
var newElement = ReactDOM.findDOMNode(this);
|
||||
var startTopOffset = oldTop - newElement.offsetParent.getBoundingClientRect().top;
|
||||
let startTopOffset;
|
||||
if (!newElement.offsetParent) {
|
||||
// this seems to happen sometimes for reasons I don't understand
|
||||
// the docs for `offsetParent` say it may be null if `display` is
|
||||
// `none`, but I can't see why that would happen.
|
||||
console.warn(
|
||||
`ReadReceiptMarker for ${this.props.member.userId} in ` +
|
||||
`${this.props.member.roomId} has no offsetParent`,
|
||||
);
|
||||
startTopOffset = 0;
|
||||
} else {
|
||||
startTopOffset = oldTop - newElement.offsetParent.getBoundingClientRect().top;
|
||||
}
|
||||
|
||||
var startStyles = [];
|
||||
var enterTransitionOpts = [];
|
||||
|
@ -131,13 +143,12 @@ module.exports = React.createClass({
|
|||
if (oldInfo && oldInfo.left) {
|
||||
// start at the old height and in the old h pos
|
||||
|
||||
var leftOffset = oldInfo.left;
|
||||
startStyles.push({ top: startTopOffset+"px",
|
||||
left: oldInfo.left+"px" });
|
||||
|
||||
var reorderTransitionOpts = {
|
||||
duration: 100,
|
||||
easing: 'easeOut'
|
||||
easing: 'easeOut',
|
||||
};
|
||||
|
||||
enterTransitionOpts.push(reorderTransitionOpts);
|
||||
|
@ -175,7 +186,7 @@ module.exports = React.createClass({
|
|||
if (this.props.timestamp) {
|
||||
title = _t(
|
||||
"Seen by %(userName)s at %(dateTime)s",
|
||||
{userName: this.props.member.userId, dateTime: DateUtils.formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}
|
||||
{userName: this.props.member.userId, dateTime: DateUtils.formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -555,6 +555,7 @@ module.exports = React.createClass({
|
|||
label={ _t('Invites') }
|
||||
editable={ false }
|
||||
order="recent"
|
||||
isInvite={true}
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
incomingCall={ self.state.incomingCall }
|
||||
collapsed={ self.props.collapsed }
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
"Profile": "Profil",
|
||||
"Refer a friend to Riot:": "Freunde zu Riot einladen:",
|
||||
"rejected": "abgelehnt",
|
||||
"Once you've followed the link it contains, click below": "Nachdem du dem darin enthaltenen Link gefolgt bist, klicke unten",
|
||||
"Once you've followed the link it contains, click below": "Nachdem du dem darin enthaltenen Link gefolgt bist, klicke unten",
|
||||
"rejected the invitation.": "lehnte die Einladung ab.",
|
||||
"Reject invitation": "Einladung ablehnen",
|
||||
"Remove Contact Information?": "Kontakt-Informationen entfernen?",
|
||||
|
|
|
@ -688,7 +688,7 @@
|
|||
"No display name": "Χωρίς όνομα",
|
||||
"No users have specific privileges in this room": "Κανένας χρήστης δεν έχει συγκεκριμένα δικαιώματα σε αυτό το δωμάτιο",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Μόλις ενεργοποιηθεί η κρυπτογράφηση για ένα δωμάτιο, δεν μπορεί να απενεργοποιηθεί ξανά (για τώρα)",
|
||||
"Once you've followed the link it contains, click below": "Μόλις ακολουθήσετε τον σύνδεσμο που περιέχει, κάντε κλικ παρακάτω",
|
||||
"Once you've followed the link it contains, click below": "Μόλις ακολουθήσετε τον σύνδεσμο που περιέχει, κάντε κλικ παρακάτω",
|
||||
"Only people who have been invited": "Μόνο άτομα που έχουν προσκληθεί",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Διαφορετικά, κάντε <a>κλικ εδώ</a> για να αποστείλετε μια αναφορά σφάλματος.",
|
||||
"%(senderName)s placed a %(callType)s call.": "Ο %(senderName)s πραγματοποίησε μια %(callType)s κλήση.",
|
||||
|
|
|
@ -440,7 +440,7 @@
|
|||
"OK": "OK",
|
||||
"olm version:": "olm version:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Once encryption is enabled for a room it cannot be turned off again (for now)",
|
||||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Only people who have been invited": "Only people who have been invited",
|
||||
"Operation failed": "Operation failed",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Otherwise, <a>click here</a> to send a bug report.",
|
||||
|
@ -969,5 +969,6 @@
|
|||
"Hide avatars in user and room mentions": "Hide avatars in user and room mentions",
|
||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
||||
"Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>"
|
||||
}
|
||||
|
|
|
@ -402,7 +402,7 @@
|
|||
"OK": "OK",
|
||||
"olm version:": "olm version:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Once encryption is enabled for a room it cannot be turned off again (for now)",
|
||||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Once you've followed the link it contains, click below": "Once you've followed the link it contains, click below",
|
||||
"Only people who have been invited": "Only people who have been invited",
|
||||
"Operation failed": "Operation failed",
|
||||
"Password": "Password",
|
||||
|
|
|
@ -658,7 +658,7 @@
|
|||
"Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensajes de entrada/salida (no afecta invitaciones/kicks/bans)",
|
||||
"Hide avatar and display name changes": "Ocultar cambios de avatar y nombre visible",
|
||||
"Matrix Apps": "Aplicaciones Matrix",
|
||||
"Once you've followed the link it contains, click below": "Cuando haya seguido el enlace que contiene, haga click debajo",
|
||||
"Once you've followed the link it contains, click below": "Cuando haya seguido el enlace que contiene, haga click debajo",
|
||||
"Sets the room topic": "Configura el tema de la sala",
|
||||
"Show Apps": "Mostrar aplicaciones",
|
||||
"To get started, please pick a username!": "Para empezar, ¡por favor elija un nombre de usuario!",
|
||||
|
|
|
@ -495,7 +495,7 @@
|
|||
"No users have specific privileges in this room": "Ez dago gela honetan baimen zehatzik duen erabiltzailerik",
|
||||
"olm version:": "olm bertsioa:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Behin gela batean zifratzea gaituta ezin da gero desgaitu (oraingoz)",
|
||||
"Once you've followed the link it contains, click below": "Behin dakarren esteka jarraitu duzula, egin klik azpian",
|
||||
"Once you've followed the link it contains, click below": "Behin dakarren esteka jarraitu duzula, egin klik azpian",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Bestela, <a>bidali arazte-txosten bat</a>.",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Agian zerbitzaria ez dago eskuragarri, edo gainezka dago, edo akats bat aurkitu duzu.",
|
||||
"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.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen. Etorkizunean hau hobetuko da.",
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{}
|
||||
|
|
|
@ -393,7 +393,7 @@
|
|||
"Mute": "Couper le son",
|
||||
"No users have specific privileges in this room": "Aucun utilisateur n’a de privilège spécifique dans ce salon",
|
||||
"olm version:": "version de olm :",
|
||||
"Once you've followed the link it contains, click below": "Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous",
|
||||
"Once you've followed the link it contains, click below": "Une fois que vous aurez suivi le lien qu’il 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.": "Veuillez vérifier vos e-mails et cliquer sur le lien que vous avez reçu. Puis cliquez sur continuer.",
|
||||
"Power level must be positive integer.": "Le niveau d'autorité doit être un entier positif.",
|
||||
|
|
|
@ -443,7 +443,7 @@
|
|||
"No users have specific privileges in this room": "Egy felhasználónak sincsenek specifikus jogosultságai ebben a szobában",
|
||||
"olm version:": "olm verzió:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Ha egyszer bekapcsolod a titkosítást a szobába utána nem lehet kikapcsolni (egyenlőre)",
|
||||
"Once you've followed the link it contains, click below": "Miután a linket követted, kattints alulra",
|
||||
"Once you've followed the link it contains, click below": "Miután a linket követted, kattints alulra",
|
||||
"Only people who have been invited": "Csak akiket meghívtak",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Különben hiba jelentés küldéséhez <a>kattints ide</a>.",
|
||||
"Password": "Jelszó",
|
||||
|
|
|
@ -452,7 +452,7 @@
|
|||
"People": "사람들",
|
||||
"Phone": "전화",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "방을 암호화하면 암호화를 도중에 끌 수 없어요. (현재로서는)",
|
||||
"Once you've followed the link it contains, click below": "포함된 주소를 따라가서, 아래를 누르세요",
|
||||
"Once you've followed the link it contains, click below": "포함된 주소를 따라가서, 아래를 누르세요",
|
||||
"Only people who have been invited": "초대받은 사람만",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "그 밖에는, <a>여기를 눌러</a> 오류 보고서를 보내주세요.",
|
||||
"%(senderName)s placed a %(callType)s call.": "%(senderName)s님이 %(callType)s 전화를 걸었어요.",
|
||||
|
|
|
@ -427,7 +427,7 @@
|
|||
"OK": "LABI",
|
||||
"olm version:": "olm versija:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Tiklīdz istabai tiks iespējota šifrēšana, tā vairs nebūs atslēdzama (pašlaik)",
|
||||
"Once you've followed the link it contains, click below": "Tiklīdz sekoji saturā esošajai saitei, noklikšķini zemāk",
|
||||
"Once you've followed the link it contains, click below": "Tiklīdz sekoji saturā esošajai saitei, noklikšķini zemāk",
|
||||
"Only people who have been invited": "Vienīgi personas, kuras ir tikušas uzaicinātas",
|
||||
"Operation failed": "Darbība neizdevās",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "pretējā gadījumā, <a>klikšķini šeit</a>, lai nosūtītu paziņojumu par kļūdu.",
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{}
|
||||
|
|
|
@ -502,7 +502,7 @@
|
|||
"New passwords don't match": "Nieuwe wachtwoorden komen niet overeen",
|
||||
"New passwords must match each other.": "Nieuwe wachtwoorden moeten overeenkomen.",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Zodra versleuteling in een kamer is ingeschakeld kan het niet meer worden uitgeschakeld (voor nu)",
|
||||
"Once you've followed the link it contains, click below": "Zodra je de link dat het bevat hebt gevolgd, klik hieronder",
|
||||
"Once you've followed the link it contains, click below": "Zodra je de link dat het bevat hebt gevolgd, klik hieronder",
|
||||
"Only people who have been invited": "Alleen personen die zijn uitgenodigd",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Klik anders <a>hier</a> om een foutmelding te versturen.",
|
||||
"Please check your email and click on the link it contains. Once this is done, click continue.": "Bekijk je e-mail en klik op de link die het bevat. Zodra dit klaar is, klik op verder gaan.",
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
"No users have specific privileges in this room": "Nenhum/a usuário/a possui privilégios específicos nesta sala",
|
||||
"olm version: ": "Versão do olm: ",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Assim que a criptografia é ativada para uma sala, ela não poderá ser desativada novamente (ainda)",
|
||||
"Once you've followed the link it contains, click below": "Quando você tiver clicado no link que está no email, clique o botão abaixo",
|
||||
"Once you've followed the link it contains, click below": "Quando você tiver clicado no link que está no email, clique o botão abaixo",
|
||||
"Only people who have been invited": "Apenas pessoas que tenham sido convidadas",
|
||||
"or": "ou",
|
||||
"other": "outro",
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
"No users have specific privileges in this room": "Nenhum/a usuário/a possui privilégios específicos nesta sala",
|
||||
"olm version: ": "Versão do olm: ",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Assim que a criptografia é ativada para uma sala, ela não poderá ser desativada novamente (ainda)",
|
||||
"Once you've followed the link it contains, click below": "Quando você tiver clicado no link que está no email, clique o botão abaixo",
|
||||
"Once you've followed the link it contains, click below": "Quando você tiver clicado no link que está no email, clique o botão abaixo",
|
||||
"Only people who have been invited": "Apenas pessoas que tenham sido convidadas",
|
||||
"or": "ou",
|
||||
"other": "outro",
|
||||
|
|
|
@ -702,7 +702,7 @@
|
|||
"Jump to first unread message.": "Перейти к первому непрочитанному сообщению.",
|
||||
"Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств",
|
||||
"Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)",
|
||||
"Once you've followed the link it contains, click below": "После перехода по ссылке, нажмите на кнопку ниже",
|
||||
"Once you've followed the link it contains, click below": "После перехода по ссылке, нажмите на кнопку ниже",
|
||||
"Password:": "Пароль:",
|
||||
"Privacy warning": "Предупреждение о конфиденциальности",
|
||||
"Privileged Users": "Привилегированные пользователи",
|
||||
|
|
|
@ -427,7 +427,7 @@
|
|||
"OK": "OK",
|
||||
"olm version:": "olm-version:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "När kryptering aktiveras i ett rum kan det inte deaktiveras (tills vidare)",
|
||||
"Once you've followed the link it contains, click below": "När du har följt länken i meddelandet, klicka här",
|
||||
"Once you've followed the link it contains, click below": "När du har följt länken i meddelandet, klicka här",
|
||||
"Only people who have been invited": "Endast inbjudna",
|
||||
"Operation failed": "Handlingen misslyckades",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Annars kan du <a>klicka här</a> för att skicka en buggrapport.",
|
||||
|
|
|
@ -251,7 +251,7 @@
|
|||
"NOT verified": "ยังไม่ได้ยืนยัน",
|
||||
"No more results": "ไม่มีผลลัพธ์อื่น",
|
||||
"No results": "ไม่มีผลลัพธ์",
|
||||
"Once you've followed the link it contains, click below": "หลังจากคุณเปิดลิงก์ข้างในแล้ว คลิกข้างล่าง",
|
||||
"Once you've followed the link it contains, click below": "หลังจากคุณเปิดลิงก์ข้างในแล้ว คลิกข้างล่าง",
|
||||
"Passwords can't be empty": "รหัสผ่านต้องไม่ว่าง",
|
||||
"People": "บุคคล",
|
||||
"Permissions": "สิทธิ์",
|
||||
|
|
|
@ -424,7 +424,7 @@
|
|||
"OK": "Tamam",
|
||||
"olm version:": "olm versiyon:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "Bu oda için şifreleme etkinleştirildikten sonra tekrar kapatılamaz (şimdilik)",
|
||||
"Once you've followed the link it contains, click below": "Bir kere ' içerdiği bağlantıyı takip ettikten sonra , aşağıya tıklayın",
|
||||
"Once you've followed the link it contains, click below": "Bir kere ' içerdiği bağlantıyı takip ettikten sonra , aşağıya tıklayın",
|
||||
"Only people who have been invited": "Sadece davet edilmiş insanlar",
|
||||
"Operation failed": "Operasyon başarısız oldu",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "Aksi taktirde , bir hata raporu göndermek için <a> buraya tıklayın </a>.",
|
||||
|
|
|
@ -556,7 +556,7 @@
|
|||
"No users have specific privileges in this room": "此房間中沒有使用者有指定的權限",
|
||||
"olm version:": "olm 版本:",
|
||||
"Once encryption is enabled for a room it cannot be turned off again (for now)": "這個房間只要啟用加密就不能再關掉了(從現在開始)",
|
||||
"Once you've followed the link it contains, click below": "一旦您跟著它所包含的連結,點選下方",
|
||||
"Once you've followed the link it contains, click below": "一旦您跟著它所包含的連結,點選下方",
|
||||
"Only people who have been invited": "僅有被邀請的夥伴",
|
||||
"Otherwise, <a>click here</a> to send a bug report.": "否則,請<a>點選此處</a>來傳送錯誤報告。",
|
||||
"Password": "密碼",
|
||||
|
|
|
@ -231,35 +231,31 @@ export function getCurrentLanguage() {
|
|||
}
|
||||
|
||||
function getLangsJson() {
|
||||
const deferred = Promise.defer();
|
||||
|
||||
request(
|
||||
{ method: "GET", url: i18nFolder + 'languages.json' },
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
deferred.reject({err: err, response: response});
|
||||
return;
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{ method: "GET", url: i18nFolder + 'languages.json' },
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
reject({err: err, response: response});
|
||||
return;
|
||||
}
|
||||
resolve(JSON.parse(body));
|
||||
}
|
||||
deferred.resolve(JSON.parse(body));
|
||||
}
|
||||
);
|
||||
return deferred.promise;
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getLanguage(langPath) {
|
||||
const deferred = Promise.defer();
|
||||
|
||||
let response_return = {};
|
||||
request(
|
||||
{ method: "GET", url: langPath },
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
deferred.reject({err: err, response: response});
|
||||
return;
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{ method: "GET", url: langPath },
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
reject({err: err, response: response});
|
||||
return;
|
||||
}
|
||||
resolve(JSON.parse(body));
|
||||
}
|
||||
|
||||
deferred.resolve(JSON.parse(body));
|
||||
}
|
||||
);
|
||||
return deferred.promise;
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue