Prevent send and show toast for invalid conversations
This commit is contained in:
parent
34be0744d2
commit
3ee830ae63
5 changed files with 83 additions and 45 deletions
|
@ -311,6 +311,10 @@
|
|||
"message": "You are no longer a member of the group.",
|
||||
"description": "Displayed when a user can't send a message because they have left the group"
|
||||
},
|
||||
"invalidConversation": {
|
||||
"message": "This group is invalid. Please create a new group.",
|
||||
"description": "Displayed when a user can't send a message because something has gone wrong in the conversation."
|
||||
},
|
||||
"scrollDown": {
|
||||
"message": "Scroll to bottom of conversation",
|
||||
"description": "Alt text for button to take user down to bottom of conversation, shown when user scrolls up"
|
||||
|
|
|
@ -163,6 +163,8 @@ type UpdatesResultType = {
|
|||
// Constants
|
||||
|
||||
export const MASTER_KEY_LENGTH = 32;
|
||||
export const ID_V1_LENGTH = 16;
|
||||
export const ID_LENGTH = 32;
|
||||
const TEMPORAL_AUTH_REJECTED_CODE = 401;
|
||||
const GROUP_ACCESS_DENIED_CODE = 403;
|
||||
const SUPPORTED_CHANGE_EPOCH = 0;
|
||||
|
|
|
@ -266,7 +266,8 @@ export class ConversationModel extends window.Backbone.Model<
|
|||
return false;
|
||||
}
|
||||
|
||||
return fromEncodedBinaryToArrayBuffer(groupId).byteLength === 16;
|
||||
const buffer = fromEncodedBinaryToArrayBuffer(groupId);
|
||||
return buffer.byteLength === window.Signal.Groups.ID_V1_LENGTH;
|
||||
}
|
||||
|
||||
isGroupV2(): boolean {
|
||||
|
@ -277,7 +278,10 @@ export class ConversationModel extends window.Backbone.Model<
|
|||
|
||||
const groupVersion = this.get('groupVersion') || 0;
|
||||
|
||||
return groupVersion === 2 && base64ToArrayBuffer(groupId).byteLength === 32;
|
||||
return (
|
||||
groupVersion === 2 &&
|
||||
base64ToArrayBuffer(groupId).byteLength === window.Signal.Groups.ID_LENGTH
|
||||
);
|
||||
}
|
||||
|
||||
isMemberPending(conversationId: string): boolean {
|
||||
|
@ -822,6 +826,10 @@ export class ConversationModel extends window.Backbone.Model<
|
|||
});
|
||||
}
|
||||
|
||||
isValid(): boolean {
|
||||
return this.isPrivate() || this.isGroupV1() || this.isGroupV2();
|
||||
}
|
||||
|
||||
maybeRepairGroupV2(data: {
|
||||
masterKey: string;
|
||||
secretParams: string;
|
||||
|
|
|
@ -76,6 +76,12 @@ Whisper.LeftGroupToast = Whisper.ToastView.extend({
|
|||
},
|
||||
});
|
||||
|
||||
Whisper.InvalidConversationToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('invalidConversation') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.OriginalNotFoundToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('originalMessageNotFound') };
|
||||
|
@ -2897,6 +2903,10 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
this.model.set({ profileSharing: true });
|
||||
}
|
||||
|
||||
if (this.showInvalidMessageToast()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { packId, stickerId } = options;
|
||||
this.model.sendStickerMessage(packId, stickerId);
|
||||
} catch (error) {
|
||||
|
@ -3030,6 +3040,43 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
});
|
||||
},
|
||||
|
||||
showInvalidMessageToast(messageText?: string): boolean {
|
||||
let ToastView;
|
||||
|
||||
if (window.reduxStore.getState().expiration.hasExpired) {
|
||||
ToastView = Whisper.ExpiredToast;
|
||||
}
|
||||
if (!this.model.isValid()) {
|
||||
ToastView = Whisper.InvalidConversationToast;
|
||||
}
|
||||
if (
|
||||
this.model.isPrivate() &&
|
||||
(window.storage.isBlocked(this.model.get('e164')) ||
|
||||
window.storage.isUuidBlocked(this.model.get('uuid')))
|
||||
) {
|
||||
ToastView = Whisper.BlockedToast;
|
||||
}
|
||||
if (
|
||||
!this.model.isPrivate() &&
|
||||
window.storage.isGroupBlocked(this.model.get('groupId'))
|
||||
) {
|
||||
ToastView = Whisper.BlockedGroupToast;
|
||||
}
|
||||
if (!this.model.isPrivate() && this.model.get('left')) {
|
||||
ToastView = Whisper.LeftGroupToast;
|
||||
}
|
||||
if (messageText && messageText.length > MAX_MESSAGE_BODY_LENGTH) {
|
||||
ToastView = Whisper.MessageBodyTooLongToast;
|
||||
}
|
||||
|
||||
if (ToastView) {
|
||||
this.showToast(ToastView);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
async sendMessage(message = '', mentions = [], options = {}) {
|
||||
this.sendStart = Date.now();
|
||||
|
||||
|
@ -3058,32 +3105,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
|
||||
this.model.clearTypingTimers();
|
||||
|
||||
let ToastView;
|
||||
if (window.reduxStore.getState().expiration.hasExpired) {
|
||||
ToastView = Whisper.ExpiredToast;
|
||||
}
|
||||
if (
|
||||
this.model.isPrivate() &&
|
||||
(window.storage.isBlocked(this.model.get('e164')) ||
|
||||
window.storage.isUuidBlocked(this.model.get('uuid')))
|
||||
) {
|
||||
ToastView = Whisper.BlockedToast;
|
||||
}
|
||||
if (
|
||||
!this.model.isPrivate() &&
|
||||
window.storage.isGroupBlocked(this.model.get('groupId'))
|
||||
) {
|
||||
ToastView = Whisper.BlockedGroupToast;
|
||||
}
|
||||
if (!this.model.isPrivate() && this.model.get('left')) {
|
||||
ToastView = Whisper.LeftGroupToast;
|
||||
}
|
||||
if (message.length > MAX_MESSAGE_BODY_LENGTH) {
|
||||
ToastView = Whisper.MessageBodyTooLongToast;
|
||||
}
|
||||
|
||||
if (ToastView) {
|
||||
this.showToast(ToastView);
|
||||
if (this.showInvalidMessageToast(message)) {
|
||||
this.enableMessageField();
|
||||
return;
|
||||
}
|
||||
|
|
36
ts/window.d.ts
vendored
36
ts/window.d.ts
vendored
|
@ -674,28 +674,30 @@ export type WhisperType = {
|
|||
deliveryReceiptBatcher: BatcherType<WhatIsThis>;
|
||||
RotateSignedPreKeyListener: WhatIsThis;
|
||||
|
||||
ExpiredToast: typeof Whisper.ToastView;
|
||||
BlockedToast: typeof Whisper.ToastView;
|
||||
BlockedGroupToast: typeof Whisper.ToastView;
|
||||
LeftGroupToast: typeof Whisper.ToastView;
|
||||
OriginalNotFoundToast: typeof Whisper.ToastView;
|
||||
OriginalNoLongerAvailableToast: typeof Whisper.ToastView;
|
||||
BlockedToast: typeof Whisper.ToastView;
|
||||
CannotMixImageAndNonImageAttachmentsToast: typeof Whisper.ToastView;
|
||||
DangerousFileTypeToast: typeof Whisper.ToastView;
|
||||
ExpiredToast: typeof Whisper.ToastView;
|
||||
FileSavedToast: typeof Whisper.ToastView;
|
||||
FileSizeToast: any;
|
||||
FoundButNotLoadedToast: typeof Whisper.ToastView;
|
||||
VoiceNoteLimit: typeof Whisper.ToastView;
|
||||
VoiceNoteMustBeOnlyAttachmentToast: typeof Whisper.ToastView;
|
||||
InvalidConversationToast: typeof Whisper.ToastView;
|
||||
LeftGroupToast: typeof Whisper.ToastView;
|
||||
MaxAttachmentsToast: typeof Whisper.ToastView;
|
||||
MessageBodyTooLongToast: typeof Whisper.ToastView;
|
||||
OneNonImageAtATimeToast: typeof Whisper.ToastView;
|
||||
OriginalNoLongerAvailableToast: typeof Whisper.ToastView;
|
||||
OriginalNotFoundToast: typeof Whisper.ToastView;
|
||||
PinnedConversationsFullToast: typeof Whisper.ToastView;
|
||||
ReactionFailedToast: typeof Whisper.ToastView;
|
||||
TapToViewExpiredIncomingToast: typeof Whisper.ToastView;
|
||||
TapToViewExpiredOutgoingToast: typeof Whisper.ToastView;
|
||||
FileSavedToast: typeof Whisper.ToastView;
|
||||
ReactionFailedToast: typeof Whisper.ToastView;
|
||||
MessageBodyTooLongToast: typeof Whisper.ToastView;
|
||||
FileSizeToast: any;
|
||||
UnableToLoadToast: typeof Whisper.ToastView;
|
||||
DangerousFileTypeToast: typeof Whisper.ToastView;
|
||||
OneNonImageAtATimeToast: typeof Whisper.ToastView;
|
||||
CannotMixImageAndNonImageAttachmentsToast: typeof Whisper.ToastView;
|
||||
MaxAttachmentsToast: typeof Whisper.ToastView;
|
||||
TimerConflictToast: typeof Whisper.ToastView;
|
||||
PinnedConversationsFullToast: typeof Whisper.ToastView;
|
||||
UnableToLoadToast: typeof Whisper.ToastView;
|
||||
VoiceNoteLimit: typeof Whisper.ToastView;
|
||||
VoiceNoteMustBeOnlyAttachmentToast: typeof Whisper.ToastView;
|
||||
|
||||
ConversationLoadingScreen: typeof Whisper.View;
|
||||
ConversationView: typeof Whisper.View;
|
||||
View: typeof Backbone.View;
|
||||
|
|
Loading…
Reference in a new issue