fix at lat types for attachment

pull/1753/head
audric 4 years ago
parent 12ff3379e1
commit 588ae85cda

@ -14,7 +14,7 @@ import useKey from 'react-use/lib/useKey';
import { getFirstUnreadMessageIdInConversation } from '../data/data';
type Props = {
conversationId: string;
authorAvatarPath?: string;
authorAvatarPath: string | null;
userName: string;
};

@ -23,7 +23,7 @@ type Props = {
const IMAGE_WIDTH = 120;
const IMAGE_HEIGHT = 120;
export const AttachmentList = (props: Props) => {
export const StagedAttachmentList = (props: Props) => {
const { attachments, onAddAttachment, onClickAttachment, onCloseAttachment, onClose } = props;
if (!attachments.length) {

@ -2,12 +2,12 @@ import React from 'react';
import classNames from 'classnames';
import { Spinner } from '../basic/Spinner';
import { AttachmentTypeWithPath } from '../../types/Attachment';
import { AttachmentType, AttachmentTypeWithPath } from '../../types/Attachment';
import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch';
type Props = {
alt: string;
attachment: AttachmentTypeWithPath;
attachment: AttachmentTypeWithPath | AttachmentType;
url: string;
height?: number;
@ -28,8 +28,8 @@ type Props = {
playIconOverlay?: boolean;
softCorners?: boolean;
onClick?: (attachment: AttachmentTypeWithPath) => void;
onClickClose?: (attachment: AttachmentTypeWithPath) => void;
onClick?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
onClickClose?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
onError?: () => void;
};

@ -3,6 +3,7 @@ import classNames from 'classnames';
import {
areAllAttachmentsVisual,
AttachmentType,
AttachmentTypeWithPath,
getAlt,
getImageDimensions,
@ -20,7 +21,7 @@ type Props = {
bottomOverlay?: boolean;
onError: () => void;
onClickAttachment?: (attachment: AttachmentTypeWithPath) => void;
onClickAttachment?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
};
export const ImageGrid = (props: Props) => {

@ -10,6 +10,7 @@ import { ContactName } from './ContactName';
import { Quote } from './Quote';
import {
AttachmentType,
AttachmentTypeWithPath,
canDisplayImage,
getExtensionForDisplay,
@ -26,12 +27,10 @@ import {
import { getIncrement } from '../../util/timer';
import { isFileDangerous } from '../../util/isFileDangerous';
import _ from 'lodash';
import { contextMenu, Menu } from 'react-contexify';
import { contextMenu } from 'react-contexify';
import uuid from 'uuid';
import { InView } from 'react-intersection-observer';
import { MessageMetadata } from './message/MessageMetadata';
import { PubKey } from '../../session/types';
import { MessageRegularProps } from '../../models/messageType';
import { MessageRenderingProps } from '../../models/messageType';
import { updateUserDetailsModal } from '../../state/ducks/modalDialog';
import autoBind from 'auto-bind';
import { AudioPlayerWithEncryptedFile } from './H5AudioPlayer';
@ -52,9 +51,9 @@ import { saveAttachmentToDisk } from '../../util/attachmentsUtil';
import { LightBoxOptions } from '../session/conversation/SessionConversation';
import { MessageContextMenu } from './MessageContextMenu';
import { ReadableMessage } from './ReadableMessage';
import { remote } from 'electron';
import { isElectronWindowFocused } from '../../session/utils/WindowUtils';
import { getConversationController } from '../../session/conversations';
import { MessageMetadata } from './message/MessageMetadata';
// Same as MIN_WIDTH in ImageGrid.tsx
const MINIMUM_LINK_PREVIEW_IMAGE_WIDTH = 200;
@ -68,13 +67,17 @@ interface State {
const EXPIRATION_CHECK_MINIMUM = 2000;
const EXPIRED_DELAY = 600;
type Props = MessageRegularProps & {
type Props = MessageRenderingProps & {
selectedMessages: Array<string>;
quotedMessageToAnimate: string | undefined;
};
function attachmentIsAttachmentTypeWithPath(attac: any): attac is AttachmentTypeWithPath {
return attac.path !== undefined;
}
const onClickAttachment = async (onClickProps: {
attachment: AttachmentTypeWithPath;
attachment: AttachmentTypeWithPath | AttachmentType;
messageId: string;
}) => {
let index = -1;
@ -101,11 +104,16 @@ const onClickAttachment = async (onClickProps: {
messageId: onClickProps.messageId,
};
});
const lightBoxOptions: LightBoxOptions = {
media: media as any,
attachment: onClickProps.attachment,
};
window.inboxStore?.dispatch(showLightBox(lightBoxOptions));
if (attachmentIsAttachmentTypeWithPath(onClickProps.attachment)) {
const lightBoxOptions: LightBoxOptions = {
media: media as any,
attachment: onClickProps.attachment,
};
window.inboxStore?.dispatch(showLightBox(lightBoxOptions));
} else {
window.log.warn('Attachment is not of the right type');
}
};
class MessageInner extends React.PureComponent<Props, State> {
@ -438,7 +446,7 @@ class MessageInner extends React.PureComponent<Props, State> {
authorPhoneNumber,
authorProfileName,
collapseMetadata,
isAdmin,
isSenderAdmin,
conversationType,
direction,
isPublic,
@ -463,7 +471,7 @@ class MessageInner extends React.PureComponent<Props, State> {
onAvatarClick={this.onMessageAvatarClick}
pubkey={authorPhoneNumber}
/>
{isPublic && isAdmin && (
{isPublic && isSenderAdmin && (
<div className="module-avatar__icon--crown-wrapper">
<div className="module-avatar__icon--crown" />
</div>
@ -665,7 +673,7 @@ class MessageInner extends React.PureComponent<Props, State> {
timestamp={this.props.timestamp}
collapseMetadata={this.props.collapseMetadata}
expirationLength={this.props.expirationLength}
isAdmin={this.props.isAdmin}
isAdmin={this.props.isSenderAdmin}
serverTimestamp={this.props.serverTimestamp}
isPublic={this.props.isPublic}
status={this.props.status}
@ -688,7 +696,7 @@ class MessageInner extends React.PureComponent<Props, State> {
timestamp={this.props.timestamp}
serverTimestamp={this.props.serverTimestamp}
attachments={this.props.attachments}
isAdmin={this.props.isAdmin}
isAdmin={this.props.isSenderAdmin}
isOpenGroupV2={this.props.isOpenGroupV2}
isPublic={this.props.isPublic}
status={this.props.status}
@ -784,7 +792,7 @@ class MessageInner extends React.PureComponent<Props, State> {
);
}
private onClickOnImageGrid(attachment: AttachmentTypeWithPath) {
private onClickOnImageGrid(attachment: AttachmentTypeWithPath | AttachmentType) {
const { multiSelectMode, id } = this.props;
if (multiSelectMode) {

@ -5,7 +5,7 @@ import moment from 'moment';
import { Avatar, AvatarSize } from '../Avatar';
import { ContactName } from './ContactName';
import { Message } from './Message';
import { MessageRegularProps } from '../../models/messageType';
import { MessageRenderingProps } from '../../models/messageType';
import { deleteMessagesById } from '../../interactions/conversationInteractions';
import { useSelector } from 'react-redux';
import { ContactPropsMessageDetail } from '../../state/ducks/conversations';
@ -20,16 +20,14 @@ const AvatarItem = (props: { contact: ContactPropsMessageDetail }) => {
);
};
const DeleteButtonItem = (props: { message: MessageRegularProps }) => {
const DeleteButtonItem = (props: { id: string; convoId: string; isDeletable: boolean }) => {
const { i18n } = window;
const { message } = props;
return message.isDeletable ? (
return props.isDeletable ? (
<div className="module-message-detail__delete-button-container">
<button
onClick={() => {
void deleteMessagesById([message.id], message.convoId, true);
void deleteMessagesById([props.id], props.convoId, true);
}}
className="module-message-detail__delete-button"
>
@ -106,7 +104,7 @@ export const MessageDetail = () => {
<div className="message-detail-wrapper">
<div className="module-message-detail">
<div className="module-message-detail__message-container">
<Message {...message} />
<Message {...message} firstMessageOfSeries={true} multiSelectMode={false} />
</div>
<table className="module-message-detail__info">
<tbody>
@ -143,7 +141,11 @@ export const MessageDetail = () => {
</tbody>
</table>
<ContactsItem contacts={messageDetailProps.contacts} />
<DeleteButtonItem message={messageDetailProps.message} />
<DeleteButtonItem
convoId={messageDetailProps.message.convoId}
id={messageDetailProps.message.id}
isDeletable={messageDetailProps.message.isDeletable}
/>
</div>
</div>
);

@ -24,7 +24,7 @@ export type QuotePropsWithoutListener = {
convoId: string;
isPublic?: boolean;
withContentAbove: boolean;
text: string;
text: string | null;
referencedMessageNotFound: boolean;
};

@ -17,7 +17,7 @@ type Props = {
serverTimestamp?: number;
status?: MessageDeliveryStatus | null;
expirationLength?: number;
expirationTimestamp?: number;
expirationTimestamp: number | null;
isPublic?: boolean;
isShowingImage: boolean;
};

@ -14,7 +14,7 @@ import { Constants } from '../../../session';
import { toArray } from 'react-emoji-render';
import { Flex } from '../../basic/Flex';
import { AttachmentList } from '../../conversation/AttachmentList';
import { StagedAttachmentList } from '../../conversation/AttachmentList';
import { ToastUtils } from '../../../session/utils';
import { AttachmentUtil } from '../../../util';
import {
@ -26,7 +26,6 @@ import { AbortController } from 'abort-controller';
import { SessionQuotedMessageComposition } from './SessionQuotedMessageComposition';
import { Mention, MentionsInput } from 'react-mentions';
import { CaptionEditor } from '../../CaptionEditor';
import { DefaultTheme } from 'styled-components';
import { getConversationController } from '../../../session/conversations';
import { ReduxConversationType } from '../../../state/ducks/conversations';
import { SessionMemberListItem } from '../SessionMemberListItem';
@ -711,7 +710,7 @@ class SessionCompositionBoxInner extends React.Component<Props, State> {
if (stagedAttachments && stagedAttachments.length) {
return (
<>
<AttachmentList
<StagedAttachmentList
attachments={stagedAttachments}
onClickAttachment={this.onClickAttachment}
onAddAttachment={this.onChooseAttachment}

@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
import {
PropsForDataExtractionNotification,
QuoteClickOptions,
MessageRegularProps,
MessageRenderingProps,
} from '../../../models/messageType';
import {
PropsForGroupUpdate,
@ -99,7 +99,7 @@ export const GenericMessageItem = (props: {
? props.scrollToQuoteMessage
: undefined;
const regularProps: MessageRegularProps = {
const regularProps: MessageRenderingProps = {
...props.messageProps.propsForMessage,
firstMessageOfSeries: props.messageProps.firstMessageOfSeries,
multiSelectMode,

@ -571,7 +571,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
isPublic,
isBlocked,
isOpenGroupV2: isPublicOpenGroupV2,
isKickedFromGroup: conversation?.get('isKickedFromGroup'),
isKickedFromGroup: conversation?.get('isKickedFromGroup') || false,
isTrustedForAttachmentDownload,
weAreAdmin,
isDeletable,
@ -695,7 +695,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
// tslint:disable-next-line: no-bitwise
Boolean(flags && flags & SignalService.AttachmentPointer.Flags.VOICE_MESSAGE) || false;
return {
id: id ? `${id}` : undefined,
id,
contentType,
size: size || 0,
width: width || 0,
@ -771,11 +771,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
receivedAt: this.get('received_at') || 0,
message: {
...this.getPropsForMessage(),
disableMenu: true,
// To ensure that group avatar doesn't show up
conversationType: ConversationTypeEnum.PRIVATE,
multiSelectMode: false,
firstMessageOfSeries: false,
},
errors,
contacts: sortedContacts || [],

@ -2,6 +2,7 @@ import { DefaultTheme } from 'styled-components';
import _ from 'underscore';
import { v4 as uuidv4 } from 'uuid';
import { QuotedAttachmentType } from '../components/conversation/Quote';
import { PropsForMessage } from '../state/ducks/conversations';
import { AttachmentType, AttachmentTypeWithPath } from '../types/Attachment';
import { Contact } from '../types/Contact';
import { ConversationTypeEnum } from './conversation';
@ -198,57 +199,23 @@ export type QuoteClickOptions = {
quoteId: number;
referencedMessageNotFound: boolean;
};
export interface MessageRegularProps {
/**
* Those props are the one generated from a single Message improved by the one by the app itself.
* Some of the one added comes from the MessageList, some from redux, etc..
*/
export type MessageRenderingProps = PropsForMessage & {
disableMenu?: boolean;
isDeletable: boolean;
isAdmin?: boolean;
weAreAdmin?: boolean;
text: string | null;
id: string;
collapseMetadata?: boolean;
direction: MessageModelType;
timestamp: number;
serverTimestamp?: number;
status?: MessageDeliveryStatus | null;
// What if changed this over to a single contact like quote, and put the events on it?
contact?: Contact & {
onSendMessage?: () => void;
onClick?: () => void;
};
authorName?: string | null;
authorProfileName?: string | null;
/** Note: this should be formatted for display */
authorPhoneNumber: string;
conversationType: ConversationTypeEnum;
attachments?: Array<AttachmentTypeWithPath>;
quote?: {
text: string;
attachment?: QuotedAttachmentType;
isFromMe: boolean;
authorPhoneNumber: string;
authorProfileName?: string;
authorName?: string;
messageId?: string;
referencedMessageNotFound: boolean;
};
previews: Array<any>;
authorAvatarPath?: string;
isExpired: boolean;
expirationLength?: number;
expirationTimestamp?: number;
convoId: string;
isPublic?: boolean;
isBlocked: boolean;
isOpenGroupV2?: boolean;
isKickedFromGroup: boolean;
// whether or not to show check boxes
attachments?: Array<AttachmentTypeWithPath>; // vs Array<PropsForAttachment>;
// whether or not to allow selecting the message
multiSelectMode: boolean;
firstMessageOfSeries: boolean;
isUnread: boolean;
isTrustedForAttachmentDownload: boolean;
onQuoteClick?: (options: QuoteClickOptions) => Promise<void>;
playableMessageIndex?: number;
nextMessageToPlay?: number;
playNextMessage?: (value: number) => void;
}
};

@ -3,7 +3,7 @@ import _, { omit } from 'lodash';
import { Constants } from '../../session';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { getConversationController } from '../../session/conversations';
import { getFirstUnreadMessageIdInConversation, getMessagesByConversation } from '../../data/data';
import { getMessagesByConversation } from '../../data/data';
import {
ConversationNotificationSettingType,
ConversationTypeEnum,
@ -11,11 +11,11 @@ import {
import {
MessageDeliveryStatus,
MessageModelType,
MessageRegularProps,
PropsForDataExtractionNotification,
} from '../../models/messageType';
import { LightBoxOptions } from '../../components/session/conversation/SessionConversation';
import { ReplyingToMessageProps } from '../../components/session/conversation/SessionCompositionBox';
import { QuotedAttachmentType } from '../../components/conversation/Quote';
export type MessageModelProps = {
propsForMessage: PropsForMessage;
@ -41,7 +41,7 @@ export type MessagePropsDetails = {
sentAt: number;
receivedAt: number;
message: MessageRegularProps;
message: PropsForMessage;
errors: Array<Error>;
contacts: Array<ContactPropsMessageDetail>;
};
@ -127,13 +127,13 @@ export type PropsForSearchResults = {
};
export type PropsForAttachment = {
id?: string;
id: number;
contentType: string;
size: number;
width?: number;
height?: number;
url: string;
path?: string;
path: string;
fileSize: string | null;
isVoiceMessage: boolean;
pending: boolean;
@ -162,22 +162,31 @@ export type PropsForMessage = {
receivedAt: number | undefined;
serverTimestamp: number | undefined;
serverId: number | undefined;
status: LastMessageStatusType;
status: LastMessageStatusType | null;
authorName: string | null;
authorProfileName: string | null;
authorPhoneNumber: string;
conversationType: ConversationTypeEnum;
convoId: string;
attachments: Array<PropsForAttachment>;
previews: any;
quote: any;
previews: Array<any>;
quote?: {
text: string | null;
attachment?: QuotedAttachmentType;
isFromMe: boolean;
authorPhoneNumber: string;
authorProfileName?: string;
authorName?: string;
messageId?: string;
referencedMessageNotFound: boolean;
} | null;
authorAvatarPath: string | null;
isUnread: boolean;
expirationLength: number;
expirationTimestamp: number | null;
isPublic: boolean;
isOpenGroupV2: boolean;
isKickedFromGroup: boolean | undefined;
isKickedFromGroup: boolean;
isTrustedForAttachmentDownload: boolean;
weAreAdmin: boolean;
isSenderAdmin: boolean;

@ -18,7 +18,7 @@ export type SessionPasswordModalState = { passwordAction: PasswordAction; onOk:
export type UserDetailsModalState = {
conversationId: string;
authorAvatarPath?: string;
authorAvatarPath: string | null;
userName: string;
} | null;

@ -33,13 +33,13 @@ export interface AttachmentType {
screenshot: {
height: number;
width: number;
url: string;
url?: string;
contentType: MIME.MIMEType;
} | null;
thumbnail: {
height: number;
width: number;
url: string;
url?: string;
contentType: MIME.MIMEType;
} | null;
}
@ -53,14 +53,14 @@ export interface AttachmentTypeWithPath extends AttachmentType {
screenshot: {
height: number;
width: number;
url: string;
url?: string;
contentType: MIME.MIMEType;
path?: string;
} | null;
thumbnail: {
height: number;
width: number;
url: string;
url?: string;
contentType: MIME.MIMEType;
path?: string;
} | null;
@ -111,17 +111,17 @@ export function canDisplayImage(attachments?: Array<AttachmentType>) {
return height && height > 0 && height <= 4096 && width && width > 0 && width <= 4096;
}
export function getThumbnailUrl(attachment: AttachmentType) {
if (attachment.thumbnail) {
export function getThumbnailUrl(attachment: AttachmentType): string {
if (attachment.thumbnail && attachment.thumbnail.url) {
return attachment.thumbnail.url;
}
return getUrl(attachment);
}
export function getUrl(attachment: AttachmentType) {
if (attachment.screenshot) {
return attachment.screenshot.url;
export function getUrl(attachment: AttachmentType): string {
if (attachment.screenshot && attachment.screenshot.url) {
return attachment.screenshot.url as string;
}
return attachment.url;

Loading…
Cancel
Save