Hide "delete for everyone" button for pending messages

This commit is contained in:
Evan Hahn 2021-12-02 15:28:19 -06:00 committed by GitHub
parent ee8d0196b1
commit c88cb62464
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 44 deletions

View file

@ -288,7 +288,7 @@ type State = {
reactionViewerRoot: HTMLDivElement | null; reactionViewerRoot: HTMLDivElement | null;
reactionPickerRoot: HTMLDivElement | null; reactionPickerRoot: HTMLDivElement | null;
canDeleteForEveryone: boolean; hasDeleteForEveryoneTimerExpired: boolean;
}; };
const EXPIRATION_CHECK_MINIMUM = 2000; const EXPIRATION_CHECK_MINIMUM = 2000;
@ -328,20 +328,15 @@ export class Message extends React.PureComponent<Props, State> {
reactionViewerRoot: null, reactionViewerRoot: null,
reactionPickerRoot: null, reactionPickerRoot: null,
canDeleteForEveryone: props.canDeleteForEveryone, hasDeleteForEveryoneTimerExpired:
this.getTimeRemainingForDeleteForEveryone() <= 0,
}; };
} }
public static getDerivedStateFromProps(props: Props, state: State): State { public static getDerivedStateFromProps(props: Props, state: State): State {
const newState = {
...state,
canDeleteForEveryone:
props.canDeleteForEveryone && state.canDeleteForEveryone,
};
if (!props.isSelected) { if (!props.isSelected) {
return { return {
...newState, ...state,
isSelected: false, isSelected: false,
prevSelectedCounter: 0, prevSelectedCounter: 0,
}; };
@ -352,13 +347,13 @@ export class Message extends React.PureComponent<Props, State> {
props.isSelectedCounter !== state.prevSelectedCounter props.isSelectedCounter !== state.prevSelectedCounter
) { ) {
return { return {
...newState, ...state,
isSelected: props.isSelected, isSelected: props.isSelected,
prevSelectedCounter: props.isSelectedCounter, prevSelectedCounter: props.isSelectedCounter,
}; };
} }
return newState; return state;
} }
private hasReactions(): boolean { private hasReactions(): boolean {
@ -423,7 +418,7 @@ export class Message extends React.PureComponent<Props, State> {
public override componentDidMount(): void { public override componentDidMount(): void {
this.startSelectedTimer(); this.startSelectedTimer();
this.startDeleteForEveryoneTimer(); this.startDeleteForEveryoneTimerIfApplicable();
const { isSelected } = this.props; const { isSelected } = this.props;
if (isSelected) { if (isSelected) {
@ -466,9 +461,10 @@ export class Message extends React.PureComponent<Props, State> {
} }
public override componentDidUpdate(prevProps: Props): void { public override componentDidUpdate(prevProps: Props): void {
const { canDeleteForEveryone, isSelected, status, timestamp } = this.props; const { isSelected, status, timestamp } = this.props;
this.startSelectedTimer(); this.startSelectedTimer();
this.startDeleteForEveryoneTimerIfApplicable();
if (!prevProps.isSelected && isSelected) { if (!prevProps.isSelected && isSelected) {
this.setFocus(); this.setFocus();
@ -477,10 +473,6 @@ export class Message extends React.PureComponent<Props, State> {
this.checkExpired(); this.checkExpired();
this.checkForHeightChange(prevProps); this.checkForHeightChange(prevProps);
if (canDeleteForEveryone !== prevProps.canDeleteForEveryone) {
this.startDeleteForEveryoneTimer();
}
if ( if (
prevProps.status === 'sending' && prevProps.status === 'sending' &&
(status === 'sent' || (status === 'sent' ||
@ -534,27 +526,32 @@ export class Message extends React.PureComponent<Props, State> {
} }
} }
public startDeleteForEveryoneTimer(): void { private getTimeRemainingForDeleteForEveryone(): number {
if (this.deleteForEveryoneTimeout) { const { timestamp } = this.props;
clearTimeout(this.deleteForEveryoneTimeout); return Math.max(timestamp - Date.now() + THREE_HOURS, 0);
} }
private canDeleteForEveryone(): boolean {
const { canDeleteForEveryone } = this.props; const { canDeleteForEveryone } = this.props;
const { hasDeleteForEveryoneTimerExpired } = this.state;
return canDeleteForEveryone && !hasDeleteForEveryoneTimerExpired;
}
if (!canDeleteForEveryone) { private startDeleteForEveryoneTimerIfApplicable(): void {
const { canDeleteForEveryone } = this.props;
const { hasDeleteForEveryoneTimerExpired } = this.state;
if (
!canDeleteForEveryone ||
hasDeleteForEveryoneTimerExpired ||
this.deleteForEveryoneTimeout
) {
return; return;
} }
const { timestamp } = this.props; this.deleteForEveryoneTimeout = setTimeout(() => {
const timeToDeletion = timestamp - Date.now() + THREE_HOURS; this.setState({ hasDeleteForEveryoneTimerExpired: true });
delete this.deleteForEveryoneTimeout;
if (timeToDeletion <= 0) { }, this.getTimeRemainingForDeleteForEveryone());
this.setState({ canDeleteForEveryone: false });
} else {
this.deleteForEveryoneTimeout = setTimeout(() => {
this.setState({ canDeleteForEveryone: false });
}, timeToDeletion);
}
} }
public checkExpired(): void { public checkExpired(): void {
@ -1527,8 +1524,6 @@ export class Message extends React.PureComponent<Props, State> {
const canForward = !isTapToView && !deletedForEveryone; const canForward = !isTapToView && !deletedForEveryone;
const { canDeleteForEveryone } = this.state;
const showRetry = const showRetry =
(status === 'paused' || (status === 'paused' ||
status === 'error' || status === 'error' ||
@ -1647,7 +1642,7 @@ export class Message extends React.PureComponent<Props, State> {
> >
{i18n('deleteMessage')} {i18n('deleteMessage')}
</MenuItem> </MenuItem>
{canDeleteForEveryone ? ( {this.canDeleteForEveryone() ? (
<MenuItem <MenuItem
attributes={{ attributes={{
className: className:

View file

@ -1493,11 +1493,8 @@ export function canDeleteForEveryone(
!message.deletedForEveryone && !message.deletedForEveryone &&
// Is it too old to delete? // Is it too old to delete?
isMoreRecentThan(message.sent_at, THREE_HOURS) && isMoreRecentThan(message.sent_at, THREE_HOURS) &&
// Is it pending/sent to anyone? // Is it sent to anyone?
someSendStatus( someSendStatus(message.sendStateByConversationId, isSent)
message.sendStateByConversationId,
sendStatus => sendStatus !== SendStatus.Failed
)
); );
} }

View file

@ -78,7 +78,7 @@ describe('state/selectors/messages', () => {
assert.isFalse(canDeleteForEveryone(message)); assert.isFalse(canDeleteForEveryone(message));
}); });
it('returns false for messages that failed to send to anyone', () => { it("returns false for messages that haven't been sent to anyone", () => {
const message = { const message = {
type: 'outgoing' as const, type: 'outgoing' as const,
sent_at: Date.now() - 1000, sent_at: Date.now() - 1000,
@ -88,7 +88,7 @@ describe('state/selectors/messages', () => {
updatedAt: Date.now(), updatedAt: Date.now(),
}, },
[uuid()]: { [uuid()]: {
status: SendStatus.Failed, status: SendStatus.Pending,
updatedAt: Date.now(), updatedAt: Date.now(),
}, },
}, },
@ -103,11 +103,11 @@ describe('state/selectors/messages', () => {
sent_at: Date.now() - 1000, sent_at: Date.now() - 1000,
sendStateByConversationId: { sendStateByConversationId: {
[ourConversationId]: { [ourConversationId]: {
status: SendStatus.Pending, status: SendStatus.Sent,
updatedAt: Date.now(), updatedAt: Date.now(),
}, },
[uuid()]: { [uuid()]: {
status: SendStatus.Pending, status: SendStatus.Delivered,
updatedAt: Date.now(), updatedAt: Date.now(),
}, },
[uuid()]: { [uuid()]: {