Merge branch 'bwindels/redesign' into bwindels/resizehandles
This commit is contained in:
commit
01471abdc5
89 changed files with 2635 additions and 1287 deletions
|
@ -329,7 +329,7 @@ const LoggedInView = React.createClass({
|
|||
), true);
|
||||
},
|
||||
|
||||
_onClick: function(ev) {
|
||||
_onMouseDown: function(ev) {
|
||||
// When the panels are disabled, clicking on them results in a mouse event
|
||||
// which bubbles to certain elements in the tree. When this happens, close
|
||||
// any settings page that is currently open (user/room/group).
|
||||
|
@ -340,11 +340,37 @@ const LoggedInView = React.createClass({
|
|||
targetClasses.has('mx_MatrixChat_middlePanel') ||
|
||||
targetClasses.has('mx_RoomView')
|
||||
) {
|
||||
dis.dispatch({ action: 'close_settings' });
|
||||
this.setState({
|
||||
mouseDown: {
|
||||
x: ev.pageX,
|
||||
y: ev.pageY,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseUp: function(ev) {
|
||||
if (!this.state.mouseDown) return;
|
||||
|
||||
const deltaX = ev.pageX - this.state.mouseDown.x;
|
||||
const deltaY = ev.pageY - this.state.mouseDown.y;
|
||||
const distance = Math.sqrt((deltaX * deltaX) + (deltaY + deltaY));
|
||||
const maxRadius = 5; // People shouldn't be straying too far, hopefully
|
||||
|
||||
// Note: we track how far the user moved their mouse to help
|
||||
// combat against https://github.com/vector-im/riot-web/issues/7158
|
||||
|
||||
if (distance < maxRadius) {
|
||||
// This is probably a real click, and not a drag
|
||||
dis.dispatch({ action: 'close_settings' });
|
||||
}
|
||||
|
||||
// Always clear the mouseDown state to ensure we don't accidentally
|
||||
// use stale values due to the mouseDown checks.
|
||||
this.setState({mouseDown: null});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const LeftPanel = sdk.getComponent('structures.LeftPanel');
|
||||
const RightPanel = sdk.getComponent('structures.RightPanel');
|
||||
|
@ -488,7 +514,7 @@ const LoggedInView = React.createClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className='mx_MatrixChat_wrapper' aria-hidden={this.props.hideToSRUsers} onClick={this._onClick}>
|
||||
<div className='mx_MatrixChat_wrapper' aria-hidden={this.props.hideToSRUsers} onMouseDown={this._onMouseDown} onMouseUp={this._onMouseUp}>
|
||||
{ topBar }
|
||||
<DragDropContext onDragEnd={this._onDragEnd}>
|
||||
<div ref={(div) => this.resizeContainer = div} className={bodyClasses}>
|
||||
|
|
|
@ -48,6 +48,10 @@ import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
|||
import { startAnyRegistrationFlow } from "../../Registration.js";
|
||||
import { messageForSyncError } from '../../utils/ErrorUtils';
|
||||
|
||||
// Disable warnings for now: we use deprecated bluebird functions
|
||||
// and need to migrate, but they spam the console with warnings.
|
||||
Promise.config({warnings: false});
|
||||
|
||||
/** constants for MatrixChat.state.view */
|
||||
const VIEWS = {
|
||||
// a special initial state which is only used at startup, while we are
|
||||
|
@ -286,6 +290,14 @@ export default React.createClass({
|
|||
register_hs_url: paramHs,
|
||||
});
|
||||
}
|
||||
// Set a default IS with query param `is_url`
|
||||
const paramIs = this.props.startingFragmentQueryParams.is_url;
|
||||
if (paramIs) {
|
||||
console.log('Setting register_is_url ', paramIs);
|
||||
this.setState({
|
||||
register_is_url: paramIs,
|
||||
});
|
||||
}
|
||||
|
||||
// a thing to call showScreen with once login completes. this is kept
|
||||
// outside this.state because updating it should never trigger a
|
||||
|
@ -1253,8 +1265,11 @@ export default React.createClass({
|
|||
// its own dispatch).
|
||||
dis.dispatch({action: 'sync_state', prevState, state});
|
||||
|
||||
if (state === "ERROR") {
|
||||
self.setState({syncError: data.error});
|
||||
if (state === "ERROR" || state === "RECONNECTING") {
|
||||
if (data.error instanceof Matrix.InvalidStoreError) {
|
||||
Lifecycle.handleInvalidStoreError(data.error);
|
||||
}
|
||||
self.setState({syncError: data.error || true});
|
||||
} else if (self.state.syncError) {
|
||||
self.setState({syncError: null});
|
||||
}
|
||||
|
@ -1730,10 +1745,14 @@ export default React.createClass({
|
|||
}
|
||||
|
||||
if (this.state.view === VIEWS.LOGGED_IN) {
|
||||
// store errors stop the client syncing and require user intervention, so we'll
|
||||
// be showing a dialog. Don't show anything else.
|
||||
const isStoreError = this.state.syncError && this.state.syncError instanceof Matrix.InvalidStoreError;
|
||||
|
||||
// `ready` and `view==LOGGED_IN` may be set before `page_type` (because the
|
||||
// latter is set via the dispatcher). If we don't yet have a `page_type`,
|
||||
// keep showing the spinner for now.
|
||||
if (this.state.ready && this.state.page_type) {
|
||||
if (this.state.ready && this.state.page_type && !isStoreError) {
|
||||
/* for now, we stuff the entirety of our props and state into the LoggedInView.
|
||||
* we should go through and figure out what we actually need to pass down, as well
|
||||
* as using something like redux to avoid having a billion bits of state kicking around.
|
||||
|
@ -1755,7 +1774,7 @@ export default React.createClass({
|
|||
// we think we are logged in, but are still waiting for the /sync to complete
|
||||
const Spinner = sdk.getComponent('elements.Spinner');
|
||||
let errorBox;
|
||||
if (this.state.syncError) {
|
||||
if (this.state.syncError && !isStoreError) {
|
||||
errorBox = <div className="mx_MatrixChat_syncError">
|
||||
{messageForSyncError(this.state.syncError)}
|
||||
</div>;
|
||||
|
|
|
@ -542,7 +542,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
// get a list of read receipts that should be shown next to this event
|
||||
// Receipts are objects which have a 'roomMember' and 'ts'.
|
||||
// Receipts are objects which have a 'userId', 'roomMember' and 'ts'.
|
||||
_getReadReceiptsForEvent: function(event) {
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
|
||||
|
@ -560,10 +560,8 @@ module.exports = React.createClass({
|
|||
return; // ignore ignored users
|
||||
}
|
||||
const member = room.getMember(r.userId);
|
||||
if (!member) {
|
||||
return; // ignore unknown user IDs
|
||||
}
|
||||
receipts.push({
|
||||
userId: r.userId,
|
||||
roomMember: member,
|
||||
ts: r.data ? r.data.ts : 0,
|
||||
});
|
||||
|
|
|
@ -51,6 +51,7 @@ class HeaderButton extends React.Component {
|
|||
|
||||
return <AccessibleButton
|
||||
aria-label={this.props.title}
|
||||
aria-expanded={this.props.isHighlighted}
|
||||
title={this.props.title}
|
||||
className="mx_RightPanel_headerButton"
|
||||
onClick={this.onClick} >
|
||||
|
@ -345,11 +346,11 @@ module.exports = React.createClass({
|
|||
// being put in the RoomHeader or GroupView header, so only show the minimise
|
||||
// button on these 2 screens or you won't be able to re-expand the panel.
|
||||
headerButtons.push(
|
||||
<div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton"
|
||||
<AccessibleButton className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton"
|
||||
title={_t("Hide panel")} aria-label={_t("Hide panel")} onClick={this.onCollapseClick}
|
||||
>
|
||||
<TintableSvg src="img/minimise.svg" width="10" height="16" />
|
||||
</div>,
|
||||
<TintableSvg src="img/minimise.svg" width="10" height="16" alt="" />
|
||||
</AccessibleButton>,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -223,14 +223,15 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||
if (!this.props.atEndOfLiveTimeline) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_scrollDownIndicator"
|
||||
<AccessibleButton className="mx_RoomStatusBar_scrollDownIndicator"
|
||||
onClick={this.props.onScrollToBottomClick}>
|
||||
<img src="img/scrolldown.svg" width="24" height="24"
|
||||
alt={_t("Scroll to bottom of page")}
|
||||
title={_t("Scroll to bottom of page")} />
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -385,7 +386,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
return <div className="mx_RoomStatusBar_connectionLostBar">
|
||||
<img src="img/warning.svg" width="24" height="23" title={_t("Warning")} alt={_t("Warning")} />
|
||||
<img src="img/warning.svg" width="24" height="23" title={_t("Warning")} alt="" />
|
||||
<div>
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_title">
|
||||
{ title }
|
||||
|
@ -485,7 +486,9 @@ module.exports = React.createClass({
|
|||
<div className="mx_RoomStatusBar_indicator">
|
||||
{ indicator }
|
||||
</div>
|
||||
{ content }
|
||||
<div role="alert">
|
||||
{ content }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -195,6 +195,8 @@ module.exports = React.createClass({
|
|||
editingRoomSettings: RoomViewStore.isEditingSettings(),
|
||||
};
|
||||
|
||||
if (this.state.editingRoomSettings && !newState.editingRoomSettings) dis.dispatch({action: 'focus_composer'});
|
||||
|
||||
// Temporary logging to diagnose https://github.com/vector-im/riot-web/issues/4307
|
||||
console.log(
|
||||
'RVS update:',
|
||||
|
|
|
@ -804,7 +804,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
return (
|
||||
<div>
|
||||
<h3>{ _t("Debug Logs Submission") }</h3>
|
||||
<h3>{ _t("Submit Debug Logs") }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<p>{
|
||||
_t( "If you've submitted a bug via GitHub, debug logs can help " +
|
||||
|
@ -832,9 +832,9 @@ module.exports = React.createClass({
|
|||
<br />
|
||||
{ _t('Privacy is important to us, so we don\'t collect any personal'
|
||||
+ ' or identifiable data for our analytics.') }
|
||||
<div className="mx_UserSettings_advanced_spoiler" onClick={Analytics.showDetailsModal}>
|
||||
<AccessibleButton className="mx_UserSettings_advanced_spoiler" onClick={Analytics.showDetailsModal}>
|
||||
{ _t('Learn more about how we use analytics.') }
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
{ ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
|
||||
</div>
|
||||
</div>;
|
||||
|
@ -1066,9 +1066,9 @@ module.exports = React.createClass({
|
|||
_renderWebRtcDeviceSettings: function() {
|
||||
if (this.state.mediaDevices === false) {
|
||||
return (
|
||||
<p className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
||||
<AccessibleButton element="p" className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
||||
{ _t('Missing Media Permissions, click here to request.') }
|
||||
</p>
|
||||
</AccessibleButton>
|
||||
);
|
||||
} else if (!this.state.mediaDevices) return;
|
||||
|
||||
|
@ -1235,7 +1235,7 @@ module.exports = React.createClass({
|
|||
/>
|
||||
</div>
|
||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||
<img src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")}
|
||||
<AccessibleButton element="img" src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")}
|
||||
onClick={onRemoveClick} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1260,7 +1260,7 @@ module.exports = React.createClass({
|
|||
onValueChanged={this._onAddEmailEditFinished} />
|
||||
</div>
|
||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||
<AccessibleButton element="img" src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1329,13 +1329,13 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="mx_UserSettings_avatarPicker">
|
||||
<div className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
|
||||
<AccessibleButton className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
|
||||
<img src="img/cancel.svg"
|
||||
width="15" height="15"
|
||||
className="mx_filterFlipColor"
|
||||
alt={_t("Remove avatar")}
|
||||
title={_t("Remove avatar")} />
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
<div onClick={this.onAvatarPickerClick} className="mx_UserSettings_avatarPicker_imgContainer">
|
||||
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
||||
showUploadSection={false} className="mx_UserSettings_avatarPicker_img" />
|
||||
|
@ -1396,11 +1396,11 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{ _t('Access Token:') + ' ' }
|
||||
<span className="mx_UserSettings_advanced_spoiler"
|
||||
<AccessibleButton element="span" className="mx_UserSettings_advanced_spoiler"
|
||||
onClick={this._showSpoiler}
|
||||
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
||||
<{ _t("click to reveal") }>
|
||||
</span>
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
<div className="mx_UserSettings_advanced">
|
||||
{ _t("Homeserver is") } { MatrixClientPeg.get().getHomeserverUrl() }
|
||||
|
|
|
@ -321,6 +321,12 @@ module.exports = React.createClass({
|
|||
case "RegistrationForm.ERR_PHONE_NUMBER_INVALID":
|
||||
errMsg = _t('This doesn\'t look like a valid phone number.');
|
||||
break;
|
||||
case "RegistrationForm.ERR_MISSING_EMAIL":
|
||||
errMsg = _t('An email address is required to register on this homeserver.');
|
||||
break;
|
||||
case "RegistrationForm.ERR_MISSING_PHONE_NUMBER":
|
||||
errMsg = _t('A phone number is required to register on this homeserver.');
|
||||
break;
|
||||
case "RegistrationForm.ERR_USERNAME_INVALID":
|
||||
errMsg = _t('User names may only contain letters, numbers, dots, hyphens and underscores.');
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue