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

pull/1381/head
Audric Ackermann 5 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(), isOnline: this.isOnline(),
hasNickname: !!this.getNickname(), hasNickname: !!this.getNickname(),
isKickedFromGroup: !!this.get('isKickedFromGroup'), isKickedFromGroup: !!this.get('isKickedFromGroup'),
leftGroup: !!this.get('left'),
selectedMessages: this.selectedMessages, selectedMessages: this.selectedMessages,

@ -1052,7 +1052,6 @@
window.log.warn('retrySend: Nobody to send to!'); window.log.warn('retrySend: Nobody to send to!');
return this.commit(); return this.commit();
} }
const { body, attachments, preview, quote } = await this.uploadData(); const { body, attachments, preview, quote } = await this.uploadData();
@ -1448,7 +1447,6 @@
}); });
await this.commit(); await this.commit();
}, },
getServerId() { getServerId() {
return this.get('serverId'); return this.get('serverId');
@ -1463,7 +1461,6 @@
}); });
await this.commit(); await this.commit();
}, },
async setServerTimestamp(serverTimestamp) { async setServerTimestamp(serverTimestamp) {
if (_.isEqual(this.get('serverTimestamp'), serverTimestamp)) { if (_.isEqual(this.get('serverTimestamp'), serverTimestamp)) {
@ -1475,7 +1472,6 @@
}); });
await this.commit(); await this.commit();
}, },
async setIsPublic(isPublic) { async setIsPublic(isPublic) {
if (_.isEqual(this.get('isPublic'), isPublic)) { if (_.isEqual(this.get('isPublic'), isPublic)) {
@ -1487,7 +1483,6 @@
}); });
await this.commit(); await this.commit();
}, },
async sendSyncMessageOnly(dataMessage) { async sendSyncMessageOnly(dataMessage) {
@ -1499,7 +1494,6 @@
await this.commit(); await this.commit();
const data = const data =
dataMessage instanceof libsession.Messages.Outgoing.DataMessage dataMessage instanceof libsession.Messages.Outgoing.DataMessage
? dataMessage.dataProto() ? dataMessage.dataProto()
@ -1531,7 +1525,6 @@
this.set({ sentSync: true }); this.set({ sentSync: true });
await this.commit(); await this.commit();
}, },
someRecipientsFailed() { someRecipientsFailed() {
@ -1613,8 +1606,6 @@
forceSave, forceSave,
Message: Whisper.Message, Message: Whisper.Message,
}); });
console.warn('case commit')
this.trigger('change'); this.trigger('change');
return id; return id;
}, },

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

@ -8,7 +8,6 @@
textsecure, textsecure,
Whisper, Whisper,
ConversationController, ConversationController,
BlockedNumberController,
*/ */
// eslint-disable-next-line func-names // eslint-disable-next-line func-names
@ -1051,45 +1050,6 @@
toastOptions.title = i18n('expiredWarning'); toastOptions.title = i18n('expiredWarning');
toastOptions.id = '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) { if (toastOptions.title) {
window.pushToast(toastOptions); window.pushToast(toastOptions);
this.focusMessageFieldAndClearDisabled(); this.focusMessageFieldAndClearDisabled();

