Merge pull request #1948 from matrix-org/export_Group

Share Dialog
This commit is contained in:
David Baker 2018-06-15 10:52:27 +01:00 committed by GitHub
commit 6904c2bafe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 459 additions and 72 deletions

View file

@ -80,6 +80,7 @@
"optimist": "^0.6.1", "optimist": "^0.6.1",
"pako": "^1.0.5", "pako": "^1.0.5",
"prop-types": "^15.5.8", "prop-types": "^15.5.8",
"qrcode-react": "^0.1.16",
"querystring": "^0.2.0", "querystring": "^0.2.0",
"react": "^15.6.0", "react": "^15.6.0",
"react-addons-css-transition-group": "15.3.2", "react-addons-css-transition-group": "15.3.2",

View file

@ -42,6 +42,7 @@
@import "./views/dialogs/_SetEmailDialog.scss"; @import "./views/dialogs/_SetEmailDialog.scss";
@import "./views/dialogs/_SetMxIdDialog.scss"; @import "./views/dialogs/_SetMxIdDialog.scss";
@import "./views/dialogs/_SetPasswordDialog.scss"; @import "./views/dialogs/_SetPasswordDialog.scss";
@import "./views/dialogs/_ShareDialog.scss";
@import "./views/dialogs/_UnknownDeviceDialog.scss"; @import "./views/dialogs/_UnknownDeviceDialog.scss";
@import "./views/directory/_NetworkDropdown.scss"; @import "./views/directory/_NetworkDropdown.scss";
@import "./views/elements/_AccessibleButton.scss"; @import "./views/elements/_AccessibleButton.scss";

View file

