signal-desktop/ts/components/conversation/media-gallery/MediaGridItem.tsx
Scott Nonnenberg 643739f65d
Responding to feedback on the updated visuals (#2549)
* Conversation List Item: timestamp bold only when convo has unread

* Preserve the positioning of overlays on re-entry into convo

* ConversationListItem: Handle missing and broken thumbnails

* Shorten timestamp in left pane for better Android consistency

* Update convo last updated if last was expire timer change

But not if it was from a sync instead of from you or from a contact.

* Make links in quotes the same color as the text

* MediaGridItem: Update placeholder icon colors for dark theme

* Ensure turning off timer shows 'Timer set to off' in left pane

* ConversationListItem: Show unread count in blue circle

* Add one pixel margin to blue indicator for text alignment

* Ensure replies to voice message can bet sent successfully
2018-07-20 16:37:57 -07:00

120 lines
2.7 KiB
TypeScript

import React from 'react';
import classNames from 'classnames';
import {
isImageTypeSupported,
isVideoTypeSupported,
} from '../../../util/GoogleChrome';
import { Message } from './types/Message';
import { Localizer } from '../../../types/Util';
interface Props {
message: Message;
onClick?: () => void;
i18n: Localizer;
}
interface State {
imageBroken: boolean;
}
export class MediaGridItem extends React.Component<Props, State> {
private onImageErrorBound: () => void;
constructor(props: Props) {
super(props);
this.state = {
imageBroken: false,
};
this.onImageErrorBound = this.onImageError.bind(this);
}
public onImageError() {
this.setState({
imageBroken: true,
});
}
public renderContent() {
const { message, i18n } = this.props;
const { imageBroken } = this.state;
const { attachments } = message;
if (!attachments || !attachments.length) {
return null;
}
const first = attachments[0];
const { contentType } = first;
if (contentType && isImageTypeSupported(contentType)) {
if (imageBroken || !message.thumbnailObjectUrl) {
return (
<div
className={classNames(
'module-media-grid-item__icon',
'module-media-grid-item__icon-image'
)}
/>
);
}
return (
<img
alt={i18n('lightboxImageAlt')}
className="module-media-grid-item__image"
src={message.thumbnailObjectUrl}
onError={this.onImageErrorBound}
/>
);
} else if (contentType && isVideoTypeSupported(contentType)) {
if (imageBroken || !message.thumbnailObjectUrl) {
return (
<div
className={classNames(
'module-media-grid-item__icon',
'module-media-grid-item__icon-video'
)}
/>
);
}
return (
<div className="module-media-grid-item__image-container">
<img
alt={i18n('lightboxImageAlt')}
className="module-media-grid-item__image"
src={message.thumbnailObjectUrl}
onError={this.onImageErrorBound}
/>
<div className="module-media-grid-item__circle-overlay">
<div className="module-media-grid-item__play-overlay" />
</div>
</div>
);
}
return (
<div
className={classNames(
'module-media-grid-item__icon',
'module-media-grid-item__icon-generic'
)}
/>
);
}
public render() {
return (
<div
className="module-media-grid-item"
role="button"
onClick={this.props.onClick}
>
{this.renderContent()}
</div>
);
}
}