Merge branch 'develop' of https://github.com/matrix-org/matrix-react-sdk into rxl881/appFixes

This commit is contained in:
Richard Lewis 2017-08-18 15:35:01 +01:00
commit b7d46d91ed
26 changed files with 119 additions and 60 deletions

View file

@ -248,6 +248,25 @@ function textForPowerEvent(event) {
});
}
function textForWidgetEvent(event) {
const senderName = event.sender ? event.sender.name : event.getSender();
const previousContent = event.getPrevContent() || {};
const {name, type, url} = event.getContent() || {};
const widgetName = widgetName || name || type || previousContent.type || '';
// If the widget was removed, its content should be {}, but this is sufficiently
// equivalent to that condition.
if (url) {
return _t('%(senderName)s added a %(widgetName)swidget', {
senderName, widgetName,
});
} else {
return _t('%(senderName)s removed a %(widgetName)swidget', {
senderName, widgetName,
});
}
}
var handlers = {
'm.room.message': textForMessageEvent,
'm.room.name': textForRoomNameEvent,
@ -260,6 +279,8 @@ var handlers = {
'm.room.history_visibility': textForHistoryVisibilityEvent,
'm.room.encryption': textForEncryptionEvent,
'm.room.power_levels': textForPowerEvent,
'im.vector.modular.widgets': textForWidgetEvent,
};
module.exports = {

View file

@ -339,6 +339,15 @@ module.exports = React.createClass({
for (;i + 1 < this.props.events.length; i++) {
const collapsedMxEv = this.props.events[i + 1];
// Ignore redacted/hidden member events
if (!this._shouldShowEvent(collapsedMxEv)) {
// If this hidden event is the RM and in or at end of a MELS put RM after MELS.
if (collapsedMxEv.getId() === this.props.readMarkerEventId) {
readMarkerInMels = true;
}
continue;
}
if (!isMembershipChange(collapsedMxEv) ||
this._wantsDateSeparator(this.props.events[i], collapsedMxEv.getDate())) {
break;
@ -349,11 +358,6 @@ module.exports = React.createClass({
readMarkerInMels = true;
}
// Ignore redacted/hidden member events
if (!this._shouldShowEvent(collapsedMxEv)) {
continue;
}
summarisedEvents.push(collapsedMxEv);
}

View file

@ -28,6 +28,7 @@ import AppPermission from './AppPermission';
import AppWarning from './AppWarning';
import MessageSpinner from './MessageSpinner';
import WidgetUtils from '../../../WidgetUtils';
import dis from '../../../dispatcher';
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
const betaHelpMsg = 'This feature is currently experimental and is intended for beta testing only';
@ -44,6 +45,10 @@ export default React.createClass({
// Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer continer.
// This should be set to true when there is only one widget in the app drawer, otherwise it should be false.
fullWidth: React.PropTypes.bool,
// UserId of the current user
userId: React.PropTypes.string.isRequired,
// UserId of the entity that added / modified the widget
creatorUserId: React.PropTypes.string,
},
getDefaultProps: function() {
@ -59,7 +64,8 @@ export default React.createClass({
loading: false,
widgetUrl: this.props.url,
widgetPermissionId: widgetPermissionId,
hasPermissionToLoad: Boolean(hasPermissionToLoad === 'true'),
// Assume that widget has permission to load if we are the user who added it to the room, or if explicitly granted by the user
hasPermissionToLoad: hasPermissionToLoad === 'true' || this.props.userId === this.props.creatorUserId,
error: null,
deleting: false,
};
@ -177,11 +183,25 @@ export default React.createClass({
let appTileName = "No name";
if(this.props.name && this.props.name.trim()) {
appTileName = this.props.name.trim();
appTileName = appTileName[0].toUpperCase() + appTileName.slice(1).toLowerCase();
}
return appTileName;
},
onClickMenuBar: function(ev) {
ev.preventDefault();
// Ignore clicks on menu bar children
if (ev.target !== this.refs.menu_bar) {
return;
}
// Toggle the view state of the apps drawer
dis.dispatch({
action: 'appsDrawer',
show: !this.props.show,
});
},
render: function() {
let appTileBody;
@ -218,7 +238,7 @@ export default React.createClass({
/>
</div>
);
} else {
} else if (this.props.show) {
appTileBody = (
<div className="mx_AppTileBody">
<iframe
@ -253,7 +273,7 @@ export default React.createClass({
return (
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
<div className="mx_AppTileMenuBar">
<div ref="menu_bar" className="mx_AppTileMenuBar" onClick={this.onClickMenuBar}>
{this.formatAppTileName()}
<span className="mx_AppTileMenuBarWidgets">
<span className="mx_Beta" alt={betaHelpMsg} title={betaHelpMsg}>&#946;</span>

View file

@ -55,9 +55,6 @@ module.exports = React.createClass({
this.scalarClient = new ScalarAuthClient();
this.scalarClient.connect().done(() => {
this.forceUpdate();
if (this.state.apps && this.state.apps.length < 1) {
this.onClickAddWidget();
}
// TODO -- Handle Scalar errors
// },
// (err) => {
@ -66,6 +63,8 @@ module.exports = React.createClass({
// });
});
}
this.dispatcherRef = dis.register(this.onAction.bind(this));
},
componentWillUnmount: function() {
@ -73,6 +72,27 @@ module.exports = React.createClass({
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
}
dis.unregister(this.dispatcherRef);
},
componentWillReceiveProps(newProps) {
// Room has changed probably, update apps
this._updateApps();
},
onAction: function(action) {
switch (action.action) {
case 'appsDrawer':
// When opening the app draw when there aren't any apps, auto-launch the
// integrations manager to skip the awkward click on "Add widget"
if (action.show) {
const apps = this._getApps();
if (apps.length === 0) {
this._launchManageIntegrations();
}
}
break;
}
},
/**
@ -95,7 +115,7 @@ module.exports = React.createClass({
return pathTemplate;
},
_initAppConfig: function(appId, app) {
_initAppConfig: function(appId, app, sender) {
const user = MatrixClientPeg.get().getUser(this.props.userId);
const params = {
'$matrix_user_id': this.props.userId,
@ -113,6 +133,7 @@ module.exports = React.createClass({
app.id = appId;
app.name = app.name || app.type;
app.url = this.encodeUri(app.url, params);
app.creatorUserId = (sender && sender.userId) ? sender.userId : null;
return app;
},
@ -133,18 +154,12 @@ module.exports = React.createClass({
return appsStateEvents.filter((ev) => {
return ev.getContent().type && ev.getContent().url;
}).map((ev) => {
return this._initAppConfig(ev.getStateKey(), ev.getContent());
return this._initAppConfig(ev.getStateKey(), ev.getContent(), ev.sender);
});
},
_updateApps: function() {
const apps = this._getApps();
if (apps.length < 1) {
dis.dispatch({
action: 'appsDrawer',
show: false,
});
}
this.setState({
apps: apps,
});
@ -159,13 +174,21 @@ module.exports = React.createClass({
}
},
onClickAddWidget: function(e) {
if (e) {
e.preventDefault();
}
_launchManageIntegrations: function() {
const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ?
this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') :
null;
Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, {
src: src,
}, "mx_IntegrationsManager");
},
onClickAddWidget: function(e) {
e.preventDefault();
// Display a warning dialog if the max number of widgets have already been added to the room
if (this.state.apps && this.state.apps.length >= MAX_WIDGETS) {
const apps = this._getApps();
if (apps && apps.length >= MAX_WIDGETS) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const errorMsg = `The maximum number of ${MAX_WIDGETS} widgets have already been added to this room.`;
console.error(errorMsg);
@ -175,14 +198,7 @@ module.exports = React.createClass({
});
return;
}
const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ?
this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') :
null;
Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, {
src: src,
}, "mx_IntegrationsManager");
this._launchManageIntegrations();
},
render: function() {
@ -197,18 +213,26 @@ module.exports = React.createClass({
fullWidth={arr.length<2 ? true : false}
room={this.props.room}
userId={this.props.userId}
show={this.props.showApps}
creatorUserId={app.creatorUserId}
/>);
});
const addWidget = (
<div onClick={this.onClickAddWidget}
let addWidget;
if (this.props.showApps &&
this.state.apps &&
this.state.apps.length < 2 &&
this._canUserModify()
) {
addWidget = <div
onClick={this.onClickAddWidget}
role="button"
tabIndex="0"
className="mx_AddWidget_button"
title={_t('Add a widget')}>
[+] {_t('Add a widget')}
</div>
);
</div>;
}
return (
<div className="mx_AppsDrawer">

View file

@ -129,15 +129,17 @@ module.exports = React.createClass({
);
let appsDrawer = null;
if(UserSettingsStore.isFeatureEnabled('matrix_apps') && this.props.showApps) {
if(UserSettingsStore.isFeatureEnabled('matrix_apps')) {
appsDrawer = <AppsDrawer ref="appsDrawer"
room={this.props.room}
userId={this.props.userId}
maxHeight={this.props.maxHeight}/>;
maxHeight={this.props.maxHeight}
showApps={this.props.showApps}
/>;
}
return (
<div className="mx_RoomView_auxPanel" style={{maxHeight: this.props.maxHeight}} >
<div className={ appsDrawer ? "mx_RoomView_auxPanel mx_RoomView_auxPanel_apps" : "mx_RoomView_auxPanel" } style={{maxHeight: this.props.maxHeight}} >
{ appsDrawer }
{ fileDropTarget }
{ callView }

View file

@ -44,6 +44,8 @@ var eventTileTypes = {
'm.room.history_visibility' : 'messages.TextualEvent',
'm.room.encryption' : 'messages.TextualEvent',
'm.room.power_levels' : 'messages.TextualEvent',
'im.vector.modular.widgets': 'messages.TextualEvent',
};
var MAX_READ_AVATARS = 5;

View file

@ -792,7 +792,7 @@ module.exports = React.createClass({
<input type="checkbox" disabled={ !roomState.mayClientSendStateEvent("m.room.aliases", cli) }
onChange={ this._onToggle.bind(this, "isRoomPublished", true, false)}
checked={this.state.isRoomPublished}/>
{_t("List this room in %(domain)s's room directory?", { domain: MatrixClientPeg.get().getDomain() })}
{_t("Publish this room to the public in %(domain)s's room directory?", { domain: MatrixClientPeg.get().getDomain() })}
</label>
</div>
<div className="mx_RoomSettings_settings">

View file

@ -853,7 +853,7 @@
"device id: ": "Geräte-ID: ",
"Device key:": "Geräte-Schlüssel:",
"Email address (optional)": "E-Mail-Adresse (optional)",
"List this room in %(domain)s's room directory?": "Diesen Raum zum Raum-Verzeichnis von %(domain)s hinzufügen?",
"Publish this room to the public in %(domain)s's room directory?": "Diesen Raum mittels Raum-Verzeichnis von %(domain)s veröffentlichen?",
"Mobile phone number (optional)": "Mobilfunknummer (optional)",
"Password:": "Passwort:",
"Register": "Registrieren",

View file

@ -297,7 +297,6 @@
"left": "έφυγε",
"%(targetName)s left the room.": "Ο χρήστης %(targetName)s έφυγε από το δωμάτιο.",
"Level": "Επίπεδο",
"List this room in %(domain)s's room directory?": "Να εμφανίζεται το δωμάτιο στο γενικό ευρετήριο του διακομιστή %(domain)s;",
"Local addresses for this room:": "Τοπική διεύθυνση για το δωμάτιο:",
"Logged in as:": "Συνδεθήκατε ως:",
"Login as guest": "Σύνδεση ως επισκέπτης",

View file

@ -393,7 +393,7 @@
"left": "left",
"%(targetName)s left the room.": "%(targetName)s left the room.",
"Level:": "Level:",
"List this room in %(domain)s's room directory?": "List this room in %(domain)s's room directory?",
"Publish this room to the public in %(domain)s's room directory?": "Publish this room to the public in %(domain)s's room directory?",
"Local addresses for this room:": "Local addresses for this room:",
"Logged in as:": "Logged in as:",
"Login as guest": "Login as guest",
@ -972,5 +972,7 @@
"Failed to upload image": "Failed to upload image",
"Failed to update group": "Failed to update group",
"Hide avatars in user and room mentions": "Hide avatars in user and room mentions",
"%(senderName)s added a %(widgetName)swidget": "%(senderName)s added a %(widgetName)swidget",
"%(senderName)s removed a %(widgetName)swidget": "%(senderName)s removed a %(widgetName)swidget",
"Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>"
}

View file

@ -359,7 +359,7 @@
"left": "left",
"%(targetName)s left the room.": "%(targetName)s left the room.",
"Level": "Level",
"List this room in %(domain)s's room directory?": "List this room in %(domain)s's room directory?",
"Publish this room to the public in %(domain)s's room directory?": "Publish this room to the public in %(domain)s's room directory?",
"Local addresses for this room:": "Local addresses for this room:",
"Logged in as:": "Logged in as:",
"Login as guest": "Login as guest",

View file

@ -500,7 +500,6 @@
"Drop File Here": "Deje el fichero aquí",
"Guest access is disabled on this Home Server.": "El acceso de invitados está desactivado en este servidor.",
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Conecte con <voiceText>voz</voiceText> o <videoText>vídeo</videoText>.",
"List this room in %(domain)s's room directory?": "¿Mostrar esta sala en el directorio de %(domain)s?",
"Manage Integrations": "Gestionar integraciones",
"Markdown is disabled": "Markdown está desactivado",
"Markdown is enabled": "Markdown está activado",

View file

@ -464,7 +464,6 @@
"left": "atera da",
"%(targetName)s left the room.": "%(targetName)s erabiltzailea gelatik atera da.",
"Level:": "Maila:",
"List this room in %(domain)s's room directory?": "Gela hau %(domain)s's domeinuko gelen direktorioan zerrendatu?",
"Local addresses for this room:": "Gela honen tokiko helbideak:",
"Logged in as:": "Saioa hasteko erabiltzailea:",
"Login as guest": "Hasi saioa bisitari gisa",

View file

@ -813,7 +813,6 @@
"device id: ": "Identifiant appareil : ",
"Device key:": "Clé de lappareil :",
"Email address (optional)": "Adresse e-mail (facultatif)",
"List this room in %(domain)s's room directory?": "Lister ce salon dans le répertoire de %(domain)s ?",
"Mobile phone number (optional)": "Numéro de téléphone (facultatif)",
"Password:": "Mot de passe :",
"Register": "S'inscrire",

View file

@ -404,7 +404,6 @@
"left": "kilépett",
"%(targetName)s left the room.": "%(targetName)s elhagyta a szobát.",
"Level:": "Szint:",
"List this room in %(domain)s's room directory?": "%(domain)s szobát feltüntessük a szobák listájában?",
"Local addresses for this room:": "A szoba helyi címe:",
"Logged in as:": "Bejelentkezve mint:",
"Login as guest": "Belépés vendégként",

View file

@ -48,7 +48,6 @@
"%(count)s new messages.other": "新しい発言 %(count)s",
"Don't send typing notifications": "文字入力中であることを公表しない",
"Filter room members": "参加者検索",
"List this room in %(domain)s's room directory?": "この部屋を %(domain)s サーバの部屋一覧に公開する?",
"Send a message (unencrypted)": "ここに送信文を入力 (暗号化なし)",
"Send an encrypted message": "暗号文を送る",
"Show timestamps in 12 hour format (e.g. 2:30pm)": "発言時刻を12時間形式で表示 (例 2:30PM)",

View file

@ -405,7 +405,6 @@
"left": "떠났음",
"%(targetName)s left the room.": "%(targetName)s님이 방을 떠나셨어요.",
"Level:": "등급:",
"List this room in %(domain)s's room directory?": "%(domain)s's 방 목록에 이 방을 놓으시겠어요?",
"Local addresses for this room:": "이 방의 로컬 주소:",
"Logged in as:": "로그인:",
"Login as guest": "손님으로 로그인",

View file

@ -380,7 +380,6 @@
"left": "atstāja",
"%(targetName)s left the room.": "%(targetName)s atstāja istabu.",
"Level:": "Līmenis:",
"List this room in %(domain)s's room directory?": "Rādīt šo istabu %(domain)s kataloga sarakstā?",
"Local addresses for this room:": "Šīs istabas lokālās adreses:",
"Logged in as:": "Pierakstījās kā:",
"Login as guest": "Pierakstīties kā viesis",

View file

@ -480,7 +480,6 @@
"left": "verlaten",
"%(targetName)s left the room.": "%(targetName)s heeft de ruimte verlaten.",
"Level:": "Niveau:",
"List this room in %(domain)s's room directory?": "Deze ruimte in %(domain)s's ruimte catalogus vermelden?",
"Local addresses for this room:": "Lokale adressen voor deze ruimte:",
"Logged in as:": "Ingelogd als:",
"Login as guest": "Als gast inloggen",

View file

@ -862,7 +862,6 @@
"device id: ": "id do dispositivo: ",
"Device key:": "Chave do dispositivo:",
"Email address (optional)": "Endereço de e-mail (opcional)",
"List this room in %(domain)s's room directory?": "Deseja listar esta sala na lista pública de salas de %(domain)s?",
"Mobile phone number (optional)": "Número de telefone celular (opcional)",
"Password:": "Senha:",
"Register": "Registre-se",

View file

@ -863,7 +863,6 @@
"device id: ": "id do dispositivo: ",
"Device key:": "Chave do dispositivo:",
"Email address (optional)": "Endereço de e-mail (opcional)",
"List this room in %(domain)s's room directory?": "Deseja listar esta sala na lista pública de salas de %(domain)s?",
"Mobile phone number (optional)": "Número de telefone celular (opcional)",
"Password:": "Senha:",
"Register": "Registre-se",

View file

@ -702,7 +702,6 @@
"Invalid file%(extra)s": "Недопустимый файл%(extra)s",
"Invited": "Приглашен",
"Jump to first unread message.": "Перейти к первому непрочитанному сообщению.",
"List this room in %(domain)s's room directory?": "Показывать эту комнату в каталоге комнат %(domain)s?",
"Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств",
"Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)",
"Once you&#39;ve followed the link it contains, click below": "После перехода по ссылке, нажмите на кнопку ниже",

View file

@ -385,7 +385,6 @@
"left": "lämnade",
"%(targetName)s left the room.": "%(targetName)s lämnade rummet.",
"Level:": "Nivå:",
"List this room in %(domain)s's room directory?": "Visa det här rummet i katalogen på %(domain)s?",
"Local addresses for this room:": "Lokala adresser för rummet:",
"Logged in as:": "Inloggad som:",
"Login as guest": "Logga in som gäst",

View file

@ -231,7 +231,6 @@
"left and rejoined": "ออกแล้วกลับเข้าร่วมอีกครั้ง",
"left": "ออกไปแล้ว",
"%(targetName)s left the room.": "%(targetName)s ออกจากห้องแล้ว",
"List this room in %(domain)s's room directory?": "แสดงห้องนี้ในไดเรกทอรีห้องของ %(domain)s?",
"Logged in as:": "เข้าสู่ระบบในชื่อ:",
"Login as guest": "เข้าสู่ระบบในฐานะแขก",
"Logout": "ออกจากระบบ",

View file

@ -380,7 +380,6 @@
"left": "ayrıldı",
"%(targetName)s left the room.": "%(targetName)s odadan ayrıldı.",
"Level:": "Seviye :",
"List this room in %(domain)s's room directory?": "Bu oda %(domain)s' in oda dizininde listelensin mi ?",
"Local addresses for this room:": "Bu oda için yerel adresler :",
"Logged in as:": "Olarak giriş yaptı :",
"Login as guest": "Misafir olarak giriş yaptı",

View file

@ -517,7 +517,6 @@
"left and rejoined": "離開並重新加入",
"left": "離開",
"Level:": "等級:",
"List this room in %(domain)s's room directory?": "在 %(domain)s 的房間目錄中列出此房間嗎?",
"Local addresses for this room:": "此房間的本機地址:",
"Logged in as:": "登入為:",
"Logout": "登出",