try to fix test

Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into joriks/delabs-font-scaling
This commit is contained in:
Jorik Schellekens 2020-07-13 19:08:44 +01:00
commit 6bf6ae2031
8 changed files with 78 additions and 37 deletions

View file

@ -48,15 +48,15 @@ limitations under the License.
} }
&.mx_NotificationBadge_2char { &.mx_NotificationBadge_2char {
width: 16px; width: $font-16px;
height: 16px; height: $font-16px;
border-radius: 16px; border-radius: $font-16px;
} }
&.mx_NotificationBadge_3char { &.mx_NotificationBadge_3char {
width: 26px; width: $font-26px;
height: 16px; height: $font-16px;
border-radius: 16px; border-radius: $font-16px;
} }
// The following is the floating badge // The following is the floating badge

View file

@ -50,7 +50,7 @@ import PageTypes from '../../PageTypes';
import { getHomePageUrl } from '../../utils/pages'; import { getHomePageUrl } from '../../utils/pages';
import createRoom from "../../createRoom"; import createRoom from "../../createRoom";
import { _t, getCurrentLanguage } from '../../languageHandler'; import {_t, _td, getCurrentLanguage} from '../../languageHandler';
import SettingsStore, { SettingLevel } from "../../settings/SettingsStore"; import SettingsStore, { SettingLevel } from "../../settings/SettingsStore";
import ThemeController from "../../settings/controllers/ThemeController"; import ThemeController from "../../settings/controllers/ThemeController";
import { startAnyRegistrationFlow } from "../../Registration.js"; import { startAnyRegistrationFlow } from "../../Registration.js";
@ -74,6 +74,7 @@ import {
} from "../../toasts/AnalyticsToast"; } from "../../toasts/AnalyticsToast";
import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast"; import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload"; import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import ErrorDialog from "../views/dialogs/ErrorDialog";
/** constants for MatrixChat.state.view */ /** constants for MatrixChat.state.view */
export enum Views { export enum Views {
@ -460,7 +461,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
onAction = (payload) => { onAction = (payload) => {
// console.log(`MatrixClientPeg.onAction: ${payload.action}`); // console.log(`MatrixClientPeg.onAction: ${payload.action}`);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// Start the onboarding process for certain actions // Start the onboarding process for certain actions
@ -554,6 +554,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
case 'leave_room': case 'leave_room':
this.leaveRoom(payload.room_id); this.leaveRoom(payload.room_id);
break; break;
case 'forget_room':
this.forgetRoom(payload.room_id);
break;
case 'reject_invite': case 'reject_invite':
Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, { Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, {
title: _t('Reject invitation'), title: _t('Reject invitation'),
@ -1060,7 +1063,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
private leaveRoom(roomId: string) { private leaveRoom(roomId: string) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const roomToLeave = MatrixClientPeg.get().getRoom(roomId); const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
const warnings = this.leaveRoomWarnings(roomId); const warnings = this.leaveRoomWarnings(roomId);
@ -1124,6 +1126,21 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}); });
} }
private forgetRoom(roomId: string) {
MatrixClientPeg.get().forget(roomId).then(() => {
// Switch to another room view if we're currently viewing the historical room
if (this.state.currentRoomId === roomId) {
dis.dispatch({ action: "view_next_room" });
}
}).catch((err) => {
const errCode = err.errcode || _td("unknown error code");
Modal.createTrackedDialog("Failed to forget room", '', ErrorDialog, {
title: _t("Failed to forget room %(errCode)s", {errCode}),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
});
}
/** /**
* Starts a chat with the welcome user, if the user doesn't already have one * Starts a chat with the welcome user, if the user doesn't already have one
* @returns {string} The room ID of the new room, or null if no room was created * @returns {string} The room ID of the new room, or null if no room was created
@ -1372,7 +1389,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
return; return;
} }
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Signed out', '', ErrorDialog, { Modal.createTrackedDialog('Signed out', '', ErrorDialog, {
title: _t('Signed Out'), title: _t('Signed Out'),
description: _t('For security, this session has been signed out. Please sign in again.'), description: _t('For security, this session has been signed out. Please sign in again.'),
@ -1442,7 +1458,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
} }
}); });
cli.on("crypto.warning", (type) => { cli.on("crypto.warning", (type) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
switch (type) { switch (type) {
case 'CRYPTO_WARNING_OLD_VERSION_DETECTED': case 'CRYPTO_WARNING_OLD_VERSION_DETECTED':
Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, { Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, {

View file

@ -1380,15 +1380,9 @@ export default createReactClass({
}, },
onForgetClick: function() { onForgetClick: function() {
this.context.forget(this.state.room.roomId).then(function() { dis.dispatch({
dis.dispatch({ action: 'view_next_room' }); action: 'forget_room',
}, function(err) { room_id: this.state.room.roomId,
const errCode = err.errcode || _t("unknown error code");
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
title: _t("Error"),
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
});
}); });
}, },

View file

@ -321,25 +321,29 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
} }
}; };
private onHeaderClick = (ev: React.MouseEvent<HTMLDivElement>) => { private onHeaderClick = () => {
let target = ev.target as HTMLDivElement; const possibleSticky = this.headerButton.current.parentElement;
if (!target.classList.contains('mx_RoomSublist2_headerText')) {
// If we don't have the headerText class, the user clicked the span in the headerText.
target = target.parentElement as HTMLDivElement;
}
const possibleSticky = target.parentElement;
const sublist = possibleSticky.parentElement.parentElement; const sublist = possibleSticky.parentElement.parentElement;
const list = sublist.parentElement.parentElement; const list = sublist.parentElement.parentElement;
// the scrollTop is capped at the height of the header in LeftPanel2 // the scrollTop is capped at the height of the header in LeftPanel2, the top header is always sticky
const isAtTop = list.scrollTop <= HEADER_HEIGHT; const isAtTop = list.scrollTop <= HEADER_HEIGHT;
const isSticky = possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_sticky'); const isAtBottom = list.scrollTop >= list.scrollHeight - list.offsetHeight;
if (isSticky && !isAtTop) { const isStickyTop = possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_stickyTop');
const isStickyBottom = possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_stickyBottom');
if ((isStickyBottom && !isAtBottom) || (isStickyTop && !isAtTop)) {
// is sticky - jump to list // is sticky - jump to list
sublist.scrollIntoView({behavior: 'smooth'}); sublist.scrollIntoView({behavior: 'smooth'});
} else { } else {
// on screen - toggle collapse // on screen - toggle collapse
const isExpanded = this.state.isExpanded;
this.toggleCollapsed(); this.toggleCollapsed();
// if the bottom list is collapsed then scroll it in so it doesn't expand off screen
if (!isExpanded && isStickyBottom) {
setImmediate(() => {
sublist.scrollIntoView({behavior: 'smooth'});
});
}
} }
}; };

View file

@ -276,6 +276,17 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
this.setState({generalMenuPosition: null}); // hide the menu this.setState({generalMenuPosition: null}); // hide the menu
}; };
private onForgetRoomClick = (ev: ButtonEvent) => {
ev.preventDefault();
ev.stopPropagation();
dis.dispatch({
action: 'forget_room',
room_id: this.props.room.roomId,
});
this.setState({generalMenuPosition: null}); // hide the menu
};
private onOpenRoomSettings = (ev: ButtonEvent) => { private onOpenRoomSettings = (ev: ButtonEvent) => {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
@ -315,7 +326,7 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
private onClickMute = ev => this.saveNotifState(ev, MUTE); private onClickMute = ev => this.saveNotifState(ev, MUTE);
private renderNotificationsMenu(isActive: boolean): React.ReactElement { private renderNotificationsMenu(isActive: boolean): React.ReactElement {
if (MatrixClientPeg.get().isGuest() || !this.showContextMenu) { if (MatrixClientPeg.get().isGuest() || this.props.tag === DefaultTagID.Archived || !this.showContextMenu) {
// the menu makes no sense in these cases so do not show one // the menu makes no sense in these cases so do not show one
return null; return null;
} }
@ -397,7 +408,20 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
const favouriteLabel = isFavorite ? _t("Favourited") : _t("Favourite"); const favouriteLabel = isFavorite ? _t("Favourited") : _t("Favourite");
let contextMenu = null; let contextMenu = null;
if (this.state.generalMenuPosition) { if (this.state.generalMenuPosition && this.props.tag === DefaultTagID.Archived) {
contextMenu = (
<ContextMenu {...contextMenuBelow(this.state.generalMenuPosition)} onFinished={this.onCloseGeneralMenu}>
<div className="mx_IconizedContextMenu mx_IconizedContextMenu_compact mx_RoomTile2_contextMenu">
<div className="mx_IconizedContextMenu_optionList mx_RoomTile2_contextMenu_redRow">
<MenuItem onClick={this.onForgetRoomClick} label={_t("Leave Room")}>
<span className="mx_IconizedContextMenu_icon mx_RoomTile2_iconSignOut" />
<span className="mx_IconizedContextMenu_label">{_t("Forget Room")}</span>
</MenuItem>
</div>
</div>
</ContextMenu>
);
} else if (this.state.generalMenuPosition) {
contextMenu = ( contextMenu = (
<ContextMenu {...contextMenuBelow(this.state.generalMenuPosition)} onFinished={this.onCloseGeneralMenu}> <ContextMenu {...contextMenuBelow(this.state.generalMenuPosition)} onFinished={this.onCloseGeneralMenu}>
<div className="mx_IconizedContextMenu mx_IconizedContextMenu_compact mx_RoomTile2_contextMenu"> <div className="mx_IconizedContextMenu mx_IconizedContextMenu_compact mx_RoomTile2_contextMenu">

View file

@ -1232,6 +1232,7 @@
"Favourited": "Favourited", "Favourited": "Favourited",
"Favourite": "Favourite", "Favourite": "Favourite",
"Leave Room": "Leave Room", "Leave Room": "Leave Room",
"Forget Room": "Forget Room",
"Room options": "Room options", "Room options": "Room options",
"Add a topic": "Add a topic", "Add a topic": "Add a topic",
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.", "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.",

View file

@ -30,7 +30,6 @@ import { TagWatcher } from "./TagWatcher";
import RoomViewStore from "../RoomViewStore"; import RoomViewStore from "../RoomViewStore";
import { Algorithm, LIST_UPDATED_EVENT } from "./algorithms/Algorithm"; import { Algorithm, LIST_UPDATED_EVENT } from "./algorithms/Algorithm";
import { EffectiveMembership, getEffectiveMembership } from "./membership"; import { EffectiveMembership, getEffectiveMembership } from "./membership";
import { ListLayout } from "./ListLayout";
import { isNullOrUndefined } from "matrix-js-sdk/src/utils"; import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
import RoomListLayoutStore from "./RoomListLayoutStore"; import RoomListLayoutStore from "./RoomListLayoutStore";
import { MarkedExecution } from "../../utils/MarkedExecution"; import { MarkedExecution } from "../../utils/MarkedExecution";
@ -425,7 +424,8 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
// logic must match calculateListOrder // logic must match calculateListOrder
private calculateTagSorting(tagId: TagID): SortAlgorithm { private calculateTagSorting(tagId: TagID): SortAlgorithm {
const defaultSort = SortAlgorithm.Alphabetic; const isDefaultRecent = tagId === DefaultTagID.Invite || tagId === DefaultTagID.DM;
const defaultSort = isDefaultRecent ? SortAlgorithm.Recent : SortAlgorithm.Alphabetic;
const settingAlphabetical = SettingsStore.getValue("RoomList.orderAlphabetically", null, true); const settingAlphabetical = SettingsStore.getValue("RoomList.orderAlphabetically", null, true);
const definedSort = this.getTagSorting(tagId); const definedSort = this.getTagSorting(tagId);
const storedSort = this.getStoredTagSorting(tagId); const storedSort = this.getStoredTagSorting(tagId);

View file

@ -38,7 +38,11 @@ export class RecentAlgorithm implements IAlgorithm {
// actually changed (probably needs to be done higher up?) then we could do an // actually changed (probably needs to be done higher up?) then we could do an
// insertion sort or similar on the limited set of changes. // insertion sort or similar on the limited set of changes.
const myUserId = MatrixClientPeg.get().getUserId(); // TODO: Don't assume we're using the same client as the peg
let myUserId = '';
if (MatrixClientPeg.get()) {
myUserId = MatrixClientPeg.get().getUserId();
}
const tsCache: { [roomId: string]: number } = {}; const tsCache: { [roomId: string]: number } = {};
const getLastTs = (r: Room) => { const getLastTs = (r: Room) => {
@ -68,7 +72,6 @@ export class RecentAlgorithm implements IAlgorithm {
const ev = r.timeline[i]; const ev = r.timeline[i];
if (!ev.getTs()) continue; // skip events that don't have timestamps (tests only?) if (!ev.getTs()) continue; // skip events that don't have timestamps (tests only?)
// TODO: Don't assume we're using the same client as the peg
if (ev.getSender() === myUserId || Unread.eventTriggersUnreadCount(ev)) { if (ev.getSender() === myUserId || Unread.eventTriggersUnreadCount(ev)) {
return ev.getTs(); return ev.getTs();
} }