@ -59,6 +59,10 @@ interface Props {
onLoadVoiceNoteView: any; onLoadVoiceNoteView: any;
onExitVoiceNoteView: any; onExitVoiceNoteView: any;
isBlocked: boolean;
isPrivate: boolean;
isKickedFromGroup: boolean;
leftGroup: boolean;
quotedMessageProps?: ReplyingToMessageProps; quotedMessageProps?: ReplyingToMessageProps;
removeQuotedMessage: () => void; removeQuotedMessage: () => void;
@ -206,16 +210,35 @@ export class SessionCompositionBox extends React.Component<Props, State> {
} }
private renderCompositionView() { private renderCompositionView() {
const { placeholder } = this.props; const {
placeholder,
isBlocked,
isKickedFromGroup,
leftGroup,
isPrivate,
} = this.props;
const { showEmojiPanel, message } = this.state; 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 ( return (
<> <>
{typingEnabled && (
<SessionIconButton <SessionIconButton
iconType={SessionIconType.CirclePlus} iconType={SessionIconType.CirclePlus}
iconSize={SessionIconSize.Large} iconSize={SessionIconSize.Large}
onClick={this.onChooseAttachment} onClick={this.onChooseAttachment}
/> />
)}
<input <input
className="hidden" className="hidden"
@ -226,11 +249,13 @@ export class SessionCompositionBox extends React.Component<Props, State> {
onChange={this.onChoseAttachment} onChange={this.onChoseAttachment}
/> />
{typingEnabled && (
<SessionIconButton <SessionIconButton
iconType={SessionIconType.Microphone} iconType={SessionIconType.Microphone}
iconSize={SessionIconSize.Huge} iconSize={SessionIconSize.Huge}
onClick={this.onLoadVoiceNoteView} onClick={this.onLoadVoiceNoteView}
/> />
)}
<div <div
className="send-message-input" className="send-message-input"
@ -245,16 +270,19 @@ export class SessionCompositionBox extends React.Component<Props, State> {
placeholder={placeholder} placeholder={placeholder}
maxLength={Constants.CONVERSATION.MAX_MESSAGE_BODY_LENGTH} maxLength={Constants.CONVERSATION.MAX_MESSAGE_BODY_LENGTH}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
value={message} value={messageWithWarning || message}
onChange={this.onChange} onChange={this.onChange}
disabled={!typingEnabled}
/> />
</div> </div>
{typingEnabled && (
<SessionIconButton <SessionIconButton
iconType={SessionIconType.Emoji} iconType={SessionIconType.Emoji}
iconSize={SessionIconSize.Large} iconSize={SessionIconSize.Large}
onClick={this.toggleEmojiPanel} onClick={this.toggleEmojiPanel}
/> />
)}
<div className="send-message-button"> <div className="send-message-button">
<SessionIconButton <SessionIconButton
iconType={SessionIconType.Send} iconType={SessionIconType.Send}
@ -264,6 +292,7 @@ export class SessionCompositionBox extends React.Component<Props, State> {
/> />
</div> </div>
{typingEnabled && (
<div <div
ref={ref => (this.emojiPanel = ref)} ref={ref => (this.emojiPanel = ref)}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
@ -276,6 +305,7 @@ export class SessionCompositionBox extends React.Component<Props, State> {
/> />
)} )}
</div> </div>
)}
</> </>
); );
} }
@ -471,9 +501,19 @@ export class SessionCompositionBox extends React.Component<Props, State> {
}, ''); }, '');
} }
// tslint:disable-next-line: cyclomatic-complexity
private async onSendMessage() { private async onSendMessage() {
const messagePlaintext = this.parseEmojis(this.state.message); 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 // Verify message length
const msgLen = messagePlaintext?.length || 0; const msgLen = messagePlaintext?.length || 0;
if (msgLen > window.CONSTANTS.MAX_MESSAGE_BODY_LENGTH) { if (msgLen > window.CONSTANTS.MAX_MESSAGE_BODY_LENGTH) {
@ -484,6 +524,29 @@ export class SessionCompositionBox extends React.Component<Props, State> {
ToastUtils.pushMessageBodyMissing(); ToastUtils.pushMessageBodyMissing();
return; 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 { quotedMessageProps } = this.props;
const { stagedLinkPreview } = this.state; const { stagedLinkPreview } = this.state;

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

@ -144,6 +144,7 @@ export class SessionConversationMessagesList extends React.Component<
if (conversation.unreadCount === 0) { if (conversation.unreadCount === 0) {
findFirstUnreadIndex = -1; findFirstUnreadIndex = -1;
} }
const isConvoBlocked = conversation.isBlocked;
return ( 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; isSecondary?: boolean;
primaryDevice: string; primaryDevice: string;
isBlocked: boolean; isBlocked: boolean;
isKickedFromGroup: boolean;
leftGroup: boolean;
}; };
export type ConversationLookupType = { export type ConversationLookupType = {
[key: string]: ConversationType; [key: string]: ConversationType;

@ -89,11 +89,15 @@ const messageSlice = createSlice({
initialState: [] as MessagesStateType, initialState: [] as MessagesStateType,
reducers: { reducers: {
messageChanged(state, action) { messageChanged(state, action) {
console.log('message changed ', state, action) // console.log('message changed ', action);
const messageInStoreIndex = state.findIndex(m => m.id === action.payload.id); const messageInStoreIndex = state.findIndex(
m => m.id === action.payload.id
);
if (messageInStoreIndex >= 0) { if (messageInStoreIndex >= 0) {
state[messageInStoreIndex] = _.omit(action.payload, toOmitFromMessageModel) state[messageInStoreIndex] = _.omit(
; action.payload,
toOmitFromMessageModel
);
} }
return state; return state;
}, },

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

2
ts/window.d.ts vendored

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

Loading…
Cancel
Save