Merge remote-tracking branch 'origin/develop' into develop
@ -80,6 +80,7 @@
|
||||
"optimist": "^0.6.1",
|
||||
"pako": "^1.0.5",
|
||||
"prop-types": "^15.5.8",
|
||||
"qrcode-react": "^0.1.16",
|
||||
"querystring": "^0.2.0",
|
||||
"react": "^15.6.0",
|
||||
"react-addons-css-transition-group": "15.3.2",
|
||||
|
@ -42,6 +42,7 @@
|
||||
@import "./views/dialogs/_SetEmailDialog.scss";
|
||||
@import "./views/dialogs/_SetMxIdDialog.scss";
|
||||
@import "./views/dialogs/_SetPasswordDialog.scss";
|
||||
@import "./views/dialogs/_ShareDialog.scss";
|
||||
@import "./views/dialogs/_UnknownDeviceDialog.scss";
|
||||
@import "./views/directory/_NetworkDropdown.scss";
|
||||
@import "./views/elements/_AccessibleButton.scss";
|
||||
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
.mx_ContextualMenu_wrapper {
|
||||
position: fixed;
|
||||
z-index: 2000;
|
||||
z-index: 5000;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_background {
|
||||
@ -26,7 +26,7 @@ limitations under the License.
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1.0;
|
||||
z-index: 2000;
|
||||
z-index: 5000;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu {
|
||||
@ -37,7 +37,7 @@ limitations under the License.
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
font-size: 14px;
|
||||
z-index: 2001;
|
||||
z-index: 5001;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu.mx_ContextualMenu_right {
|
||||
|
89
res/css/views/dialogs/_ShareDialog.scss
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_ShareDialog {
|
||||
// this is to center the content
|
||||
padding-right: 58px;
|
||||
}
|
||||
|
||||
.mx_ShareDialog hr {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 25px;
|
||||
border-color: $light-fg-color;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_content {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_matrixto {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-radius: 5px;
|
||||
border: solid 1px $light-fg-color;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 30px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_matrixto a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_matrixto_link {
|
||||
flex-shrink: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_matrixto_copy {
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
margin-left: 20px;
|
||||
display: inherit;
|
||||
}
|
||||
.mx_ShareDialog_matrixto_copy > div {
|
||||
background-image: url($copy-button-url);
|
||||
margin-left: 5px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_split {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_qrcode_container {
|
||||
float: left;
|
||||
background-color: #ffffff;
|
||||
padding: 5px; // makes qr code more readable in dark theme
|
||||
border-radius: 5px;
|
||||
height: 256px;
|
||||
width: 256px;
|
||||
margin-right: 64px;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_social_container {
|
||||
display: inline-block;
|
||||
width: 299px;
|
||||
}
|
||||
|
||||
.mx_ShareDialog_social_icon {
|
||||
display: inline-grid;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
6
res/img/icons-share.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 481.6 481.6" style="enable-background:new 0 0 481.6 481.6;" xml:space="preserve" width="16px" height="16px">
|
||||
<g>
|
||||
<path stroke="#76CFA6" stroke-width="5" d="M381.6,309.4c-27.7,0-52.4,13.2-68.2,33.6l-132.3-73.9c3.1-8.9,4.8-18.5,4.8-28.4c0-10-1.7-19.5-4.9-28.5l132.2-73.8 c15.7,20.5,40.5,33.8,68.3,33.8c47.4,0,86.1-38.6,86.1-86.1S429,0,381.5,0s-86.1,38.6-86.1,86.1c0,10,1.7,19.6,4.9,28.5 l-132.1,73.8c-15.7-20.6-40.5-33.8-68.3-33.8c-47.4,0-86.1,38.6-86.1,86.1s38.7,86.1,86.2,86.1c27.8,0,52.6-13.3,68.4-33.9 l132.2,73.9c-3.2,9-5,18.7-5,28.7c0,47.4,38.6,86.1,86.1,86.1s86.1-38.6,86.1-86.1S429.1,309.4,381.6,309.4z M381.6,27.1 c32.6,0,59.1,26.5,59.1,59.1s-26.5,59.1-59.1,59.1s-59.1-26.5-59.1-59.1S349.1,27.1,381.6,27.1z M100,299.8 c-32.6,0-59.1-26.5-59.1-59.1s26.5-59.1,59.1-59.1s59.1,26.5,59.1,59.1S132.5,299.8,100,299.8z M381.6,454.5 c-32.6,0-59.1-26.5-59.1-59.1c0-32.6,26.5-59.1,59.1-59.1s59.1,26.5,59.1,59.1C440.7,428,414.2,454.5,381.6,454.5z" fill="#76cfa6"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
15
res/img/matrix-m.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 520 520" style="enable-background:new 0 0 520 520;" xml:space="preserve">
|
||||
<rect width="100%" height="100%" fill="#FFFFFF"/>
|
||||
<path d="M13.7,11.9v496.2h35.7V520H0V0h49.4v11.9H13.7z"/>
|
||||
<path d="M166.3,169.2v25.1h0.7c6.7-9.6,14.8-17,24.2-22.2c9.4-5.3,20.3-7.9,32.5-7.9c11.7,0,22.4,2.3,32.1,6.8
|
||||
c9.7,4.5,17,12.6,22.1,24c5.5-8.1,13-15.3,22.4-21.5c9.4-6.2,20.6-9.3,33.5-9.3c9.8,0,18.9,1.2,27.3,3.6c8.4,2.4,15.5,6.2,21.5,11.5
|
||||
c6,5.3,10.6,12.1,14,20.6c3.3,8.5,5,18.7,5,30.7v124.1h-50.9V249.6c0-6.2-0.2-12.1-0.7-17.6c-0.5-5.5-1.8-10.3-3.9-14.3
|
||||
c-2.2-4.1-5.3-7.3-9.5-9.7c-4.2-2.4-9.9-3.6-17-3.6c-7.2,0-13,1.4-17.4,4.1c-4.4,2.8-7.9,6.3-10.4,10.8c-2.5,4.4-4.2,9.4-5,15.1
|
||||
c-0.8,5.6-1.3,11.3-1.3,17v103.3h-50.9v-104c0-5.5-0.1-10.9-0.4-16.3c-0.2-5.4-1.3-10.3-3.1-14.9c-1.8-4.5-4.8-8.2-9-10.9
|
||||
c-4.2-2.7-10.3-4.1-18.5-4.1c-2.4,0-5.6,0.5-9.5,1.6c-3.9,1.1-7.8,3.1-11.5,6.1c-3.7,3-6.9,7.3-9.5,12.9c-2.6,5.6-3.9,13-3.9,22.1
|
||||
v107.6h-50.9V169.2H166.3z"/>
|
||||
<path d="M506.3,508.1V11.9h-35.7V0H520v520h-49.4v-11.9H506.3z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
res/img/social/email-1.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
res/img/social/facebook.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
res/img/social/linkedin.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
res/img/social/reddit.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
res/img/social/twitter-2.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2018 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.
|
||||
@ -15,12 +16,10 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
const classNames = require('classnames');
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||
@ -61,7 +60,12 @@ export default class ContextualMenu extends React.Component {
|
||||
// If true, insert an invisible screen-sized element behind the
|
||||
// menu that when clicked will close it.
|
||||
hasBackground: PropTypes.bool,
|
||||
}
|
||||
|
||||
// The component to render as the context menu
|
||||
elementClass: PropTypes.element.isRequired,
|
||||
// on resize callback
|
||||
windowResize: PropTypes.func
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -145,7 +149,7 @@ export default class ContextualMenu extends React.Component {
|
||||
`;
|
||||
}
|
||||
|
||||
const chevron = <div style={chevronOffset} className={"mx_ContextualMenu_chevron_" + chevronFace}></div>;
|
||||
const chevron = <div style={chevronOffset} className={"mx_ContextualMenu_chevron_" + chevronFace} />;
|
||||
const className = 'mx_ContextualMenu_wrapper';
|
||||
|
||||
const menuClasses = classNames({
|
||||
@ -191,13 +195,13 @@ export default class ContextualMenu extends React.Component {
|
||||
{ chevron }
|
||||
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
||||
</div>
|
||||
{ props.hasBackground && <div className="mx_ContextualMenu_background" onClick={props.closeMenu}></div> }
|
||||
{ props.hasBackground && <div className="mx_ContextualMenu_background" onClick={props.closeMenu} /> }
|
||||
<style>{ chevronCSS }</style>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export function createMenu(ElementClass, props) {
|
||||
export function createMenu(ElementClass, props, hasBackground=true) {
|
||||
const closeMenu = function(...args) {
|
||||
ReactDOM.unmountComponentAtNode(getOrCreateContainer());
|
||||
|
||||
@ -208,8 +212,8 @@ export function createMenu(ElementClass, props) {
|
||||
|
||||
// We only reference closeMenu once per call to createMenu
|
||||
const menu = <ContextualMenu
|
||||
hasBackground={hasBackground}
|
||||
{...props}
|
||||
hasBackground={true}
|
||||
elementClass={ElementClass}
|
||||
closeMenu={closeMenu} // eslint-disable-line react/jsx-no-bind
|
||||
windowResize={closeMenu} // eslint-disable-line react/jsx-no-bind
|
||||
|
@ -562,6 +562,13 @@ export default React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
_onShareClick: function() {
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share community dialog', '', ShareDialog, {
|
||||
target: this._matrixClient.getGroup(this.props.groupId),
|
||||
});
|
||||
},
|
||||
|
||||
_onCancelClick: function() {
|
||||
this._closeSettings();
|
||||
},
|
||||
@ -1207,6 +1214,7 @@ export default React.createClass({
|
||||
shortDescNode = <span onClick={onGroupHeaderItemClick}>{ summary.profile.short_description }</span>;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.editing) {
|
||||
rightButtons.push(
|
||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||
@ -1231,6 +1239,11 @@ export default React.createClass({
|
||||
</AccessibleButton>,
|
||||
);
|
||||
}
|
||||
rightButtons.push(
|
||||
<AccessibleButton className="mx_GroupHeader_button" onClick={this._onShareClick} title={_t('Share Community')} key="_shareButton">
|
||||
<TintableSvg src="img/icons-share.svg" width="16" height="16" />
|
||||
</AccessibleButton>,
|
||||
);
|
||||
if (this.props.collapsedRhs) {
|
||||
rightButtons.push(
|
||||
<AccessibleButton className="mx_GroupHeader_button"
|
||||
|
@ -1108,6 +1108,14 @@ module.exports = React.createClass({
|
||||
</div>;
|
||||
},
|
||||
|
||||
onSelfShareClick: function() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share self dialog', '', ShareDialog, {
|
||||
target: cli.getUser(this._me),
|
||||
});
|
||||
},
|
||||
|
||||
_showSpoiler: function(event) {
|
||||
const target = event.target;
|
||||
target.innerHTML = target.getAttribute('data-spoiler');
|
||||
@ -1329,10 +1337,13 @@ module.exports = React.createClass({
|
||||
|
||||
<div className="mx_UserSettings_section">
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{ _t("Logged in as:") } { this._me }
|
||||
{ _t("Logged in as:") + ' ' }
|
||||
<a onClick={this.onSelfShareClick} className="mx_UserSettings_link">
|
||||
{ this._me }
|
||||
</a>
|
||||
</div>
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{ _t('Access Token:') }
|
||||
{ _t('Access Token:') + ' ' }
|
||||
<span className="mx_UserSettings_advanced_spoiler"
|
||||
onClick={this._showSpoiler}
|
||||
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
||||
|
@ -184,6 +184,15 @@ module.exports = React.createClass({
|
||||
this.closeMenu();
|
||||
},
|
||||
|
||||
onPermalinkClick: function(e: Event) {
|
||||
e.preventDefault();
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share room message dialog', '', ShareDialog, {
|
||||
target: this.props.mxEvent,
|
||||
});
|
||||
this.closeMenu();
|
||||
},
|
||||
|
||||
onReplyClick: function() {
|
||||
dis.dispatch({
|
||||
action: 'reply_to_event',
|
||||
@ -290,7 +299,7 @@ module.exports = React.createClass({
|
||||
const permalinkButton = (
|
||||
<div className="mx_MessageContextMenu_field">
|
||||
<a href={makeEventPermalink(this.props.mxEvent.getRoomId(), this.props.mxEvent.getId())}
|
||||
target="_blank" rel="noopener" onClick={this.closeMenu}>{ _t('Permalink') }</a>
|
||||
target="_blank" rel="noopener" onClick={this.onPermalinkClick}>{ _t('Share Message') }</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||
import React from 'react';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { MatrixClient } from 'matrix-js-sdk';
|
||||
|
||||
@ -64,7 +65,10 @@ export default React.createClass({
|
||||
|
||||
// Id of content element
|
||||
// If provided, this is used to add a aria-describedby attribute
|
||||
contentId: React.PropTypes.string,
|
||||
contentId: PropTypes.string,
|
||||
|
||||
// optional additional class for the title element
|
||||
titleClass: PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
@ -105,25 +109,28 @@ export default React.createClass({
|
||||
render: function() {
|
||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
|
||||
let cancelButton;
|
||||
if (this.props.hasCancel) {
|
||||
cancelButton = <AccessibleButton onClick={this._onCancelClick} className="mx_Dialog_cancelButton">
|
||||
<TintableSvg src="img/icons-close-button.svg" width="35" height="35" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
return (
|
||||
<FocusTrap onKeyDown={this._onKeyDown}
|
||||
className={this.props.className}
|
||||
role="dialog"
|
||||
aria-labelledby='mx_BaseDialog_title'
|
||||
// This should point to a node describing the dialog.
|
||||
// If we were about to completelly follow this recommendation we'd need to
|
||||
// If we were about to completely follow this recommendation we'd need to
|
||||
// make all the components relying on BaseDialog to be aware of it.
|
||||
// So instead we will use the whole content as the description.
|
||||
// Description comes first and if the content contains more text,
|
||||
// AT users can skip its presentation.
|
||||
aria-describedby={this.props.contentId}
|
||||
>
|
||||
{ this.props.hasCancel ? <AccessibleButton onClick={this._onCancelClick}
|
||||
className="mx_Dialog_cancelButton"
|
||||
>
|
||||
<TintableSvg src="img/icons-close-button.svg" width="35" height="35" />
|
||||
</AccessibleButton> : null }
|
||||
<div className={'mx_Dialog_title ' + this.props.titleClass} id='mx_BaseDialog_title'>
|
||||
{ cancelButton }
|
||||
<div className={classNames('mx_Dialog_title', this.props.titleClass)} id='mx_BaseDialog_title'>
|
||||
{ this.props.title }
|
||||
</div>
|
||||
{ this.props.children }
|
||||
|
@ -187,7 +187,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
ChatCreateOrReuseDialog.propTyps = {
|
||||
ChatCreateOrReuseDialog.propTypes = {
|
||||
userId: PropTypes.string.isRequired,
|
||||
// Called when clicking outside of the dialog
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
|
224
src/components/views/dialogs/ShareDialog.js
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Room, User, Group, RoomMember, MatrixEvent} from 'matrix-js-sdk';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import QRCode from 'qrcode-react';
|
||||
import {makeEventPermalink, makeGroupPermalink, makeRoomPermalink, makeUserPermalink} from "../../../matrix-to";
|
||||
import * as ContextualMenu from "../../structures/ContextualMenu";
|
||||
|
||||
const socials = [
|
||||
{
|
||||
name: 'Facebook',
|
||||
img: 'img/social/facebook.png',
|
||||
url: (url) => `https://www.facebook.com/sharer/sharer.php?u=${url}`,
|
||||
}, {
|
||||
name: 'Twitter',
|
||||
img: 'img/social/twitter-2.png',
|
||||
url: (url) => `https://twitter.com/home?status=${url}`,
|
||||
}, /* // icon missing
|
||||
name: 'Google Plus',
|
||||
img: 'img/social/',
|
||||
url: (url) => `https://plus.google.com/share?url=${url}`,
|
||||
},*/ {
|
||||
name: 'LinkedIn',
|
||||
img: 'img/social/linkedin.png',
|
||||
url: (url) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`,
|
||||
}, {
|
||||
name: 'Reddit',
|
||||
img: 'img/social/reddit.png',
|
||||
url: (url) => `http://www.reddit.com/submit?url=${url}`,
|
||||
}, {
|
||||
name: 'email',
|
||||
img: 'img/social/email-1.png',
|
||||
url: (url) => `mailto:?body=${url}`,
|
||||
},
|
||||
];
|
||||
|
||||
export default class ShareDialog extends React.Component {
|
||||
static propTypes = {
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
target: PropTypes.oneOfType([
|
||||
PropTypes.instanceOf(Room),
|
||||
PropTypes.instanceOf(User),
|
||||
PropTypes.instanceOf(Group),
|
||||
PropTypes.instanceOf(RoomMember),
|
||||
PropTypes.instanceOf(MatrixEvent),
|
||||
]).isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.onCopyClick = this.onCopyClick.bind(this);
|
||||
this.onLinkSpecificEventCheckboxClick = this.onLinkSpecificEventCheckboxClick.bind(this);
|
||||
|
||||
this.state = {
|
||||
// MatrixEvent defaults to share linkSpecificEvent
|
||||
linkSpecificEvent: this.props.target instanceof MatrixEvent,
|
||||
};
|
||||
}
|
||||
|
||||
static _selectText(target) {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(target);
|
||||
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
static onLinkClick(e) {
|
||||
e.preventDefault();
|
||||
const {target} = e;
|
||||
ShareDialog._selectText(target);
|
||||
}
|
||||
|
||||
onCopyClick(e) {
|
||||
e.preventDefault();
|
||||
|
||||
ShareDialog._selectText(this.refs.link);
|
||||
|
||||
let successful;
|
||||
try {
|
||||
successful = document.execCommand('copy');
|
||||
} catch (err) {
|
||||
console.error('Failed to copy: ', err);
|
||||
}
|
||||
|
||||
const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu');
|
||||
const buttonRect = e.target.getBoundingClientRect();
|
||||
|
||||
// The window X and Y offsets are to adjust position when zoomed in to page
|
||||
const x = buttonRect.right + window.pageXOffset;
|
||||
const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
|
||||
const {close} = ContextualMenu.createMenu(GenericTextContextMenu, {
|
||||
chevronOffset: 10,
|
||||
left: x,
|
||||
top: y,
|
||||
message: successful ? _t('Copied!') : _t('Failed to copy'),
|
||||
}, false);
|
||||
e.target.onmouseleave = close;
|
||||
}
|
||||
|
||||
onLinkSpecificEventCheckboxClick() {
|
||||
this.setState({
|
||||
linkSpecificEvent: !this.state.linkSpecificEvent,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let title;
|
||||
let matrixToUrl;
|
||||
|
||||
let checkbox;
|
||||
|
||||
if (this.props.target instanceof Room) {
|
||||
title = _t('Share Room');
|
||||
|
||||
const events = this.props.target.getLiveTimeline().getEvents();
|
||||
if (events.length > 0) {
|
||||
checkbox = <div>
|
||||
<input type="checkbox"
|
||||
id="mx_ShareDialog_checkbox"
|
||||
checked={this.state.linkSpecificEvent}
|
||||
onClick={this.onLinkSpecificEventCheckboxClick} />
|
||||
<label htmlFor="mx_ShareDialog_checkbox">
|
||||
{ _t('Link to most recent message') }
|
||||
</label>
|
||||
</div>;
|
||||
}
|
||||
|
||||
if (this.state.linkSpecificEvent) {
|
||||
matrixToUrl = makeEventPermalink(this.props.target.roomId, events[events.length - 1].getId());
|
||||
} else {
|
||||
matrixToUrl = makeRoomPermalink(this.props.target.roomId);
|
||||
}
|
||||
} else if (this.props.target instanceof User || this.props.target instanceof RoomMember) {
|
||||
title = _t('Share User');
|
||||
matrixToUrl = makeUserPermalink(this.props.target.userId);
|
||||
} else if (this.props.target instanceof Group) {
|
||||
title = _t('Share Community');
|
||||
matrixToUrl = makeGroupPermalink(this.props.target.groupId);
|
||||
} else if (this.props.target instanceof MatrixEvent) {
|
||||
title = _t('Share Room Message');
|
||||
checkbox = <div>
|
||||
<input type="checkbox"
|
||||
id="mx_ShareDialog_checkbox"
|
||||
checked={this.state.linkSpecificEvent}
|
||||
onClick={this.onLinkSpecificEventCheckboxClick} />
|
||||
<label htmlFor="mx_ShareDialog_checkbox">
|
||||
{ _t('Link to selected message') }
|
||||
</label>
|
||||
</div>;
|
||||
|
||||
if (this.state.linkSpecificEvent) {
|
||||
matrixToUrl = makeEventPermalink(this.props.target.getRoomId(), this.props.target.getId());
|
||||
} else {
|
||||
matrixToUrl = makeRoomPermalink(this.props.target.getRoomId());
|
||||
}
|
||||
}
|
||||
|
||||
const encodedUrl = encodeURIComponent(matrixToUrl);
|
||||
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return <BaseDialog title={title}
|
||||
className='mx_ShareDialog'
|
||||
contentId='mx_Dialog_content'
|
||||
onFinished={this.props.onFinished}
|
||||
>
|
||||
<div className="mx_ShareDialog_content">
|
||||
<div className="mx_ShareDialog_matrixto">
|
||||
<a ref="link"
|
||||
href={matrixToUrl}
|
||||
onClick={ShareDialog.onLinkClick}
|
||||
className="mx_ShareDialog_matrixto_link"
|
||||
>
|
||||
{ matrixToUrl }
|
||||
</a>
|
||||
<a href={matrixToUrl} className="mx_ShareDialog_matrixto_copy" onClick={this.onCopyClick}>
|
||||
{ _t('COPY') }
|
||||
<div> </div>
|
||||
</a>
|
||||
</div>
|
||||
{ checkbox }
|
||||
<hr />
|
||||
|
||||
<div className="mx_ShareDialog_split">
|
||||
<div className="mx_ShareDialog_qrcode_container">
|
||||
<QRCode value={matrixToUrl} size={256} logoWidth={48} logo="img/matrix-m.svg" />
|
||||
</div>
|
||||
<div className="mx_ShareDialog_social_container">
|
||||
{
|
||||
socials.map((social) => <a rel="noopener"
|
||||
target="_blank"
|
||||
key={social.name}
|
||||
name={social.name}
|
||||
href={social.url(encodedUrl)}
|
||||
className="mx_ShareDialog_social_icon"
|
||||
>
|
||||
<img src={social.img} alt={social.name} height={64} width={64} />
|
||||
</a>)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseDialog>;
|
||||
}
|
||||
}
|
@ -336,8 +336,8 @@ module.exports = React.createClass({
|
||||
left: x,
|
||||
top: y,
|
||||
message: successful ? _t('Copied!') : _t('Failed to copy'),
|
||||
});
|
||||
e.target.onmouseout = close;
|
||||
}, false);
|
||||
e.target.onmouseleave = close;
|
||||
};
|
||||
p.appendChild(button);
|
||||
});
|
||||
|
@ -439,6 +439,17 @@ module.exports = withMatrixClient(React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
onPermalinkShareClicked: function(e) {
|
||||
// These permalinks are like above, can be opened in new tab/window to matrix.to
|
||||
// but otherwise fire the ShareDialog as it makes little sense to click permalink
|
||||
// whilst it is in the current room
|
||||
e.preventDefault();
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share room event dialog', '', ShareDialog, {
|
||||
target: this.props.mxEvent,
|
||||
});
|
||||
},
|
||||
|
||||
_renderE2EPadlock: function() {
|
||||
const ev = this.props.mxEvent;
|
||||
const props = {onClick: this.onCryptoClicked};
|
||||
@ -669,7 +680,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||
{ avatar }
|
||||
{ sender }
|
||||
<div className="mx_EventTile_reply">
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkShareClicked}>
|
||||
{ timestamp }
|
||||
</a>
|
||||
{ this._renderE2EPadlock() }
|
||||
@ -696,7 +707,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||
{ avatar }
|
||||
{ sender }
|
||||
<div className="mx_EventTile_line">
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkShareClicked}>
|
||||
{ timestamp }
|
||||
</a>
|
||||
{ this._renderE2EPadlock() }
|
||||
|
@ -632,6 +632,13 @@ module.exports = withMatrixClient(React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
onShareUserClick: function() {
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share room member dialog', '', ShareDialog, {
|
||||
target: this.props.member,
|
||||
});
|
||||
},
|
||||
|
||||
_renderUserOptions: function() {
|
||||
const cli = this.props.matrixClient;
|
||||
const member = this.props.member;
|
||||
@ -705,13 +712,18 @@ module.exports = withMatrixClient(React.createClass({
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreButton && !readReceiptButton && !insertPillButton && !inviteUserButton) return null;
|
||||
const shareUserButton = (
|
||||
<AccessibleButton onClick={this.onShareUserClick} className="mx_MemberInfo_field">
|
||||
{ _t('Share Link to User') }
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>{ _t("User Options") }</h3>
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
{ readReceiptButton }
|
||||
{ shareUserButton }
|
||||
{ insertPillButton }
|
||||
{ ignoreButton }
|
||||
{ inviteUserButton }
|
||||
|
@ -149,6 +149,13 @@ module.exports = React.createClass({
|
||||
dis.dispatch({ action: 'show_right_panel' });
|
||||
},
|
||||
|
||||
onShareRoomClick: function(ev) {
|
||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
||||
Modal.createTrackedDialog('share room dialog', '', ShareDialog, {
|
||||
target: this.props.room,
|
||||
});
|
||||
},
|
||||
|
||||
_hasUnreadPins: function() {
|
||||
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
||||
if (!currentPinEvent) return false;
|
||||
@ -379,6 +386,14 @@ module.exports = React.createClass({
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
let shareRoomButton;
|
||||
if (this.props.inRoom) {
|
||||
shareRoomButton =
|
||||
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShareRoomClick} title={_t('Share room')}>
|
||||
<TintableSvg src="img/icons-share.svg" width="16" height="16" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
let rightPanelButtons;
|
||||
if (this.props.collapsedRhs) {
|
||||
rightPanelButtons =
|
||||
@ -400,6 +415,7 @@ module.exports = React.createClass({
|
||||
<div className="mx_RoomHeader_rightRow">
|
||||
{ settingsButton }
|
||||
{ pinnedEventsButton }
|
||||
{ shareRoomButton }
|
||||
{ manageIntegsButton }
|
||||
{ forgetButton }
|
||||
{ searchButton }
|
||||
|
@ -31,7 +31,6 @@
|
||||
"Noisy": "Шумна",
|
||||
"Resend": "Паўторна",
|
||||
"On": "Уключыць",
|
||||
"Permalink": "Пастаянная спасылка",
|
||||
"remove %(name)s from the directory.": "выдаліць %(name)s з каталога.",
|
||||
"Off": "Выключыць",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Выдаліць псеўданім пакоя %(alias)s і выдаліць %(name)s з каталога?",
|
||||
|
@ -1124,7 +1124,6 @@
|
||||
"Set Password": "Задаване на парола",
|
||||
"An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.",
|
||||
"Enable audible notifications in web client": "Включване на звукови известия в уеб клиент",
|
||||
"Permalink": "Permalink",
|
||||
"Off": "Изключено",
|
||||
"Riot does not know how to join a room on this network": "Riot не знае как да се присъедини към стая от тази мрежа",
|
||||
"Mentions only": "Само при споменаване",
|
||||
|
@ -1003,7 +1003,6 @@
|
||||
"Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions",
|
||||
"Set Password": "Establiu una contrasenya",
|
||||
"Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web",
|
||||
"Permalink": "Enllaç permanent",
|
||||
"Off": "Apagat",
|
||||
"Riot does not know how to join a room on this network": "El Riot no sap com unir-se a una sala en aquesta xarxa",
|
||||
"Mentions only": "Només mencions",
|
||||
|
@ -1061,7 +1061,6 @@
|
||||
"Set Password": "Nastavit heslo",
|
||||
"An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.",
|
||||
"Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci",
|
||||
"Permalink": "Trvalý odkaz",
|
||||
"Off": "Vypnout",
|
||||
"#example": "#příklad",
|
||||
"Mentions only": "Pouze zmínky",
|
||||
|
@ -370,7 +370,6 @@
|
||||
"Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste",
|
||||
"Set Password": "Indstil Password",
|
||||
"Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten",
|
||||
"Permalink": "Permanent link",
|
||||
"Resend": "Send igen",
|
||||
"Riot does not know how to join a room on this network": "Riot ved ikke, hvordan man kan deltage i et rum på dette netværk",
|
||||
"Mentions only": "Kun nævninger",
|
||||
|
@ -1125,7 +1125,6 @@
|
||||
"Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden",
|
||||
"Set Password": "Passwort einrichten",
|
||||
"Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren",
|
||||
"Permalink": "Permanenter Link",
|
||||
"Off": "Aus",
|
||||
"Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll",
|
||||
"Mentions only": "Nur, wenn du erwähnt wirst",
|
||||
|
@ -745,7 +745,6 @@
|
||||
"What's New": "Τι νέο υπάρχει",
|
||||
"Set Password": "Ορισμός κωδικού πρόσβασης",
|
||||
"Enable audible notifications in web client": "Ενεργοποίηση ηχητικών ειδοποιήσεων",
|
||||
"Permalink": "Μόνιμος σύνδεσμος",
|
||||
"Off": "Ανενεργό",
|
||||
"#example": "#παράδειγμα",
|
||||
"Mentions only": "Μόνο αναφορές",
|
||||
|
@ -371,6 +371,7 @@
|
||||
"Jump to read receipt": "Jump to read receipt",
|
||||
"Mention": "Mention",
|
||||
"Invite": "Invite",
|
||||
"Share Link to User": "Share Link to User",
|
||||
"User Options": "User Options",
|
||||
"Direct chats": "Direct chats",
|
||||
"Unmute": "Unmute",
|
||||
@ -452,6 +453,7 @@
|
||||
"Settings": "Settings",
|
||||
"Forget room": "Forget room",
|
||||
"Search": "Search",
|
||||
"Share room": "Share room",
|
||||
"Show panel": "Show panel",
|
||||
"Drop here to favourite": "Drop here to favourite",
|
||||
"Drop here to tag direct chat": "Drop here to tag direct chat",
|
||||
@ -858,6 +860,13 @@
|
||||
"(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)",
|
||||
"Please set a password!": "Please set a password!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.",
|
||||
"Share Room": "Share Room",
|
||||
"Link to most recent message": "Link to most recent message",
|
||||
"Share User": "Share User",
|
||||
"Share Community": "Share Community",
|
||||
"Share Room Message": "Share Room Message",
|
||||
"Link to selected message": "Link to selected message",
|
||||
"COPY": "COPY",
|
||||
"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.",
|
||||
"Room contains unknown devices": "Room contains unknown devices",
|
||||
@ -876,7 +885,7 @@
|
||||
"View Source": "View Source",
|
||||
"View Decrypted Source": "View Decrypted Source",
|
||||
"Unhide Preview": "Unhide Preview",
|
||||
"Permalink": "Permalink",
|
||||
"Share Message": "Share Message",
|
||||
"Quote": "Quote",
|
||||
"Source URL": "Source URL",
|
||||
"Collapse Reply Thread": "Collapse Reply Thread",
|
||||
|
@ -815,7 +815,6 @@
|
||||
"Unable to fetch notification target list": "Unable to fetch notification target list",
|
||||
"Set Password": "Set Password",
|
||||
"Enable audible notifications in web client": "Enable audible notifications in web client",
|
||||
"Permalink": "Permalink",
|
||||
"Off": "Off",
|
||||
"Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network",
|
||||
"Mentions only": "Mentions only",
|
||||
|
@ -1076,7 +1076,6 @@
|
||||
"Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj",
|
||||
"Set Password": "Agordi pasvorton",
|
||||
"Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento",
|
||||
"Permalink": "Konstanta ligilo",
|
||||
"Off": "For",
|
||||
"Riot does not know how to join a room on this network": "Riot ne scias aliĝi al ĉambroj en tiu ĉi reto",
|
||||
"Mentions only": "Nur mencioj",
|
||||
|
@ -716,7 +716,6 @@
|
||||
"Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red",
|
||||
"Set Password": "Establecer contraseña",
|
||||
"Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web",
|
||||
"Permalink": "Enlace permanente",
|
||||
"Off": "Apagado",
|
||||
"#example": "#ejemplo",
|
||||
"Mentions only": "Sólo menciones",
|
||||
|
@ -1126,7 +1126,6 @@
|
||||
"Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu",
|
||||
"Set Password": "Ezarri pasahitza",
|
||||
"Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan",
|
||||
"Permalink": "Esteka iraunkorra",
|
||||
"Off": "Ez",
|
||||
"Riot does not know how to join a room on this network": "Riotek ez daki nola elkartu gela batetara sare honetan",
|
||||
"Mentions only": "Aipamenak besterik ez",
|
||||
|
@ -124,7 +124,6 @@
|
||||
"Set Password": "پسوردتان را انتخاب کنید",
|
||||
"An error occurred whilst saving your email notification preferences.": "خطایی در حین ذخیرهی ترجیجات شما دربارهی رایانامه رخ داد.",
|
||||
"Enable audible notifications in web client": "آگاهسازی صدادار را در کارگزار وب فعال کن",
|
||||
"Permalink": "پایاپیوند",
|
||||
"Off": "خاموش",
|
||||
"Riot does not know how to join a room on this network": "رایوت از چگونگی ورود به یک گپ در این شبکه اطلاعی ندارد",
|
||||
"Mentions only": "فقط نامبردنها",
|
||||
|
@ -1049,7 +1049,6 @@
|
||||
"Set Password": "Aseta salasana",
|
||||
"An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.",
|
||||
"Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset",
|
||||
"Permalink": "Pysyvä linkki",
|
||||
"remove %(name)s from the directory.": "poista %(name)s hakemistosta.",
|
||||
"Off": "Pois päältä",
|
||||
"Riot does not know how to join a room on this network": "Riot ei tiedä miten liittya huoneeseen tässä verkossa",
|
||||
|
@ -1120,7 +1120,6 @@
|
||||
"Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications",
|
||||
"Set Password": "Définir un mot de passe",
|
||||
"Enable audible notifications in web client": "Activer les notifications sonores pour le client web",
|
||||
"Permalink": "Permalien",
|
||||
"Off": "Désactivé",
|
||||
"Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau",
|
||||
"Mentions only": "Seulement les mentions",
|
||||
|
@ -1126,7 +1126,6 @@
|
||||
"Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións",
|
||||
"Set Password": "Establecer contrasinal",
|
||||
"Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web",
|
||||
"Permalink": "Ligazón permanente",
|
||||
"Off": "Off",
|
||||
"Riot does not know how to join a room on this network": "Riot non sabe cómo conectar con unha sala en esta rede",
|
||||
"Mentions only": "Só mencións",
|
||||
|
@ -221,7 +221,6 @@
|
||||
"Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה",
|
||||
"Set Password": "הגדר סיסמא",
|
||||
"Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן",
|
||||
"Permalink": "קישור קבוע",
|
||||
"Off": "סגור",
|
||||
"Riot does not know how to join a room on this network": "Riot אינו יודע כיצד להצטרף לחדר ברשת זו",
|
||||
"Mentions only": "מאזכר בלבד",
|
||||
|
@ -1125,7 +1125,6 @@
|
||||
"Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját",
|
||||
"Set Password": "Jelszó beállítása",
|
||||
"Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben",
|
||||
"Permalink": "Állandó hivatkozás",
|
||||
"Off": "Ki",
|
||||
"Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton",
|
||||
"Mentions only": "Csak ha megemlítenek",
|
||||
|
@ -323,7 +323,6 @@
|
||||
"Unable to fetch notification target list": "Tidak dapat mengambil daftar notifikasi target",
|
||||
"Set Password": "Ubah Password",
|
||||
"Enable audible notifications in web client": "Aktifkan notifikasi suara di klien web",
|
||||
"Permalink": "Permalink",
|
||||
"Off": "Mati",
|
||||
"Riot does not know how to join a room on this network": "Riot tidak tau bagaimana gabung ruang di jaringan ini",
|
||||
"Mentions only": "Hanya jika disinggung",
|
||||
|
@ -380,7 +380,6 @@
|
||||
"View Source": "Skoða frumkóða",
|
||||
"View Decrypted Source": "Skoða afkóðaða upprunaskrá",
|
||||
"Unhide Preview": "Birta forskoðun",
|
||||
"Permalink": "Varanlegur tengill",
|
||||
"Quote": "Tilvitnun",
|
||||
"Source URL": "Upprunaslóð",
|
||||
"All messages (noisy)": "Öll skilaboð (hávært)",
|
||||
|
@ -1121,7 +1121,6 @@
|
||||
"What's New": "Novità",
|
||||
"Set Password": "Imposta Password",
|
||||
"Enable audible notifications in web client": "Abilita notifiche audio nel client web",
|
||||
"Permalink": "Link permanente",
|
||||
"Off": "Spento",
|
||||
"#example": "#esempio",
|
||||
"Mentions only": "Solo le citazioni",
|
||||
|
@ -223,7 +223,6 @@
|
||||
"Event Type": "イベントの形式",
|
||||
"What's New": "新着",
|
||||
"Enable audible notifications in web client": "ウェブクライアントで音による通知を有効化",
|
||||
"Permalink": "パーマリンク",
|
||||
"remove %(name)s from the directory.": "ディレクトリから %(name)s を消去する。",
|
||||
"Riot does not know how to join a room on this network": "Riotはこのネットワークで部屋に参加する方法を知りません",
|
||||
"You can now return to your account after signing out, and sign in on other devices.": "サインアウト後にあなたの\nアカウントに戻る、また、他の端末でサインインすることができます。",
|
||||
|
@ -753,7 +753,6 @@
|
||||
"Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요",
|
||||
"Set Password": "비밀번호 설정",
|
||||
"Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기",
|
||||
"Permalink": "고유주소",
|
||||
"Off": "끄기",
|
||||
"#example": "#예",
|
||||
"Mentions only": "답만 하기",
|
||||
|
@ -161,7 +161,6 @@
|
||||
"Set Password": "Nustatyti slaptažodį",
|
||||
"An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.",
|
||||
"Unable to join network": "Nepavyko prisijungti prie tinklo",
|
||||
"Permalink": "Pastovioji nuoroda",
|
||||
"Register": "Registruotis",
|
||||
"Off": "Išjungta",
|
||||
"Edit": "Koreguoti",
|
||||
|
@ -1114,7 +1114,6 @@
|
||||
"Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu",
|
||||
"Set Password": "Iestatīt paroli",
|
||||
"Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā",
|
||||
"Permalink": "Pastāvīgā saite",
|
||||
"Off": "izslēgts",
|
||||
"Riot does not know how to join a room on this network": "Riot nezin kā pievienoties šajā tīklā esošajai istabai",
|
||||
"Mentions only": "Vienīgi atsauces",
|
||||
|
@ -137,7 +137,6 @@
|
||||
"Unable to fetch notification target list": "നോട്ടിഫിക്കേഷന് ടാര്ഗെറ്റ് ലിസ്റ്റ് നേടാനായില്ല",
|
||||
"Set Password": "രഹസ്യവാക്ക് സജ്ജീകരിക്കുക",
|
||||
"Enable audible notifications in web client": "വെബ് പതിപ്പിലെ അറിയിപ്പുകള് കേള്ക്കാവുന്നതാക്കുക",
|
||||
"Permalink": "പെര്മാലിങ്ക്",
|
||||
"remove %(name)s from the directory.": "%(name)s ഡയറക്റ്ററിയില് നിന്ന് നീക്കം ചെയ്യുക.",
|
||||
"Off": "ഓഫ്",
|
||||
"Riot does not know how to join a room on this network": "ഈ നെറ്റ്വര്ക്കിലെ ഒരു റൂമില് എങ്ങനെ അംഗമാകാമെന്ന് റയട്ടിന് അറിയില്ല",
|
||||
|
@ -98,7 +98,6 @@
|
||||
"Riot does not know how to join a room on this network": "Riot vet ikke hvordan man kan komme inn på et rom på dette nettverket",
|
||||
"An error occurred whilst saving your email notification preferences.": "En feil oppsto i forbindelse med lagring av epost varsel innstillinger.",
|
||||
"Enable audible notifications in web client": "Aktiver lyd-varsel i webklient",
|
||||
"Permalink": "Permanent lenke",
|
||||
"remove %(name)s from the directory.": "fjern %(name)s fra katalogen.",
|
||||
"Off": "Av",
|
||||
"#example": "#eksempel",
|
||||
|
@ -1119,7 +1119,6 @@
|
||||
"Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen",
|
||||
"Set Password": "Wachtwoord instellen",
|
||||
"Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten",
|
||||
"Permalink": "Permanente link",
|
||||
"Off": "Uit",
|
||||
"Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een ruimte op dit netwerk",
|
||||
"Mentions only": "Alleen vermeldingen",
|
||||
|
@ -900,7 +900,6 @@
|
||||
"Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień",
|
||||
"Set Password": "Ustaw hasło",
|
||||
"Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym",
|
||||
"Permalink": "Odnośnik bezpośredni",
|
||||
"Off": "Wyłącz",
|
||||
"Riot does not know how to join a room on this network": "Riot nie wie, jak dołączyć do pokoju w tej sieci",
|
||||
"Mentions only": "Tylko, gdy wymienieni",
|
||||
|
@ -825,7 +825,6 @@
|
||||
"Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação",
|
||||
"Set Password": "Definir palavra-passe",
|
||||
"Enable audible notifications in web client": "Ativar notificações de áudio no cliente web",
|
||||
"Permalink": "Link permanente",
|
||||
"Off": "Desativado",
|
||||
"Riot does not know how to join a room on this network": "O Riot não sabe como entrar numa sala nesta rede",
|
||||
"Mentions only": "Apenas menções",
|
||||
|
@ -1100,7 +1100,6 @@
|
||||
"Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação",
|
||||
"Set Password": "Definir senha",
|
||||
"Enable audible notifications in web client": "Ativar notificações de áudio no cliente web",
|
||||
"Permalink": "Link permanente",
|
||||
"Off": "Desativado",
|
||||
"Riot does not know how to join a room on this network": "O sistema não sabe como entrar na sala desta rede",
|
||||
"Mentions only": "Apenas menções",
|
||||
|
@ -1124,7 +1124,6 @@
|
||||
"Unable to fetch notification target list": "Не удалось получить список устройств для уведомлений",
|
||||
"Set Password": "Задать пароль",
|
||||
"Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте",
|
||||
"Permalink": "Постоянная ссылка",
|
||||
"Off": "Выключить",
|
||||
"Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети",
|
||||
"Mentions only": "Только при упоминаниях",
|
||||
|
@ -1125,7 +1125,6 @@
|
||||
"Set Password": "Nastaviť Heslo",
|
||||
"An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.",
|
||||
"Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi",
|
||||
"Permalink": "Trvalý odkaz",
|
||||
"Off": "Zakázané",
|
||||
"Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti",
|
||||
"Mentions only": "Len zmienky",
|
||||
|
@ -269,7 +269,6 @@
|
||||
"Set Password": "Caktoni Fjalëkalim",
|
||||
"An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.",
|
||||
"Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web",
|
||||
"Permalink": "Permalidhje",
|
||||
"Register": "Regjistrohuni",
|
||||
"Off": "Off",
|
||||
"Edit": "Përpunoni",
|
||||
|
@ -1100,7 +1100,6 @@
|
||||
"Set Password": "Постави лозинку",
|
||||
"An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.",
|
||||
"Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту",
|
||||
"Permalink": "Трајна веза",
|
||||
"Resend": "Поново пошаљи",
|
||||
"Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи",
|
||||
"Mentions only": "Само спомињања",
|
||||
|
@ -546,7 +546,6 @@
|
||||
"Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan",
|
||||
"Set Password": "Välj lösenord",
|
||||
"Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten",
|
||||
"Permalink": "Permanent länk",
|
||||
"Off": "Av",
|
||||
"Riot does not know how to join a room on this network": "Riot kan inte gå med i ett rum på det här nätverket",
|
||||
"Mentions only": "Endast omnämnande",
|
||||
|
@ -78,7 +78,6 @@
|
||||
"Off": "அமை",
|
||||
"On": "மீது",
|
||||
"Operation failed": "செயல்பாடு தோல்வியுற்றது",
|
||||
"Permalink": "நிரந்தரத் தொடுப்பு",
|
||||
"powered by Matrix": "Matrix-ஆல் ஆனது",
|
||||
"Quote": "மேற்கோள்",
|
||||
"Reject": "நிராகரி",
|
||||
|
@ -543,7 +543,6 @@
|
||||
"Riot does not know how to join a room on this network": "Riot ไม่รู้วิธีเข้าร่วมห้องในเครือข่ายนี้",
|
||||
"Set Password": "ตั้งรหัสผ่าน",
|
||||
"Enable audible notifications in web client": "เปิดใช้งานเสียงแจ้งเตือนบนเว็บไคลเอนต์",
|
||||
"Permalink": "ลิงก์ถาวร",
|
||||
"Off": "ปิด",
|
||||
"#example": "#example",
|
||||
"Mentions only": "เมื่อถูกกล่าวถึงเท่านั้น",
|
||||
|
@ -740,7 +740,6 @@
|
||||
"Unable to fetch notification target list": "Bildirim hedef listesi çekilemedi",
|
||||
"An error occurred whilst saving your email notification preferences.": "E-posta bildirim tercihlerinizi kaydetme işlemi sırasında bir hata oluştu.",
|
||||
"Enable audible notifications in web client": "Web istemcisinde sesli bildirimleri etkinleştir",
|
||||
"Permalink": "Kalıcı Bağlantı(permalink)",
|
||||
"Off": "Kapalı",
|
||||
"Riot does not know how to join a room on this network": "Riot bu ağdaki bir odaya nasıl gireceğini bilmiyor",
|
||||
"Mentions only": "Sadece Mention'lar",
|
||||
|
@ -232,7 +232,6 @@
|
||||
"Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення",
|
||||
"Set Password": "Задати пароль",
|
||||
"Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку",
|
||||
"Permalink": "Постійне посилання",
|
||||
"Off": "Вимкнено",
|
||||
"Riot does not know how to join a room on this network": "Riot не знає як приєднатись до кімнати у цій мережі",
|
||||
"Mentions only": "Тільки згадки",
|
||||
|
@ -1098,7 +1098,6 @@
|
||||
"Unable to fetch notification target list": "无法获取通知目标列表",
|
||||
"Set Password": "设置密码",
|
||||
"Enable audible notifications in web client": "在网页客户端启用音频通知",
|
||||
"Permalink": "永久链接",
|
||||
"Off": "关闭",
|
||||
"Riot does not know how to join a room on this network": "Riot 不知道如何在此网络中加入聊天室",
|
||||
"Mentions only": "只限提及",
|
||||
|
@ -1125,7 +1125,6 @@
|
||||
"Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室",
|
||||
"Set Password": "設定密碼",
|
||||
"Enable audible notifications in web client": "在網頁客戶端啟用音訊通知",
|
||||
"Permalink": "永久連結",
|
||||
"Off": "關閉",
|
||||
"#example": "#範例",
|
||||
"Mentions only": "僅提及",
|
||||
|