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'; import { getFirstUnreadMessageIdInConversation } from '../data/data';
type Props = { type Props = {
conversationId: string; conversationId: string;
authorAvatarPath?: string; authorAvatarPath: string | null;
userName: string; userName: string;
}; };

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

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

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

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

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

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

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

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

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

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

@ -2,6 +2,7 @@ import { DefaultTheme } from 'styled-components';
import _ from 'underscore'; import _ from 'underscore';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { QuotedAttachmentType } from '../components/conversation/Quote'; import { QuotedAttachmentType } from '../components/conversation/Quote';
import { PropsForMessage } from '../state/ducks/conversations';
import { AttachmentType, AttachmentTypeWithPath } from '../types/Attachment'; import { AttachmentType, AttachmentTypeWithPath } from '../types/Attachment';
import { Contact } from '../types/Contact'; import { Contact } from '../types/Contact';
import { ConversationTypeEnum } from './conversation'; import { ConversationTypeEnum } from './conversation';
@ -198,57 +199,23 @@ export type QuoteClickOptions = {
quoteId: number; quoteId: number;
referencedMessageNotFound: boolean; 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; disableMenu?: boolean;
isDeletable: boolean;
isAdmin?: boolean;
weAreAdmin?: boolean;
text: string | null;
id: string;
collapseMetadata?: boolean; 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 */ /** Note: this should be formatted for display */
authorPhoneNumber: string; attachments?: Array<AttachmentTypeWithPath>; // vs Array<PropsForAttachment>;
conversationType: ConversationTypeEnum;
attachments?: Array<AttachmentTypeWithPath>; // whether or not to allow selecting the message
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
multiSelectMode: boolean; multiSelectMode: boolean;
firstMessageOfSeries: boolean; firstMessageOfSeries: boolean;
isUnread: boolean;
isTrustedForAttachmentDownload: boolean;
onQuoteClick?: (options: QuoteClickOptions) => Promise<void>; onQuoteClick?: (options: QuoteClickOptions) => Promise<void>;
playableMessageIndex?: number; playableMessageIndex?: number;
nextMessageToPlay?: number; nextMessageToPlay?: number;
playNextMessage?: (value: number) => void; playNextMessage?: (value: number) => void;
} };

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

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

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

Loading…
Cancel
Save