@ -16,7 +16,7 @@ limitations under the License.
.mx_ContextualMenu_wrapper { .mx_ContextualMenu_wrapper {
position: fixed; position: fixed;
z-index: 2000; z-index: 5000;
} }
.mx_ContextualMenu_background { .mx_ContextualMenu_background {
@ -26,7 +26,7 @@ limitations under the License.
width: 100%; width: 100%;
height: 100%; height: 100%;
opacity: 1.0; opacity: 1.0;
z-index: 2000; z-index: 5000;
} }
.mx_ContextualMenu { .mx_ContextualMenu {
@ -37,7 +37,7 @@ limitations under the License.
position: absolute; position: absolute;
padding: 6px; padding: 6px;
font-size: 14px; font-size: 14px;
z-index: 2001; z-index: 5001;
} }
.mx_ContextualMenu.mx_ContextualMenu_right { .mx_ContextualMenu.mx_ContextualMenu_right {

View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
res/img/social/facebook.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/img/social/linkedin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
res/img/social/reddit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,5 +1,6 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -15,12 +16,10 @@ limitations under the License.
*/ */
'use strict'; import React from 'react';
import ReactDOM from 'react-dom';
const classNames = require('classnames');
const React = require('react');
const ReactDOM = require('react-dom');
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames';
// Shamelessly ripped off Modal.js. There's probably a better way // Shamelessly ripped off Modal.js. There's probably a better way
// of doing reusable widgets like dialog boxes & menus where we go and // 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 // If true, insert an invisible screen-sized element behind the
// menu that when clicked will close it. // menu that when clicked will close it.
hasBackground: PropTypes.bool, hasBackground: PropTypes.bool,
}
// The component to render as the context menu
elementClass: PropTypes.element.isRequired,
// on resize callback
windowResize: PropTypes.func
};
constructor() { constructor() {
super(); 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 className = 'mx_ContextualMenu_wrapper';
const menuClasses = classNames({ const menuClasses = classNames({
@ -191,13 +195,13 @@ export default class ContextualMenu extends React.Component {
{ chevron } { chevron }
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} /> <ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
</div> </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> <style>{ chevronCSS }</style>
</div>; </div>;
} }
} }
export function createMenu(ElementClass, props) { export function createMenu(ElementClass, props, hasBackground=true) {
const closeMenu = function(...args) { const closeMenu = function(...args) {
ReactDOM.unmountComponentAtNode(getOrCreateContainer()); ReactDOM.unmountComponentAtNode(getOrCreateContainer());
@ -208,8 +212,8 @@ export function createMenu(ElementClass, props) {
// We only reference closeMenu once per call to createMenu // We only reference closeMenu once per call to createMenu
const menu = <ContextualMenu const menu = <ContextualMenu
hasBackground={hasBackground}
{...props} {...props}
hasBackground={true}
elementClass={ElementClass} elementClass={ElementClass}
closeMenu={closeMenu} // eslint-disable-line react/jsx-no-bind closeMenu={closeMenu} // eslint-disable-line react/jsx-no-bind
windowResize={closeMenu} // eslint-disable-line react/jsx-no-bind windowResize={closeMenu} // eslint-disable-line react/jsx-no-bind

View file

@ -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() { _onCancelClick: function() {
this._closeSettings(); this._closeSettings();
}, },
@ -1207,6 +1214,7 @@ export default React.createClass({
shortDescNode = <span onClick={onGroupHeaderItemClick}>{ summary.profile.short_description }</span>; shortDescNode = <span onClick={onGroupHeaderItemClick}>{ summary.profile.short_description }</span>;
} }
} }
if (this.state.editing) { if (this.state.editing) {
rightButtons.push( rightButtons.push(
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton" <AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
@ -1231,6 +1239,11 @@ export default React.createClass({
</AccessibleButton>, </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) { if (this.props.collapsedRhs) {
rightButtons.push( rightButtons.push(
<AccessibleButton className="mx_GroupHeader_button" <AccessibleButton className="mx_GroupHeader_button"

View file

@ -1108,6 +1108,14 @@ module.exports = React.createClass({
</div>; </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) { _showSpoiler: function(event) {
const target = event.target; const target = event.target;
target.innerHTML = target.getAttribute('data-spoiler'); target.innerHTML = target.getAttribute('data-spoiler');
@ -1329,10 +1337,13 @@ module.exports = React.createClass({
<div className="mx_UserSettings_section"> <div className="mx_UserSettings_section">
<div className="mx_UserSettings_advanced"> <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>
<div className="mx_UserSettings_advanced"> <div className="mx_UserSettings_advanced">
{ _t('Access Token:') } { _t('Access Token:') + ' ' }
<span className="mx_UserSettings_advanced_spoiler" <span className="mx_UserSettings_advanced_spoiler"
onClick={this._showSpoiler} onClick={this._showSpoiler}
data-spoiler={MatrixClientPeg.get().getAccessToken()}> data-spoiler={MatrixClientPeg.get().getAccessToken()}>

View file

@ -184,6 +184,15 @@ module.exports = React.createClass({
this.closeMenu(); 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() { onReplyClick: function() {
dis.dispatch({ dis.dispatch({
action: 'reply_to_event', action: 'reply_to_event',
@ -290,7 +299,7 @@ module.exports = React.createClass({
const permalinkButton = ( const permalinkButton = (
<div className="mx_MessageContextMenu_field"> <div className="mx_MessageContextMenu_field">
<a href={makeEventPermalink(this.props.mxEvent.getRoomId(), this.props.mxEvent.getId())} <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> </div>
); );

View file

@ -18,6 +18,7 @@ limitations under the License.
import React from 'react'; import React from 'react';
import FocusTrap from 'focus-trap-react'; import FocusTrap from 'focus-trap-react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames';
import { MatrixClient } from 'matrix-js-sdk'; import { MatrixClient } from 'matrix-js-sdk';
@ -64,7 +65,10 @@ export default React.createClass({
// Id of content element // Id of content element
// If provided, this is used to add a aria-describedby attribute // 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() { getDefaultProps: function() {
@ -105,25 +109,28 @@ export default React.createClass({
render: function() { render: function() {
const TintableSvg = sdk.getComponent("elements.TintableSvg"); 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 ( return (
<FocusTrap onKeyDown={this._onKeyDown} <FocusTrap onKeyDown={this._onKeyDown}
className={this.props.className} className={this.props.className}
role="dialog" role="dialog"
aria-labelledby='mx_BaseDialog_title' aria-labelledby='mx_BaseDialog_title'
// This should point to a node describing the dialog. // 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. // make all the components relying on BaseDialog to be aware of it.
// So instead we will use the whole content as the description. // So instead we will use the whole content as the description.
// Description comes first and if the content contains more text, // Description comes first and if the content contains more text,
// AT users can skip its presentation. // AT users can skip its presentation.
aria-describedby={this.props.contentId} aria-describedby={this.props.contentId}
> >
{ this.props.hasCancel ? <AccessibleButton onClick={this._onCancelClick} { cancelButton }
className="mx_Dialog_cancelButton" <div className={classNames('mx_Dialog_title', this.props.titleClass)} id='mx_BaseDialog_title'>
>
<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'>
{ this.props.title } { this.props.title }
</div> </div>
{ this.props.children } { this.props.children }

View file

@ -187,7 +187,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
} }
} }
ChatCreateOrReuseDialog.propTyps = { ChatCreateOrReuseDialog.propTypes = {
userId: PropTypes.string.isRequired, userId: PropTypes.string.isRequired,
// Called when clicking outside of the dialog // Called when clicking outside of the dialog
onFinished: PropTypes.func.isRequired, onFinished: PropTypes.func.isRequired,

View 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>&nbsp;</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>;
}
}

View file

@ -336,8 +336,8 @@ module.exports = React.createClass({
left: x, left: x,
top: y, top: y,
message: successful ? _t('Copied!') : _t('Failed to copy'), message: successful ? _t('Copied!') : _t('Failed to copy'),
}); }, false);
e.target.onmouseout = close; e.target.onmouseleave = close;
}; };
p.appendChild(button); p.appendChild(button);
}); });

View file

@ -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() { _renderE2EPadlock: function() {
const ev = this.props.mxEvent; const ev = this.props.mxEvent;
const props = {onClick: this.onCryptoClicked}; const props = {onClick: this.onCryptoClicked};
@ -669,7 +680,7 @@ module.exports = withMatrixClient(React.createClass({
{ avatar } { avatar }
{ sender } { sender }
<div className="mx_EventTile_reply"> <div className="mx_EventTile_reply">
<a href={permalink} onClick={this.onPermalinkClicked}> <a href={permalink} onClick={this.onPermalinkShareClicked}>
{ timestamp } { timestamp }
</a> </a>
{ this._renderE2EPadlock() } { this._renderE2EPadlock() }
@ -696,7 +707,7 @@ module.exports = withMatrixClient(React.createClass({
{ avatar } { avatar }
{ sender } { sender }
<div className="mx_EventTile_line"> <div className="mx_EventTile_line">
<a href={permalink} onClick={this.onPermalinkClicked}> <a href={permalink} onClick={this.onPermalinkShareClicked}>
{ timestamp } { timestamp }
</a> </a>
{ this._renderE2EPadlock() } { this._renderE2EPadlock() }

View file

@ -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() { _renderUserOptions: function() {
const cli = this.props.matrixClient; const cli = this.props.matrixClient;
const member = this.props.member; 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 ( return (
<div> <div>
<h3>{ _t("User Options") }</h3> <h3>{ _t("User Options") }</h3>
<div className="mx_MemberInfo_buttons"> <div className="mx_MemberInfo_buttons">
{ readReceiptButton } { readReceiptButton }
{ shareUserButton }
{ insertPillButton } { insertPillButton }
{ ignoreButton } { ignoreButton }
{ inviteUserButton } { inviteUserButton }

View file

@ -149,6 +149,13 @@ module.exports = React.createClass({
dis.dispatch({ action: 'show_right_panel' }); 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() { _hasUnreadPins: function() {
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", ''); const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
if (!currentPinEvent) return false; if (!currentPinEvent) return false;
@ -379,6 +386,14 @@ module.exports = React.createClass({
</AccessibleButton>; </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; let rightPanelButtons;
if (this.props.collapsedRhs) { if (this.props.collapsedRhs) {
rightPanelButtons = rightPanelButtons =
@ -400,6 +415,7 @@ module.exports = React.createClass({
<div className="mx_RoomHeader_rightRow"> <div className="mx_RoomHeader_rightRow">
{ settingsButton } { settingsButton }
{ pinnedEventsButton } { pinnedEventsButton }
{ shareRoomButton }
{ manageIntegsButton } { manageIntegsButton }
{ forgetButton } { forgetButton }
{ searchButton } { searchButton }

View file

@ -31,7 +31,6 @@
"Noisy": "Шумна", "Noisy": "Шумна",
"Resend": "Паўторна", "Resend": "Паўторна",
"On": "Уключыць", "On": "Уключыць",
"Permalink": "Пастаянная спасылка",
"remove %(name)s from the directory.": "выдаліць %(name)s з каталога.", "remove %(name)s from the directory.": "выдаліць %(name)s з каталога.",
"Off": "Выключыць", "Off": "Выключыць",
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Выдаліць псеўданім пакоя %(alias)s і выдаліць %(name)s з каталога?", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Выдаліць псеўданім пакоя %(alias)s і выдаліць %(name)s з каталога?",

View file

@ -1124,7 +1124,6 @@
"Set Password": "Задаване на парола", "Set Password": "Задаване на парола",
"An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.",
"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 не знае как да се присъедини към стая от тази мрежа", "Riot does not know how to join a room on this network": "Riot не знае как да се присъедини към стая от тази мрежа",
"Mentions only": "Само при споменаване", "Mentions only": "Само при споменаване",

View file

@ -1003,7 +1003,6 @@
"Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions",
"Set Password": "Establiu una contrasenya", "Set Password": "Establiu una contrasenya",
"Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web",
"Permalink": "Enllaç permanent",
"Off": "Apagat", "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", "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", "Mentions only": "Només mencions",

View file

@ -1061,7 +1061,6 @@
"Set Password": "Nastavit heslo", "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.", "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", "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci",
"Permalink": "Trvalý odkaz",
"Off": "Vypnout", "Off": "Vypnout",
"#example": "#příklad", "#example": "#příklad",
"Mentions only": "Pouze zmínky", "Mentions only": "Pouze zmínky",

View file

@ -370,7 +370,6 @@
"Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste",
"Set Password": "Indstil Password", "Set Password": "Indstil Password",
"Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten",
"Permalink": "Permanent link",
"Resend": "Send igen", "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", "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", "Mentions only": "Kun nævninger",

View file

@ -1125,7 +1125,6 @@
"Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden",
"Set Password": "Passwort einrichten", "Set Password": "Passwort einrichten",
"Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren",
"Permalink": "Permanenter Link",
"Off": "Aus", "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", "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", "Mentions only": "Nur, wenn du erwähnt wirst",

View file

@ -745,7 +745,6 @@
"What's New": "Τι νέο υπάρχει", "What's New": "Τι νέο υπάρχει",
"Set Password": "Ορισμός κωδικού πρόσβασης", "Set Password": "Ορισμός κωδικού πρόσβασης",
"Enable audible notifications in web client": "Ενεργοποίηση ηχητικών ειδοποιήσεων", "Enable audible notifications in web client": "Ενεργοποίηση ηχητικών ειδοποιήσεων",
"Permalink": "Μόνιμος σύνδεσμος",
"Off": "Ανενεργό", "Off": "Ανενεργό",
"#example": "#παράδειγμα", "#example": "#παράδειγμα",
"Mentions only": "Μόνο αναφορές", "Mentions only": "Μόνο αναφορές",

View file

@ -371,6 +371,7 @@
"Jump to read receipt": "Jump to read receipt", "Jump to read receipt": "Jump to read receipt",
"Mention": "Mention", "Mention": "Mention",
"Invite": "Invite", "Invite": "Invite",
"Share Link to User": "Share Link to User",
"User Options": "User Options", "User Options": "User Options",
"Direct chats": "Direct chats", "Direct chats": "Direct chats",
"Unmute": "Unmute", "Unmute": "Unmute",
@ -452,6 +453,7 @@
"Settings": "Settings", "Settings": "Settings",
"Forget room": "Forget room", "Forget room": "Forget room",
"Search": "Search", "Search": "Search",
"Share room": "Share room",
"Show panel": "Show panel", "Show panel": "Show panel",
"Drop here to favourite": "Drop here to favourite", "Drop here to favourite": "Drop here to favourite",
"Drop here to tag direct chat": "Drop here to tag direct chat", "Drop here to tag direct chat": "Drop here to tag direct chat",
@ -858,6 +860,13 @@
"(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)",
"Please set a password!": "Please set a password!", "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.", "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.", "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.", "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", "Room contains unknown devices": "Room contains unknown devices",
@ -876,7 +885,7 @@
"View Source": "View Source", "View Source": "View Source",
"View Decrypted Source": "View Decrypted Source", "View Decrypted Source": "View Decrypted Source",
"Unhide Preview": "Unhide Preview", "Unhide Preview": "Unhide Preview",
"Permalink": "Permalink", "Share Message": "Share Message",
"Quote": "Quote", "Quote": "Quote",
"Source URL": "Source URL", "Source URL": "Source URL",
"Collapse Reply Thread": "Collapse Reply Thread", "Collapse Reply Thread": "Collapse Reply Thread",

View file

@ -815,7 +815,6 @@
"Unable to fetch notification target list": "Unable to fetch notification target list", "Unable to fetch notification target list": "Unable to fetch notification target list",
"Set Password": "Set Password", "Set Password": "Set Password",
"Enable audible notifications in web client": "Enable audible notifications in web client", "Enable audible notifications in web client": "Enable audible notifications in web client",
"Permalink": "Permalink",
"Off": "Off", "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", "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", "Mentions only": "Mentions only",

View file

@ -1076,7 +1076,6 @@
"Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj",
"Set Password": "Agordi pasvorton", "Set Password": "Agordi pasvorton",
"Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento",
"Permalink": "Konstanta ligilo",
"Off": "For", "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", "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", "Mentions only": "Nur mencioj",

View file

@ -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", "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", "Set Password": "Establecer contraseña",
"Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web",
"Permalink": "Enlace permanente",
"Off": "Apagado", "Off": "Apagado",
"#example": "#ejemplo", "#example": "#ejemplo",
"Mentions only": "Sólo menciones", "Mentions only": "Sólo menciones",

View file

@ -1126,7 +1126,6 @@
"Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu",
"Set Password": "Ezarri pasahitza", "Set Password": "Ezarri pasahitza",
"Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan",
"Permalink": "Esteka iraunkorra",
"Off": "Ez", "Off": "Ez",
"Riot does not know how to join a room on this network": "Riotek ez daki nola elkartu gela batetara sare honetan", "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", "Mentions only": "Aipamenak besterik ez",

View file

@ -124,7 +124,6 @@
"Set Password": "پسوردتان را انتخاب کنید", "Set Password": "پسوردتان را انتخاب کنید",
"An error occurred whilst saving your email notification preferences.": "خطایی در حین ذخیره‌ی ترجیجات شما درباره‌ی رایانامه رخ داد.", "An error occurred whilst saving your email notification preferences.": "خطایی در حین ذخیره‌ی ترجیجات شما درباره‌ی رایانامه رخ داد.",
"Enable audible notifications in web client": "آگاه‌سازی صدادار را در کارگزار وب فعال کن", "Enable audible notifications in web client": "آگاه‌سازی صدادار را در کارگزار وب فعال کن",
"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": "فقط نام‌بردن‌ها",

View file

@ -1049,7 +1049,6 @@
"Set Password": "Aseta salasana", "Set Password": "Aseta salasana",
"An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", "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", "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.", "remove %(name)s from the directory.": "poista %(name)s hakemistosta.",
"Off": "Pois päältä", "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", "Riot does not know how to join a room on this network": "Riot ei tiedä miten liittya huoneeseen tässä verkossa",

View file

@ -1120,7 +1120,6 @@
"Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", "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", "Set Password": "Définir un mot de passe",
"Enable audible notifications in web client": "Activer les notifications sonores pour le client web", "Enable audible notifications in web client": "Activer les notifications sonores pour le client web",
"Permalink": "Permalien",
"Off": "Désactivé", "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", "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", "Mentions only": "Seulement les mentions",

View file

@ -1126,7 +1126,6 @@
"Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións",
"Set Password": "Establecer contrasinal", "Set Password": "Establecer contrasinal",
"Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web",
"Permalink": "Ligazón permanente",
"Off": "Off", "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", "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", "Mentions only": "Só mencións",

View file

@ -221,7 +221,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": "קישור קבוע",
"Off": "סגור", "Off": "סגור",
"Riot does not know how to join a room on this network": "Riot אינו יודע כיצד להצטרף לחדר ברשת זו", "Riot does not know how to join a room on this network": "Riot אינו יודע כיצד להצטרף לחדר ברשת זו",
"Mentions only": "מאזכר בלבד", "Mentions only": "מאזכר בלבד",

View file

@ -1125,7 +1125,6 @@
"Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", "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", "Set Password": "Jelszó beállítása",
"Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben",
"Permalink": "Állandó hivatkozás",
"Off": "Ki", "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", "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", "Mentions only": "Csak ha megemlítenek",

View file

@ -323,7 +323,6 @@
"Unable to fetch notification target list": "Tidak dapat mengambil daftar notifikasi target", "Unable to fetch notification target list": "Tidak dapat mengambil daftar notifikasi target",
"Set Password": "Ubah Password", "Set Password": "Ubah Password",
"Enable audible notifications in web client": "Aktifkan notifikasi suara di klien web", "Enable audible notifications in web client": "Aktifkan notifikasi suara di klien web",
"Permalink": "Permalink",
"Off": "Mati", "Off": "Mati",
"Riot does not know how to join a room on this network": "Riot tidak tau bagaimana gabung ruang di jaringan ini", "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", "Mentions only": "Hanya jika disinggung",

View file

@ -380,7 +380,6 @@
"View Source": "Skoða frumkóða", "View Source": "Skoða frumkóða",
"View Decrypted Source": "Skoða afkóðaða upprunaskrá", "View Decrypted Source": "Skoða afkóðaða upprunaskrá",
"Unhide Preview": "Birta forskoðun", "Unhide Preview": "Birta forskoðun",
"Permalink": "Varanlegur tengill",
"Quote": "Tilvitnun", "Quote": "Tilvitnun",
"Source URL": "Upprunaslóð", "Source URL": "Upprunaslóð",
"All messages (noisy)": "Öll skilaboð (hávært)", "All messages (noisy)": "Öll skilaboð (hávært)",

View file

@ -1121,7 +1121,6 @@
"What's New": "Novità", "What's New": "Novità",
"Set Password": "Imposta Password", "Set Password": "Imposta Password",
"Enable audible notifications in web client": "Abilita notifiche audio nel client web", "Enable audible notifications in web client": "Abilita notifiche audio nel client web",
"Permalink": "Link permanente",
"Off": "Spento", "Off": "Spento",
"#example": "#esempio", "#example": "#esempio",
"Mentions only": "Solo le citazioni", "Mentions only": "Solo le citazioni",

View file

@ -223,7 +223,6 @@
"Event Type": "イベントの形式", "Event Type": "イベントの形式",
"What's New": "新着", "What's New": "新着",
"Enable audible notifications in web client": "ウェブクライアントで音による通知を有効化", "Enable audible notifications in web client": "ウェブクライアントで音による通知を有効化",
"Permalink": "パーマリンク",
"remove %(name)s from the directory.": "ディレクトリから %(name)s を消去する。", "remove %(name)s from the directory.": "ディレクトリから %(name)s を消去する。",
"Riot does not know how to join a room on this network": "Riotはこのネットワークで部屋に参加する方法を知りません", "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アカウントに戻る、また、他の端末でサインインすることができます。", "You can now return to your account after signing out, and sign in on other devices.": "サインアウト後にあなたの\nアカウントに戻る、また、他の端末でサインインすることができます。",

View file

@ -753,7 +753,6 @@
"Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요",
"Set Password": "비밀번호 설정", "Set Password": "비밀번호 설정",
"Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기",
"Permalink": "고유주소",
"Off": "끄기", "Off": "끄기",
"#example": "#예", "#example": "#예",
"Mentions only": "답만 하기", "Mentions only": "답만 하기",

View file

@ -161,7 +161,6 @@
"Set Password": "Nustatyti slaptažodį", "Set Password": "Nustatyti slaptažodį",
"An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", "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", "Unable to join network": "Nepavyko prisijungti prie tinklo",
"Permalink": "Pastovioji nuoroda",
"Register": "Registruotis", "Register": "Registruotis",
"Off": "Išjungta", "Off": "Išjungta",
"Edit": "Koreguoti", "Edit": "Koreguoti",

View file

@ -1114,7 +1114,6 @@
"Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu",
"Set Password": "Iestatīt paroli", "Set Password": "Iestatīt paroli",
"Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā",
"Permalink": "Pastāvīgā saite",
"Off": "izslēgts", "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", "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", "Mentions only": "Vienīgi atsauces",

View file

@ -137,7 +137,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": "പെര്‍മാലിങ്ക്",
"remove %(name)s from the directory.": "%(name)s ഡയറക്റ്ററിയില്‍ നിന്ന് നീക്കം ചെയ്യുക.", "remove %(name)s from the directory.": "%(name)s ഡയറക്റ്ററിയില്‍ നിന്ന് നീക്കം ചെയ്യുക.",
"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": "ഈ നെറ്റ്‍വര്‍ക്കിലെ ഒരു റൂമില്‍ എങ്ങനെ അംഗമാകാമെന്ന് റയട്ടിന് അറിയില്ല",

View file

@ -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", "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.", "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", "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.", "remove %(name)s from the directory.": "fjern %(name)s fra katalogen.",
"Off": "Av", "Off": "Av",
"#example": "#eksempel", "#example": "#eksempel",

View file

@ -1119,7 +1119,6 @@
"Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen",
"Set Password": "Wachtwoord instellen", "Set Password": "Wachtwoord instellen",
"Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten",
"Permalink": "Permanente link",
"Off": "Uit", "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", "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", "Mentions only": "Alleen vermeldingen",

View file

@ -900,7 +900,6 @@
"Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień",
"Set Password": "Ustaw hasło", "Set Password": "Ustaw hasło",
"Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym",
"Permalink": "Odnośnik bezpośredni",
"Off": "Wyłącz", "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", "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", "Mentions only": "Tylko, gdy wymienieni",

View file

@ -825,7 +825,6 @@
"Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação",
"Set Password": "Definir palavra-passe", "Set Password": "Definir palavra-passe",
"Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web",
"Permalink": "Link permanente",
"Off": "Desativado", "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", "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", "Mentions only": "Apenas menções",

View file

@ -1100,7 +1100,6 @@
"Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação",
"Set Password": "Definir senha", "Set Password": "Definir senha",
"Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web",
"Permalink": "Link permanente",
"Off": "Desativado", "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", "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", "Mentions only": "Apenas menções",

View file

@ -1124,7 +1124,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": "Постоянная ссылка",
"Off": "Выключить", "Off": "Выключить",
"Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети",
"Mentions only": "Только при упоминаниях", "Mentions only": "Только при упоминаниях",

View file

@ -1125,7 +1125,6 @@
"Set Password": "Nastaviť Heslo", "Set Password": "Nastaviť Heslo",
"An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", "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", "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi",
"Permalink": "Trvalý odkaz",
"Off": "Zakázané", "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", "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", "Mentions only": "Len zmienky",

View file

@ -269,7 +269,6 @@
"Set Password": "Caktoni Fjalëkalim", "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.", "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", "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web",
"Permalink": "Permalidhje",
"Register": "Regjistrohuni", "Register": "Regjistrohuni",
"Off": "Off", "Off": "Off",
"Edit": "Përpunoni", "Edit": "Përpunoni",

View file

@ -1100,7 +1100,6 @@
"Set Password": "Постави лозинку", "Set Password": "Постави лозинку",
"An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.",
"Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту",
"Permalink": "Трајна веза",
"Resend": "Поново пошаљи", "Resend": "Поново пошаљи",
"Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи",
"Mentions only": "Само спомињања", "Mentions only": "Само спомињања",

View file

@ -546,7 +546,6 @@
"Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan",
"Set Password": "Välj lösenord", "Set Password": "Välj lösenord",
"Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten",
"Permalink": "Permanent länk",
"Off": "Av", "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", "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", "Mentions only": "Endast omnämnande",

View file

@ -78,7 +78,6 @@
"Off": "அமை", "Off": "அமை",
"On": "மீது", "On": "மீது",
"Operation failed": "செயல்பாடு தோல்வியுற்றது", "Operation failed": "செயல்பாடு தோல்வியுற்றது",
"Permalink": "நிரந்தரத் தொடுப்பு",
"powered by Matrix": "Matrix-ஆல் ஆனது", "powered by Matrix": "Matrix-ஆல் ஆனது",
"Quote": "மேற்கோள்", "Quote": "மேற்கோள்",
"Reject": "நிராகரி", "Reject": "நிராகரி",

View file

@ -543,7 +543,6 @@
"Riot does not know how to join a room on this network": "Riot ไม่รู้วิธีเข้าร่วมห้องในเครือข่ายนี้", "Riot does not know how to join a room on this network": "Riot ไม่รู้วิธีเข้าร่วมห้องในเครือข่ายนี้",
"Set Password": "ตั้งรหัสผ่าน", "Set Password": "ตั้งรหัสผ่าน",
"Enable audible notifications in web client": "เปิดใช้งานเสียงแจ้งเตือนบนเว็บไคลเอนต์", "Enable audible notifications in web client": "เปิดใช้งานเสียงแจ้งเตือนบนเว็บไคลเอนต์",
"Permalink": "ลิงก์ถาวร",
"Off": "ปิด", "Off": "ปิด",
"#example": "#example", "#example": "#example",
"Mentions only": "เมื่อถูกกล่าวถึงเท่านั้น", "Mentions only": "เมื่อถูกกล่าวถึงเท่านั้น",

View file

@ -740,7 +740,6 @@
"Unable to fetch notification target list": "Bildirim hedef listesi çekilemedi", "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.", "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", "Enable audible notifications in web client": "Web istemcisinde sesli bildirimleri etkinleştir",
"Permalink": "Kalıcı Bağlantı(permalink)",
"Off": "Kapalı", "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", "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", "Mentions only": "Sadece Mention'lar",

View file

@ -232,7 +232,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": "Постійне посилання",
"Off": "Вимкнено", "Off": "Вимкнено",
"Riot does not know how to join a room on this network": "Riot не знає як приєднатись до кімнати у цій мережі", "Riot does not know how to join a room on this network": "Riot не знає як приєднатись до кімнати у цій мережі",
"Mentions only": "Тільки згадки", "Mentions only": "Тільки згадки",

View file

@ -1098,7 +1098,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": "永久链接",
"Off": "关闭", "Off": "关闭",
"Riot does not know how to join a room on this network": "Riot 不知道如何在此网络中加入聊天室", "Riot does not know how to join a room on this network": "Riot 不知道如何在此网络中加入聊天室",
"Mentions only": "只限提及", "Mentions only": "只限提及",

View file

@ -1125,7 +1125,6 @@
"Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室",
"Set Password": "設定密碼", "Set Password": "設定密碼",
"Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知",
"Permalink": "永久連結",
"Off": "關閉", "Off": "關閉",
"#example": "#範例", "#example": "#範例",
"Mentions only": "僅提及", "Mentions only": "僅提及",