add toast on isBlocked, isKicked, ... for sending of messages

pull/1381/head
Audric Ackermann 4 years ago
parent 866c28bc20
commit f3430bdcb5
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -517,6 +517,7 @@
isOnline: this.isOnline(),
hasNickname: !!this.getNickname(),
isKickedFromGroup: !!this.get('isKickedFromGroup'),
leftGroup: !!this.get('left'),
selectedMessages: this.selectedMessages,

@ -660,8 +660,8 @@
contact.number && contact.number[0] && contact.number[0].value;
const onSendMessage = firstNumber
? () => {
this.trigger('open-conversation', firstNumber);
}
this.trigger('open-conversation', firstNumber);
}
: null;
const onClick = async () => {
// First let's be sure that the signal account check is complete.
@ -692,8 +692,8 @@
!path && !objectUrl
? null
: Object.assign({}, attachment.thumbnail || {}, {
objectUrl: path || objectUrl,
});
objectUrl: path || objectUrl,
});
return Object.assign({}, attachment, {
isVoiceMessage: Signal.Types.Attachment.isVoiceMessage(attachment),
@ -746,13 +746,13 @@
const onClick = noClick
? null
: event => {
event.stopPropagation();
this.trigger('scroll-to-message', {
author,
id,
referencedMessageNotFound,
});
};
event.stopPropagation();
this.trigger('scroll-to-message', {
author,
id,
referencedMessageNotFound,
});
};
const firstAttachment = quote.attachments && quote.attachments[0];
@ -787,15 +787,15 @@
url: path ? getAbsoluteAttachmentPath(path) : null,
screenshot: screenshot
? {
...screenshot,
url: getAbsoluteAttachmentPath(screenshot.path),
}
...screenshot,
url: getAbsoluteAttachmentPath(screenshot.path),
}
: null,
thumbnail: thumbnail
? {
...thumbnail,
url: getAbsoluteAttachmentPath(thumbnail.path),
}
...thumbnail,
url: getAbsoluteAttachmentPath(thumbnail.path),
}
: null,
};
},
@ -824,9 +824,9 @@
const phoneNumbers = this.isIncoming()
? [this.get('source')]
: _.union(
this.get('sent_to') || [],
this.get('recipients') || this.getConversation().getRecipients()
);
this.get('sent_to') || [],
this.get('recipients') || this.getConversation().getRecipients()
);
// This will make the error message for outgoing key errors a bit nicer
const allErrors = (this.get('errors') || []).map(error => {
@ -1052,7 +1052,6 @@
window.log.warn('retrySend: Nobody to send to!');
return this.commit();
}
const { body, attachments, preview, quote } = await this.uploadData();
@ -1276,8 +1275,8 @@
*/
const hasBodyOrAttachments = Boolean(
dataMessage &&
(dataMessage.body ||
(dataMessage.attachments && dataMessage.attachments.length))
(dataMessage.body ||
(dataMessage.attachments && dataMessage.attachments.length))
);
const shouldNotifyPushServer =
hasBodyOrAttachments && isSessionOrClosedMessage;
@ -1448,7 +1447,6 @@
});
await this.commit();
},
getServerId() {
return this.get('serverId');
@ -1463,7 +1461,6 @@
});
await this.commit();
},
async setServerTimestamp(serverTimestamp) {
if (_.isEqual(this.get('serverTimestamp'), serverTimestamp)) {
@ -1475,7 +1472,6 @@
});
await this.commit();
},
async setIsPublic(isPublic) {
if (_.isEqual(this.get('isPublic'), isPublic)) {
@ -1487,7 +1483,6 @@
});
await this.commit();
},
async sendSyncMessageOnly(dataMessage) {
@ -1499,7 +1494,6 @@
await this.commit();
const data =
dataMessage instanceof libsession.Messages.Outgoing.DataMessage
? dataMessage.dataProto()
@ -1531,7 +1525,6 @@
this.set({ sentSync: true });
await this.commit();
},
someRecipientsFailed() {
@ -1613,8 +1606,6 @@
forceSave,
Message: Whisper.Message,
});
console.warn('case commit')
this.trigger('change');
return id;
},

@ -1,5 +1,5 @@
/* eslint-env node */
/* global log, Signal, Whisper */
/* global log */
const fs = require('fs-extra');
const path = require('path');

