mirror of https://github.com/vector-im/riot-web
first cut (untested)
parent
bcd1c7e099
commit
ebdac4ee50
|
@ -113,6 +113,34 @@ module.exports = {
|
|||
});
|
||||
},
|
||||
|
||||
getUrlPreviewsDisabled: function() {
|
||||
var event = MatrixClientPeg.get().getAccountData("org.matrix.preview_urls");
|
||||
return (event && event.disable);
|
||||
},
|
||||
|
||||
setUrlPreviewsDisabled: function(disabled) {
|
||||
// FIXME: handle errors
|
||||
MatrixClientPeg.get().setAccountData("org.matrix.preview_urls", {
|
||||
disable: disabled
|
||||
});
|
||||
},
|
||||
|
||||
getSyncedSettings: function() {
|
||||
return MatrixClientPeg.get().getAccountData("im.vector.web.settings") || {};
|
||||
},
|
||||
|
||||
getSyncedSetting: function(type) {
|
||||
var settings = this.getSyncedSettings();
|
||||
return settings[type];
|
||||
},
|
||||
|
||||
setSyncedSetting: function(type, value) {
|
||||
var settings = this.getSyncedSettings();
|
||||
settings[type] = value;
|
||||
// FIXME: handle errors
|
||||
MatrixClientPeg.get().setAccountData("im.vector.web.settings", settings);
|
||||
},
|
||||
|
||||
isFeatureEnabled: function(feature: string): boolean {
|
||||
return localStorage.getItem(`mx_labs_feature_${feature}`) === 'true';
|
||||
},
|
||||
|
|
|
@ -44,6 +44,9 @@ module.exports = React.createClass({
|
|||
// ID of an event to highlight. If undefined, no event will be highlighted.
|
||||
highlightedEventId: React.PropTypes.string,
|
||||
|
||||
// Should we show URL Previews
|
||||
showUrlPreview: React.PropTypes.bool,
|
||||
|
||||
// event after which we should show a read marker
|
||||
readMarkerEventId: React.PropTypes.string,
|
||||
|
||||
|
@ -365,6 +368,7 @@ module.exports = React.createClass({
|
|||
onWidgetLoad={this._onWidgetLoad}
|
||||
readReceipts={readReceipts}
|
||||
readReceiptMap={this._readReceiptMap}
|
||||
showUrlPreview={this.props.showUrlPreview}
|
||||
checkUnmounting={this._isUnmounting}
|
||||
eventSendStatus={mxEv.status}
|
||||
last={last} isSelectedEvent={highlight}/>
|
||||
|
|
|
@ -239,6 +239,8 @@ module.exports = React.createClass({
|
|||
MatrixClientPeg.get().stopPeeking();
|
||||
this._onRoomLoaded(this.state.room);
|
||||
}
|
||||
|
||||
_updatePreviewUrlVisibility(this.state.room);
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
|
@ -341,6 +343,10 @@ module.exports = React.createClass({
|
|||
// ignore events for other rooms
|
||||
if (!this.state.room || room.roomId != this.state.room.roomId) return;
|
||||
|
||||
if (event.getType() === "org.matrix.room.preview_urls") {
|
||||
_updatePreviewUrlVisibility(room);
|
||||
}
|
||||
|
||||
// ignore anything but real-time updates at the end of the room:
|
||||
// updates from pagination will happen when the paginate completes.
|
||||
if (toStartOfTimeline || !data || !data.liveEvent) return;
|
||||
|
@ -384,6 +390,40 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_updatePreviewUrlVisibility: function(room) {
|
||||
// check our per-room overrides
|
||||
var roomPreviewUrls = room.getAccountData("org.matrix.room.preview_urls");
|
||||
if (roomPreviewUrls && roomPreviewUrls.disabled !== undefined) {
|
||||
this.setState({
|
||||
showUrlPreview: !roomPreviewUrls.disabled
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// check our global disable override
|
||||
var userRoomPreviewUrls = MatrixClientPeg().get().getAccountData("org.matrix.preview_urls");
|
||||
if (userRoomPreviewUrls && userRoomPreviewUrls.disabled) {
|
||||
this.setState({
|
||||
showUrlPreview: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// check the room state event
|
||||
var roomStatePreviewUrls = room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||
if (roomStatePreviewUrls && roomStatePreviewUrls.disabled) {
|
||||
this.setState({
|
||||
showUrlPreview: false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, we assume they're on.
|
||||
this.setState({
|
||||
showUrlPreview: true;
|
||||
});
|
||||
},
|
||||
|
||||
onRoom: function(room) {
|
||||
// This event is fired when the room is 'stored' by the JS SDK, which
|
||||
// means it's now a fully-fledged room object ready to be used, so
|
||||
|
@ -416,12 +456,15 @@ module.exports = React.createClass({
|
|||
|
||||
onRoomAccountData: function(room, event) {
|
||||
if (room.roomId == this.props.roomId) {
|
||||
if (event.getType === "org.matrix.room.color_scheme") {
|
||||
if (event.getType() === "org.matrix.room.color_scheme") {
|
||||
var color_scheme = event.getContent();
|
||||
// XXX: we should validate the event
|
||||
console.log("Tinter.tint from onRoomAccountData");
|
||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||
}
|
||||
else if (event.getType() === "org.matrix.room.preview_urls") {
|
||||
_updatePreviewUrlVisibility(room);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1523,6 +1566,7 @@ module.exports = React.createClass({
|
|||
eventPixelOffset={this.props.eventPixelOffset}
|
||||
onScroll={ this.onMessageListScroll }
|
||||
onReadMarkerUpdated={ this._updateTopUnreadMessagesBar }
|
||||
showUrlPreview = { this.state.showUrlPreview }
|
||||
opacity={ this.props.opacity }
|
||||
/>);
|
||||
|
||||
|
|
|
@ -71,6 +71,9 @@ var TimelinePanel = React.createClass({
|
|||
// half way down the viewport.
|
||||
eventPixelOffset: React.PropTypes.number,
|
||||
|
||||
// Should we show URL Previews
|
||||
showUrlPreview: React.PropTypes.bool,
|
||||
|
||||
// callback which is called when the panel is scrolled.
|
||||
onScroll: React.PropTypes.func,
|
||||
|
||||
|
@ -934,6 +937,7 @@ var TimelinePanel = React.createClass({
|
|||
readMarkerEventId={ this.state.readMarkerEventId }
|
||||
readMarkerVisible={ this.state.readMarkerVisible }
|
||||
suppressFirstDateSeparator={ this.state.canBackPaginate }
|
||||
showUrlPreview = { this.state.showUrlPreview }
|
||||
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
||||
stickyBottom={ stickyBottom }
|
||||
onScroll={ this.onMessageListScroll }
|
||||
|
|
|
@ -261,6 +261,63 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
_renderUserInterfaceSettings: function() {
|
||||
var client = MatrixClientPeg.get();
|
||||
|
||||
var settingsLabels = [
|
||||
/*
|
||||
{
|
||||
id: 'alwaysShowTimestamps',
|
||||
label: 'Always show message timestamps',
|
||||
},
|
||||
{
|
||||
id: 'showTwelveHourTimestamps',
|
||||
label: 'Show timestamps in 12 hour format (e.g. 2:30pm)',
|
||||
},
|
||||
{
|
||||
id: 'useCompactLayout',
|
||||
label: 'Use compact timeline layout',
|
||||
},
|
||||
{
|
||||
id: 'useFixedWidthFont',
|
||||
label: 'Use fixed width font',
|
||||
},
|
||||
*/
|
||||
];
|
||||
|
||||
var syncedSettings = UserSettingsStore.getSyncedSettings();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>User Interface</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<div className="mx_UserSettings_toggle">
|
||||
<input id="urlPreviewsDisabled"
|
||||
type="checkbox"
|
||||
defaultChecked={ UserSettingsStore.getUrlPreviewsDisabled() }
|
||||
onChange={ e => UserSettingsStore.setUrlPreviewsDisabled(e.target.checked) }
|
||||
/>
|
||||
<label htmlFor="urlPreviewsDisabled">
|
||||
Disable inline URL previews by default
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{ settingsLabels.forEach( setting => {
|
||||
<div className="mx_UserSettings_toggle">
|
||||
<input id={ setting.id }
|
||||
type="checkbox"
|
||||
defaultChecked={ syncedSettings[setting.id] }
|
||||
onChange={ e => UserSettingsStore.setSyncedSetting(setting.id, e.target.checked) }
|
||||
/>
|
||||
<label htmlFor={ setting.id }>
|
||||
{ settings.label }
|
||||
</label>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
_renderDeviceInfo: function() {
|
||||
if (!UserSettingsStore.isFeatureEnabled("e2e_encryption")) {
|
||||
return null;
|
||||
|
@ -378,7 +435,7 @@ module.exports = React.createClass({
|
|||
|
||||
this._renderLabs = function () {
|
||||
let features = LABS_FEATURES.map(feature => (
|
||||
<div key={feature.id}>
|
||||
<div key={feature.id} className="mx_UserSettings_toggle">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={feature.id}
|
||||
|
@ -452,6 +509,8 @@ module.exports = React.createClass({
|
|||
|
||||
{notification_area}
|
||||
|
||||
{this._renderUserInterfaceSettings()}
|
||||
|
||||
{this._renderDeviceInfo()}
|
||||
|
||||
{this._renderLabs()}
|
||||
|
|
|
@ -38,6 +38,9 @@ module.exports = React.createClass({
|
|||
/* link URL for the highlights */
|
||||
highlightLink: React.PropTypes.string,
|
||||
|
||||
/* should show URL previews for this event */
|
||||
showUrlPreview: React.PropTypes.bool,
|
||||
|
||||
/* callback called when dynamic content in events are loaded */
|
||||
onWidgetLoad: React.PropTypes.func,
|
||||
},
|
||||
|
@ -71,6 +74,7 @@ module.exports = React.createClass({
|
|||
|
||||
return <BodyType ref="body" mxEvent={this.props.mxEvent} highlights={this.props.highlights}
|
||||
highlightLink={this.props.highlightLink}
|
||||
showUrlPreview={this.props.showUrlPreview}
|
||||
onWidgetLoad={this.props.onWidgetLoad} />;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -39,6 +39,9 @@ module.exports = React.createClass({
|
|||
/* link URL for the highlights */
|
||||
highlightLink: React.PropTypes.string,
|
||||
|
||||
/* should show URL previews for this event */
|
||||
showUrlPreview: React.PropTypes.bool,
|
||||
|
||||
/* callback for when our widget has loaded */
|
||||
onWidgetLoad: React.PropTypes.func,
|
||||
},
|
||||
|
@ -57,16 +60,18 @@ module.exports = React.createClass({
|
|||
componentDidMount: function() {
|
||||
linkifyElement(this.refs.content, linkifyMatrix.options);
|
||||
|
||||
var links = this.findLinks(this.refs.content.children);
|
||||
if (links.length) {
|
||||
this.setState({ links: links.map((link)=>{
|
||||
return link.getAttribute("href");
|
||||
})});
|
||||
if (this.props.showUrlPreview) {
|
||||
var links = this.findLinks(this.refs.content.children);
|
||||
if (links.length) {
|
||||
this.setState({ links: links.map((link)=>{
|
||||
return link.getAttribute("href");
|
||||
})});
|
||||
|
||||
// lazy-load the hidden state of the preview widget from localstorage
|
||||
if (global.localStorage) {
|
||||
var hidden = global.localStorage.getItem("hide_preview_" + this.props.mxEvent.getId());
|
||||
this.setState({ widgetHidden: hidden });
|
||||
// lazy-load the hidden state of the preview widget from localstorage
|
||||
if (global.localStorage) {
|
||||
var hidden = global.localStorage.getItem("hide_preview_" + this.props.mxEvent.getId());
|
||||
this.setState({ widgetHidden: hidden });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,9 +168,11 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
var mxEvent = this.props.mxEvent;
|
||||
var content = mxEvent.getContent();
|
||||
var body = HtmlUtils.bodyToHtml(content, this.props.highlights,
|
||||
{highlightLink: this.props.highlightLink});
|
||||
var body = HtmlUtils.bodyToHtml(content, this.props.highlights, {});
|
||||
|
||||
if (this.props.highlightLink) {
|
||||
body = <a href={ this.props.highlightLink }>{ body }</a>;
|
||||
}
|
||||
|
||||
var widgets;
|
||||
if (this.state.links.length && !this.state.widgetHidden) {
|
||||
|
|
|
@ -57,7 +57,7 @@ module.exports = React.createClass({
|
|||
data.primary_color = scheme.primary_color;
|
||||
data.secondary_color = scheme.secondary_color;
|
||||
data.index = this._getColorIndex(data);
|
||||
|
||||
|
||||
if (data.index === -1) {
|
||||
// append the unrecognised colours to our palette
|
||||
data.index = ROOM_COLORS.length;
|
||||
|
|
|
@ -101,6 +101,9 @@ module.exports = React.createClass({
|
|||
/* link URL for the highlights */
|
||||
highlightLink: React.PropTypes.string,
|
||||
|
||||
/* should show URL previews for this event */
|
||||
showUrlPreview: React.PropTypes.bool,
|
||||
|
||||
/* is this the focused event */
|
||||
isSelectedEvent: React.PropTypes.bool,
|
||||
|
||||
|
@ -420,6 +423,7 @@ module.exports = React.createClass({
|
|||
<div className="mx_EventTile_line">
|
||||
<EventTileType ref="tile" mxEvent={this.props.mxEvent} highlights={this.props.highlights}
|
||||
highlightLink={this.props.highlightLink}
|
||||
showUrlPreview={this.props.showUrlPreview}
|
||||
onWidgetLoad={this.props.onWidgetLoad} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -422,6 +422,7 @@ module.exports = React.createClass({
|
|||
|
||||
var AliasSettings = sdk.getComponent("room_settings.AliasSettings");
|
||||
var ColorSettings = sdk.getComponent("room_settings.ColorSettings");
|
||||
var UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings");
|
||||
var EditableText = sdk.getComponent('elements.EditableText');
|
||||
var PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||
|
||||
|
@ -654,6 +655,8 @@ module.exports = React.createClass({
|
|||
canonicalAliasEvent={this.props.room.currentState.getStateEvents('m.room.canonical_alias', '')}
|
||||
aliasEvents={this.props.room.currentState.getStateEvents('m.room.aliases')} />
|
||||
|
||||
<UrlPreviewSettings ref="url_preview_settings" room={this.props.room} />
|
||||
|
||||
<h3>Permissions</h3>
|
||||
<div className="mx_RoomSettings_powerLevels mx_RoomSettings_settings">
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
|
|
Loading…
Reference in New Issue