Migrate Images plugin to ant.design

Summary: {gif:xcsasxxe}

Reviewed By: mweststrate

Differential Revision: D28463799

fbshipit-source-id: 280eaaf0ad5858b3507055a278d1f98fd5668fd0
This commit is contained in:
Mathias Fleig Mortensen
2021-05-18 04:12:21 -07:00
committed by Facebook GitHub Bot
parent 6e206fc054
commit 996e8ab87c
4 changed files with 187 additions and 389 deletions

View File

@@ -10,23 +10,22 @@
import {CacheInfo, ImageId, ImageData, ImagesList} from './api';
import {ImageEventWithId} from './index';
import {styled, Layout, Toolbar, theme} from 'flipper-plugin';
import {
Toolbar,
Button,
Spacer,
colors,
FlexBox,
FlexRow,
FlexColumn,
LoadingIndicator,
styled,
ToggleButton,
Text,
} from 'flipper';
Switch,
Empty,
Skeleton,
Typography,
Image,
Row,
Col,
Badge,
} from 'antd';
import MultipleSelect from './MultipleSelect';
import {ImagesMap} from './ImagePool';
import {clipboard} from 'electron';
import React, {ChangeEvent, KeyboardEvent, PureComponent} from 'react';
import React, {PureComponent} from 'react';
import {DeleteFilled} from '@ant-design/icons';
function formatMB(bytes: number) {
return Math.floor(bytes / (1024 * 1024)) + 'MB';
@@ -42,26 +41,16 @@ type ToggleProps = {
toggled: boolean;
};
const ToolbarToggleButton = styled(ToggleButton)(() => ({
alignSelf: 'center',
marginRight: 4,
minWidth: 30,
}));
const ToggleLabel = styled(Text)(() => ({
whiteSpace: 'nowrap',
}));
function Toggle(props: ToggleProps) {
return (
<>
<ToolbarToggleButton
<Switch
onClick={() => {
props.onClick && props.onClick(!props.toggled);
}}
toggled={props.toggled}
checked={props.toggled}
/>
<ToggleLabel>{props.label}</ToggleLabel>
<Typography.Text>{props.label}</Typography.Text>
</>
);
}
@@ -104,39 +93,11 @@ export default class ImagesCacheOverview extends PureComponent<
size: 150,
};
static Container = styled(FlexColumn)({
backgroundColor: colors.white,
});
static Content = styled(FlexColumn)({
flex: 1,
overflow: 'auto',
});
static Empty = styled(FlexBox)({
alignItems: 'center',
height: '100%',
justifyContent: 'center',
width: '100%',
});
onImageSelected = (selectedImage: ImageId) => {
this.setState({selectedImage});
this.props.onImageSelected(selectedImage);
};
onKeyDown = (e: KeyboardEvent) => {
const selectedImage = this.state.selectedImage;
const imagesMap = this.props.imagesMap;
if (selectedImage) {
if ((e.ctrlKey || e.metaKey) && e.key === 'c') {
clipboard.writeText(String(imagesMap[selectedImage]));
e.preventDefault();
}
}
};
onEnableDebugOverlayToggled = () => {
this.props.onEnableDebugOverlay(!this.props.isDebugOverlayEnabled);
};
@@ -145,9 +106,6 @@ export default class ImagesCacheOverview extends PureComponent<
this.props.onEnableAutoRefresh(!this.props.isAutoRefreshEnabled);
};
onChangeSize = (e: ChangeEvent<HTMLInputElement>) =>
this.setState({size: parseInt(e.target.value, 10)});
onSurfaceOptionsChange = (selectedItem: string, checked: boolean) => {
const {allSurfacesOption, surfaceOptions} = this.props;
const selectedSurfaces = new Set([...this.props.selectedSurfaces]);
@@ -190,12 +148,11 @@ export default class ImagesCacheOverview extends PureComponent<
) > 0;
return (
<ImagesCacheOverview.Container
grow
onKeyDown={this.onKeyDown}
tabIndex={0}>
<Toolbar position="top">
<Button icon="trash" onClick={this.props.onTrimMemory}>
<Layout.Top>
<Toolbar>
<Button
icon={<DeleteFilled></DeleteFilled>}
onClick={this.props.onTrimMemory}>
Trim Memory
</Button>
<Button onClick={this.props.onRefresh}>Refresh</Button>
@@ -230,21 +187,13 @@ export default class ImagesCacheOverview extends PureComponent<
onClick={this.props.onShowDiskImages}
label="Show Disk Images"
/>
<Spacer />
<input
type="range"
onChange={this.onChangeSize}
min={50}
max={150}
value={this.state.size}
/>
</Toolbar>
{!hasImages ? (
<ImagesCacheOverview.Empty>
<LoadingIndicator size={50} />
</ImagesCacheOverview.Empty>
<Layout.Container pad>
<Empty />
</Layout.Container>
) : (
<ImagesCacheOverview.Content>
<Layout.ScrollContainer>
{this.props.images.map((data: CacheInfo, index: number) => {
const maxSize = data.maxSizeBytes;
const subtitle = maxSize
@@ -263,15 +212,14 @@ export default class ImagesCacheOverview extends PureComponent<
onImageSelected={this.onImageSelected}
selectedImage={this.state.selectedImage}
imagesMap={this.props.imagesMap}
size={this.state.size}
events={this.props.events}
onClear={onClear}
/>
);
})}
</ImagesCacheOverview.Content>
</Layout.ScrollContainer>
)}
</ImagesCacheOverview.Container>
</Layout.Top>
);
}
}
@@ -284,7 +232,6 @@ class ImageGrid extends PureComponent<{
onImageSelected: (image: ImageId) => void;
onClear: (() => void) | undefined;
imagesMap: ImagesMap;
size: number;
events: Array<ImageEventWithId>;
}> {
static Content = styled.div({
@@ -298,31 +245,48 @@ class ImageGrid extends PureComponent<{
return null;
}
const ROW_SIZE = 6;
const imageRows = Array(Math.ceil(images.length / ROW_SIZE))
.fill(0)
.map((_, index) => index * ROW_SIZE)
.map((begin) => images.slice(begin, begin + ROW_SIZE));
return (
<>
<Layout.Container gap>
<ImageGridHeader
key="header"
title={this.props.title}
subtitle={this.props.subtitle}
onClear={this.props.onClear}
/>
<ImageGrid.Content key="content">
{images.map((imageId) => (
<ImageItem
imageId={imageId}
image={this.props.imagesMap[imageId]}
key={imageId}
selected={selectedImage != null && selectedImage === imageId}
onSelected={onImageSelected}
size={this.props.size}
numberOfRequests={
this.props.events.filter((e) => e.imageIds.includes(imageId))
.length
}
/>
<Layout.Container pad>
{imageRows.map((row, rowIndex) => (
<Layout.Container pad key={rowIndex}>
<Row key={rowIndex} align={'middle'} gutter={[8, 24]}>
{row.map((imageId, colIndex) => (
<Col key={colIndex} span={24 / ROW_SIZE}>
<ImageItem
imageId={imageId}
image={this.props.imagesMap[imageId]}
key={imageId}
selected={
selectedImage != null && selectedImage === imageId
}
onSelected={onImageSelected}
numberOfRequests={
this.props.events.filter((e) =>
e.imageIds.includes(imageId),
).length
}
/>
</Col>
))}
</Row>
</Layout.Container>
))}
</ImageGrid.Content>
</>
</Layout.Container>
</Layout.Container>
);
}
}
@@ -332,56 +296,23 @@ class ImageGridHeader extends PureComponent<{
subtitle: string;
onClear: (() => void) | undefined;
}> {
static Container = styled(FlexRow)({
color: colors.dark70,
paddingTop: 10,
paddingBottom: 10,
marginLeft: 15,
marginRight: 15,
marginBottom: 15,
borderBottom: `1px solid ${colors.light10}`,
flexShrink: 0,
alignItems: 'center',
position: 'sticky',
top: 0,
left: 0,
right: 0,
backgroundColor: colors.white,
zIndex: 3,
});
static Heading = styled.span({
fontSize: 22,
fontWeight: 600,
});
static Subtitle = styled.span({
fontSize: 22,
fontWeight: 300,
marginLeft: 15,
});
static ClearButton = styled(Button)({
alignSelf: 'center',
height: 30,
marginLeft: 'auto',
width: 100,
});
render() {
return (
<ImageGridHeader.Container>
<ImageGridHeader.Heading>{this.props.title}</ImageGridHeader.Heading>
<Layout.Horizontal gap pad grow borderBottom>
<Typography.Title>{this.props.title}</Typography.Title>
<ImageGridHeader.Subtitle>
{this.props.subtitle}
</ImageGridHeader.Subtitle>
<Spacer />
{this.props.onClear ? (
<ImageGridHeader.ClearButton onClick={this.props.onClear}>
Clear Cache
</ImageGridHeader.ClearButton>
<Button onClick={this.props.onClear}>Clear Cache</Button>
) : null}
</ImageGridHeader.Container>
</Layout.Horizontal>
);
}
}
@@ -394,36 +325,16 @@ class ImageItem extends PureComponent<{
size: number;
numberOfRequests: number;
}> {
static Container = styled(FlexBox)<{size: number}>((props) => ({
float: 'left',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
height: props.size,
width: props.size,
borderRadius: 4,
marginRight: 15,
marginBottom: 15,
backgroundColor: colors.light02,
}));
static Image = styled.img({
borderRadius: 4,
maxHeight: '100%',
maxWidth: '100%',
objectFit: 'contain',
});
static Loading = styled.span({
padding: '0 0',
});
static defaultProps = {
size: 150,
};
static SelectedHighlight = styled.div<{selected: boolean}>((props) => ({
borderColor: colors.highlight,
borderColor: theme.primaryColor,
borderStyle: 'solid',
borderWidth: props.selected ? 3 : 0,
borderRadius: 4,
boxShadow: props.selected ? `inset 0 0 0 1px ${colors.white}` : 'none',
boxShadow: props.selected ? `inset 0 0 0 1px ${theme.white}` : 'none',
bottom: 0,
left: 0,
position: 'absolute',
@@ -431,25 +342,26 @@ class ImageItem extends PureComponent<{
top: 0,
}));
static HoverOverlay = styled(FlexColumn)<{selected: boolean; size: number}>(
(props) => ({
alignItems: 'center',
backgroundColor: colors.whiteAlpha80,
bottom: props.selected ? 4 : 0,
fontSize: props.size > 100 ? 16 : 11,
justifyContent: 'center',
left: props.selected ? 4 : 0,
opacity: 0,
position: 'absolute',
right: props.selected ? 4 : 0,
top: props.selected ? 4 : 0,
overflow: 'hidden',
transition: '.1s opacity',
'&:hover': {
opacity: 1,
},
}),
);
static HoverOverlay = styled(Layout.Container)<{
selected: boolean;
size: number;
}>((props) => ({
alignItems: 'center',
backgroundColor: 'rgba(255,255,255,0.8)',
bottom: props.selected ? 4 : 0,
fontSize: props.size > 100 ? 16 : 11,
justifyContent: 'center',
left: props.selected ? 4 : 0,
opacity: 0,
position: 'absolute',
right: props.selected ? 4 : 0,
top: props.selected ? 4 : 0,
overflow: 'hidden',
transition: '.1s opacity',
'&:hover': {
opacity: 1,
},
}));
static MemoryLabel = styled.span({
fontWeight: 600,
@@ -460,25 +372,13 @@ class ImageItem extends PureComponent<{
fontWeight: 300,
});
static Events = styled.div({
static EventBadge = styled(Badge)({
position: 'absolute',
top: -5,
right: -5,
color: colors.white,
backgroundColor: colors.highlight,
fontWeight: 600,
borderRadius: 10,
fontSize: '0.85em',
zIndex: 2,
lineHeight: '20px',
width: 20,
textAlign: 'center',
top: 0,
right: 0,
zIndex: 1,
});
static defaultProps = {
size: 150,
};
onClick = () => {
this.props.onSelected(this.props.imageId);
};
@@ -487,14 +387,14 @@ class ImageItem extends PureComponent<{
const {image, selected, size, numberOfRequests} = this.props;
return (
<ImageItem.Container onClick={this.onClick} size={size}>
<Layout.Container onClick={this.onClick} gap>
{numberOfRequests > 0 && image != null && (
<ImageItem.Events>{numberOfRequests}</ImageItem.Events>
<ImageItem.EventBadge count={numberOfRequests}></ImageItem.EventBadge>
)}
{image != null ? (
<ImageItem.Image src={image.data} />
<Image src={image.data} preview={false} />
) : (
<LoadingIndicator size={25} />
<Skeleton.Image />
)}
<ImageItem.SelectedHighlight selected={selected} />
{image != null && (
@@ -507,7 +407,7 @@ class ImageItem extends PureComponent<{
</ImageItem.SizeLabel>
</ImageItem.HoverOverlay>
)}
</ImageItem.Container>
</Layout.Container>
);
}
}