@ -8,7 +8,6 @@
textsecure,
Whisper,
ConversationController,
BlockedNumberController,
*/
// eslint-disable-next-line func-names
@ -1051,45 +1050,6 @@
toastOptions.title = i18n('expiredWarning');
toastOptions.id = 'expiredWarning';
}
if (!window.clientClockSynced) {
let clockSynced = false;
if (window.setClockParams) {
// Check to see if user has updated their clock to current time
clockSynced = await window.setClockParams();
} else {
window.log.info('setClockParams not loaded yet');
}
if (clockSynced) {
toastOptions.title = i18n('clockOutOfSync');
toastOptions.id = 'clockOutOfSync';
}
}
if (
this.model.isPrivate() &&
BlockedNumberController.isBlocked(this.model.id)
) {
toastOptions.title = i18n('unblockToSend');
toastOptions.id = 'unblockToSend';
}
if (
!this.model.isPrivate() &&
BlockedNumberController.isGroupBlocked(this.model.id)
) {
toastOptions.title = i18n('unblockGroupToSend');
toastOptions.id = 'unblockGroupToSend';
}
if (!this.model.isPrivate() && this.model.get('left')) {
toastOptions.title = i18n('youLeftTheGroup');
toastOptions.id = 'youLeftTheGroup';
}
if (
message.length >
window.libsession.Constants.CONVERSATION.MAX_MESSAGE_BODY_LENGTH
) {
toastOptions.title = i18n('messageBodyTooLong');
toastOptions.id = 'messageBodyTooLong';
}
if (toastOptions.title) {
window.pushToast(toastOptions);
this.focusMessageFieldAndClearDisabled();

@ -59,6 +59,10 @@ interface Props {
onLoadVoiceNoteView: any;
onExitVoiceNoteView: any;
isBlocked: boolean;
isPrivate: boolean;
isKickedFromGroup: boolean;
leftGroup: boolean;
quotedMessageProps?: ReplyingToMessageProps;
removeQuotedMessage: () => void;
@ -206,16 +210,35 @@ export class SessionCompositionBox extends React.Component<Props, State> {
}
private renderCompositionView() {
const { placeholder } = this.props;
const {
placeholder,
isBlocked,
isKickedFromGroup,
leftGroup,
isPrivate,
} = this.props;
const { showEmojiPanel, message } = this.state;
const typingEnabled = !(isBlocked || isKickedFromGroup || leftGroup);
const { i18n } = window;
const messageWithWarning = isKickedFromGroup
? i18n('youGotKickedFromGroup')
: leftGroup
? i18n('youLeftTheGroup')
: isBlocked && isPrivate
? i18n('unblockToSend')
: isBlocked && !isPrivate
? i18n('unblockGroupToSend')
: undefined;
return (
<>
<SessionIconButton
iconType={SessionIconType.CirclePlus}
iconSize={SessionIconSize.Large}
onClick={this.onChooseAttachment}
/>
{typingEnabled && (
<SessionIconButton
iconType={SessionIconType.CirclePlus}
iconSize={SessionIconSize.Large}
onClick={this.onChooseAttachment}
/>
)}
<input
className="hidden"
@ -226,11 +249,13 @@ export class SessionCompositionBox extends React.Component<Props, State> {
onChange={this.onChoseAttachment}
/>
<SessionIconButton
iconType={SessionIconType.Microphone}
iconSize={SessionIconSize.Huge}
onClick={this.onLoadVoiceNoteView}
/>
{typingEnabled && (
<SessionIconButton
iconType={SessionIconType.Microphone}
iconSize={SessionIconSize.Huge}
onClick={this.onLoadVoiceNoteView}
/>
)}
<div
className="send-message-input"
@ -245,16 +270,19 @@ export class SessionCompositionBox extends React.Component<Props, State> {
placeholder={placeholder}
maxLength={Constants.CONVERSATION.MAX_MESSAGE_BODY_LENGTH}
onKeyDown={this.onKeyDown}
value={message}
value={messageWithWarning || message}
onChange={this.onChange}
disabled={!typingEnabled}
/>
</div>
<SessionIconButton
iconType={SessionIconType.Emoji}
iconSize={SessionIconSize.Large}
onClick={this.toggleEmojiPanel}
/>
{typingEnabled && (
<SessionIconButton
iconType={SessionIconType.Emoji}
iconSize={SessionIconSize.Large}
onClick={this.toggleEmojiPanel}
/>
)}
<div className="send-message-button">
<SessionIconButton
iconType={SessionIconType.Send}
@ -264,18 +292,20 @@ export class SessionCompositionBox extends React.Component<Props, State> {
/>
</div>
<div
ref={ref => (this.emojiPanel = ref)}
onKeyDown={this.onKeyDown}
role="button"
>
{showEmojiPanel && (
<SessionEmojiPanel
onEmojiClicked={this.onEmojiClick}
show={showEmojiPanel}
/>
)}
</div>
{typingEnabled && (
<div
ref={ref => (this.emojiPanel = ref)}
onKeyDown={this.onKeyDown}
role="button"
>
{showEmojiPanel && (
<SessionEmojiPanel
onEmojiClicked={this.onEmojiClick}
show={showEmojiPanel}
/>
)}
</div>
)}
</>
);
}
@ -471,9 +501,19 @@ export class SessionCompositionBox extends React.Component<Props, State> {
}, '');
}
// tslint:disable-next-line: cyclomatic-complexity
private async onSendMessage() {
const messagePlaintext = this.parseEmojis(this.state.message);
const { isBlocked, isPrivate, leftGroup, isKickedFromGroup } = this.props;
if (isBlocked && isPrivate) {
ToastUtils.pushUnblockToSend();
return;
}
if (isBlocked && !isPrivate) {
ToastUtils.pushUnblockToSendGroup();
return;
}
// Verify message length
const msgLen = messagePlaintext?.length || 0;
if (msgLen > window.CONSTANTS.MAX_MESSAGE_BODY_LENGTH) {
@ -484,6 +524,29 @@ export class SessionCompositionBox extends React.Component<Props, State> {
ToastUtils.pushMessageBodyMissing();
return;
}
if (!window.clientClockSynced) {
let clockSynced = false;
if (window.setClockParams) {
// Check to see if user has updated their clock to current time
clockSynced = await window.setClockParams();
} else {
window.log.info('setClockParams not loaded yet');
}
if (clockSynced) {
ToastUtils.pushClockOutOfSync();
return;
}
}
if (!isPrivate && leftGroup) {
ToastUtils.pushYouLeftTheGroup();
return;
}
if (!isPrivate && isKickedFromGroup) {
ToastUtils.pushYouLeftTheGroup();
return;
}
const { quotedMessageProps } = this.props;
const { stagedLinkPreview } = this.state;

@ -28,6 +28,8 @@ import * as MIME from '../../../types/MIME';
import { SessionFileDropzone } from './SessionFileDropzone';
import { ConversationType } from '../../../state/ducks/conversations';
import { MessageView } from '../../MainViewController';
import { getMessageById } from '../../../../js/modules/data';
import { pushUnblockToSend } from '../../../session/utils/Toast';
interface State {
// Message sending progress
@ -161,7 +163,6 @@ export class SessionConversation extends React.Component<Props, State> {
div?.removeEventListener('drop', this.handleDrop);
}
public componentDidMount() {
// Pause thread to wait for rendering to complete
setTimeout(() => {
@ -253,7 +254,12 @@ export class SessionConversation extends React.Component<Props, State> {
</div>
{!isRss && (
// tslint:disable-next-line: use-simple-attributes
<SessionCompositionBox
isBlocked={conversation.isBlocked}
leftGroup={conversation.leftGroup}
isKickedFromGroup={conversation.isKickedFromGroup}
isPrivate={conversation.type === 'direct'}
sendMessage={sendMessageFn}
stagedAttachments={stagedAttachments}
onMessageSending={this.onMessageSending}
@ -689,6 +695,10 @@ export class SessionConversation extends React.Component<Props, State> {
// ~~~~~~~~~~~~~~ MESSAGE QUOTE ~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private async replyToMessage(quotedMessageTimestamp?: number) {
if (this.props.conversation.isBlocked) {
pushUnblockToSend();
return;
}
if (!_.isEqual(this.state.quotedMessageTimestamp, quotedMessageTimestamp)) {
const { messages, conversationKey } = this.props;
const conversationModel = window.ConversationController.getOrThrow(
@ -697,7 +707,9 @@ export class SessionConversation extends React.Component<Props, State> {
let quotedMessageProps = null;
if (quotedMessageTimestamp) {
const quotedMessage = messages.find(m => m.attributes.sent_at === quotedMessageTimestamp);
const quotedMessage = messages.find(
m => m.attributes.sent_at === quotedMessageTimestamp
);
if (quotedMessage) {
const quotedMessageModel = await getMessageById(quotedMessage.id, {

@ -144,6 +144,7 @@ export class SessionConversationMessagesList extends React.Component<
if (conversation.unreadCount === 0) {
findFirstUnreadIndex = -1;
}
const isConvoBlocked = conversation.isBlocked;
return (
<>

@ -211,3 +211,19 @@ export function pushPairingRequestReceived(alreadyLinked: boolean) {
);
}
}
export function pushUnblockToSend() {
pushToastInfo('unblockToSend', window.i18n('unblockToSend'));
}
export function pushUnblockToSendGroup() {
pushToastInfo('unblockGroupToSend', window.i18n('unblockGroupToSend'));
}
export function pushClockOutOfSync() {
pushToastError('clockOutOfSync', window.i18n('clockOutOfSync'));
}
export function pushYouLeftTheGroup() {
pushToastError('youLeftTheGroup', window.i18n('youLeftTheGroup'));
}

@ -56,6 +56,8 @@ export type ConversationType = {
isSecondary?: boolean;
primaryDevice: string;
isBlocked: boolean;
isKickedFromGroup: boolean;
leftGroup: boolean;
};
export type ConversationLookupType = {
[key: string]: ConversationType;

@ -8,7 +8,7 @@ export type MessagesStateType = Array<MessageType>;
export async function getMessages(
conversationKey: string,
numMessages: number
) : Promise<MessagesStateType> {
): Promise<MessagesStateType> {
const conversation = window.ConversationController.get(conversationKey);
if (!conversation) {
// no valid conversation, early return
@ -88,12 +88,16 @@ const messageSlice = createSlice({
name: 'messages',
initialState: [] as MessagesStateType,
reducers: {
messageChanged(state, action){
console.log('message changed ', state, action)
const messageInStoreIndex = state.findIndex(m => m.id === action.payload.id);
messageChanged(state, action) {
// console.log('message changed ', action);
const messageInStoreIndex = state.findIndex(
m => m.id === action.payload.id
);
if (messageInStoreIndex >= 0) {
state[messageInStoreIndex] = _.omit(action.payload, toOmitFromMessageModel)
;
state[messageInStoreIndex] = _.omit(
action.payload,
toOmitFromMessageModel
);
}
return state;
},

@ -30,6 +30,8 @@ describe('state/selectors/conversations', () => {
isSelected: false,
isTyping: false,
isBlocked: false,
isKickedFromGroup: false,
leftGroup: false,
},
id2: {
id: 'id2',
@ -49,6 +51,8 @@ describe('state/selectors/conversations', () => {
isSelected: false,
isTyping: false,
isBlocked: false,
isKickedFromGroup: false,
leftGroup: false,
},
id3: {
id: 'id3',
@ -68,6 +72,8 @@ describe('state/selectors/conversations', () => {
isSelected: false,
isTyping: false,
isBlocked: false,
isKickedFromGroup: false,
leftGroup: false,
},
id4: {
id: 'id4',
@ -78,7 +84,6 @@ describe('state/selectors/conversations', () => {
isArchived: false,
isSecondary: false,
primaryDevice: 'id4',
type: 'direct',
isMe: false,
lastUpdated: Date.now(),
@ -87,6 +92,8 @@ describe('state/selectors/conversations', () => {
isSelected: false,
isTyping: false,
isBlocked: false,
isKickedFromGroup: false,
leftGroup: false,
},
id5: {
id: 'id5',
@ -106,6 +113,8 @@ describe('state/selectors/conversations', () => {
isSelected: false,
isTyping: false,
isBlocked: false,
isKickedFromGroup: false,
leftGroup: false,
},
};
const comparator = _getConversationComparator(i18n, regionCode);

2
ts/window.d.ts vendored

@ -109,5 +109,7 @@ declare global {
sessionGenerateKeyPair: (
seed: ArrayBuffer
) => Promise<{ pubKey: ArrayBufferLike; privKey: ArrayBufferLike }>;
setClockParams: any;
clientClockSynced: number | undefined;
}
}

Loading…
Cancel
Save