Improve decryption error UI by consolidating error messages and providing instructions when possible (#9544)
* Improve decryption error UI by consolidating error messages and providing instructions when possible * Fix TS strict errors * Rename .scss to .pcss * Avoid accessing clipboard, Cypress doesn't like it * Display DecryptionFailureBar alongside other AuxPanel bars * Add comments * Add small margin off-screen for visible decryption failures * Fix some more TS strict errors * Add unit tests for DecryptionFailureBar * Add button to resend key requests manually * Remove references to matrix-js-sdk crypto internals * Add hysteresis to visible decryption failures * Add comment Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Add comment Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Don't create empty div if we're not showing resend requests button * cancel updateSessions on unmount * Update unit tests * Fix lint and implicit any * Simplify visible event bounds checking * Adjust cypress test descriptions * Add percy snapshots * Update src/components/structures/TimelinePanel.tsx Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Add comments on TimelinePanel IState * comment * Add names to percy snapshots * Show Resend Key Requests button when there are sessions that haven't already been requested via this bar * We no longer request keys from senders * update i18n * update expected text in cypress test * don't download keys ourselves, update device info in response to updates from client * fix ts strict errors * visibledecryptionfailures undefined handling * Fix implicitAny errors Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
b728b27435
commit
4724506320
18 changed files with 1779 additions and 165 deletions
|
@ -64,6 +64,9 @@ const READ_RECEIPT_INTERVAL_MS = 500;
|
|||
|
||||
const READ_MARKER_DEBOUNCE_MS = 100;
|
||||
|
||||
// How far off-screen a decryption failure can be for it to still count as "visible"
|
||||
const VISIBLE_DECRYPTION_FAILURE_MARGIN = 100;
|
||||
|
||||
const debuglog = (...args: any[]) => {
|
||||
if (SettingsStore.getValue("debug_timeline_panel")) {
|
||||
logger.log.call(console, "TimelinePanel debuglog:", ...args);
|
||||
|
@ -149,7 +152,9 @@ interface IProps {
|
|||
}
|
||||
|
||||
interface IState {
|
||||
// All events, including still-pending events being sent by us
|
||||
events: MatrixEvent[];
|
||||
// Only events that are actually in the live timeline
|
||||
liveEvents: MatrixEvent[];
|
||||
// track whether our room timeline is loading
|
||||
timelineLoading: boolean;
|
||||
|
@ -1690,6 +1695,45 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||
return index > -1 ? index : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of undecryptable events currently visible on-screen.
|
||||
*
|
||||
* @param {boolean} addMargin Whether to add an extra margin beyond the viewport
|
||||
* where events are still considered "visible"
|
||||
*
|
||||
* @returns {MatrixEvent[] | null} A list of undecryptable events, or null if
|
||||
* the list of events could not be determined.
|
||||
*/
|
||||
public getVisibleDecryptionFailures(addMargin?: boolean): MatrixEvent[] | null {
|
||||
const messagePanel = this.messagePanel.current;
|
||||
if (!messagePanel) return null;
|
||||
|
||||
const messagePanelNode = ReactDOM.findDOMNode(messagePanel) as Element;
|
||||
if (!messagePanelNode) return null; // sometimes this happens for fresh rooms/post-sync
|
||||
const wrapperRect = messagePanelNode.getBoundingClientRect();
|
||||
const margin = addMargin ? VISIBLE_DECRYPTION_FAILURE_MARGIN : 0;
|
||||
const screenTop = wrapperRect.top - margin;
|
||||
const screenBottom = wrapperRect.bottom + margin;
|
||||
|
||||
const result: MatrixEvent[] = [];
|
||||
for (const ev of this.state.liveEvents) {
|
||||
const eventId = ev.getId();
|
||||
if (!eventId) continue;
|
||||
const node = messagePanel.getNodeForEventId(eventId);
|
||||
if (!node) continue;
|
||||
|
||||
const boundingRect = node.getBoundingClientRect();
|
||||
if (boundingRect.top > screenBottom) {
|
||||
// we have gone past the visible section of timeline
|
||||
break;
|
||||
} else if (boundingRect.bottom >= screenTop) {
|
||||
// the tile for this event is in the visible part of the screen (or just above/below it).
|
||||
if (ev.isDecryptionFailure()) result.push(ev);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private getLastDisplayedEventIndex(opts: IEventIndexOpts = {}): number | null {
|
||||
const ignoreOwn = opts.ignoreOwn || false;
|
||||
const allowPartial = opts.allowPartial || false;
|
||||
|
@ -1702,7 +1746,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||
const wrapperRect = messagePanelNode.getBoundingClientRect();
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
|
||||
const isNodeInView = (node) => {
|
||||
const isNodeInView = (node: HTMLElement) => {
|
||||
if (node) {
|
||||
const boundingRect = node.getBoundingClientRect();
|
||||
if (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue