Filter Images by surfaces
Summary: Adds a capability to filter images by surfaces. Note: I will allow multi select in the next diff, stacked on the current one. Reviewed By: passy Differential Revision: D14158223 fbshipit-source-id: d96d73b94a8a442f3b60f656bc573b328c5500ad
This commit is contained in:
committed by
Facebook Github Bot
parent
520ffec7c9
commit
863088e7cf
@@ -18,6 +18,7 @@ import {
|
||||
FlexColumn,
|
||||
LoadingIndicator,
|
||||
styled,
|
||||
Select,
|
||||
} from 'flipper';
|
||||
import type {ImagesMap} from './ImagePool.js';
|
||||
import {clipboard} from 'electron';
|
||||
@@ -32,6 +33,9 @@ function formatKB(bytes: number) {
|
||||
}
|
||||
|
||||
type ImagesCacheOverviewProps = {
|
||||
surfaceOptions: {[key: string]: string},
|
||||
selectedSurface: string,
|
||||
onChangeSurface: (key: string) => void,
|
||||
images: ImagesList,
|
||||
onClear: (type: string) => void,
|
||||
onTrimMemory: () => void,
|
||||
@@ -50,6 +54,12 @@ type ImagesCacheOverviewState = {|
|
||||
size: number,
|
||||
|};
|
||||
|
||||
const StyledSelect = styled(Select)(props => ({
|
||||
marginLeft: 6,
|
||||
marginRight: 6,
|
||||
height: '100%',
|
||||
}));
|
||||
|
||||
export default class ImagesCacheOverview extends PureComponent<
|
||||
ImagesCacheOverviewProps,
|
||||
ImagesCacheOverviewState,
|
||||
@@ -133,6 +143,11 @@ export default class ImagesCacheOverview extends PureComponent<
|
||||
<Button onClick={this.onEnableAutoRefreshToggled}>
|
||||
Auto Refresh {this.props.isAutoRefreshEnabled ? 'ON' : 'OFF'}
|
||||
</Button>
|
||||
<StyledSelect
|
||||
options={this.props.surfaceOptions}
|
||||
selected={this.props.selectedSurface}
|
||||
onChange={this.props.onChangeSurface}
|
||||
/>
|
||||
<Spacer />
|
||||
<input
|
||||
type="range"
|
||||
|
||||
@@ -37,6 +37,7 @@ export type ImageData = {|
|
||||
height: number,
|
||||
sizeBytes: number,
|
||||
data: ImageBytes,
|
||||
surface?: string,
|
||||
|};
|
||||
|
||||
// getImage({imageId: string}) -> ImageData
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
ImagesListResponse,
|
||||
ImageEvent,
|
||||
FrescoDebugOverlayEvent,
|
||||
CacheInfo,
|
||||
} from './api.js';
|
||||
import type {ImagesMap} from './ImagePool.js';
|
||||
|
||||
@@ -31,15 +32,18 @@ import ImagePool from './ImagePool.js';
|
||||
export type ImageEventWithId = ImageEvent & {eventId: number};
|
||||
|
||||
type PersistedState = {
|
||||
surfaceList: Set<string>,
|
||||
images: ImagesList,
|
||||
events: Array<ImageEventWithId>,
|
||||
imagesMap: ImagesMap,
|
||||
};
|
||||
|
||||
type PluginState = {
|
||||
selectedSurface: string,
|
||||
selectedImage: ?ImageId,
|
||||
isDebugOverlayEnabled: boolean,
|
||||
isAutoRefreshEnabled: boolean,
|
||||
images: ImagesList,
|
||||
};
|
||||
|
||||
const EmptySidebar = styled(FlexRow)({
|
||||
@@ -51,12 +55,14 @@ const EmptySidebar = styled(FlexRow)({
|
||||
});
|
||||
|
||||
const DEBUG = false;
|
||||
const surfaceDefaultText = 'SELECT ALL SURFACES';
|
||||
|
||||
export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
static defaultPersistedState: PersistedState = {
|
||||
images: [],
|
||||
events: [],
|
||||
imagesMap: {},
|
||||
surfaceList: new Set(),
|
||||
};
|
||||
|
||||
state: PluginState;
|
||||
@@ -64,9 +70,11 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
nextEventId: number = 1;
|
||||
|
||||
state = {
|
||||
selectedSurface: surfaceDefaultText,
|
||||
selectedImage: null,
|
||||
isDebugOverlayEnabled: false,
|
||||
isAutoRefreshEnabled: false,
|
||||
images: [],
|
||||
};
|
||||
|
||||
init() {
|
||||
@@ -76,6 +84,14 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
}
|
||||
this.updateCaches('init');
|
||||
this.client.subscribe('events', (event: ImageEvent) => {
|
||||
const {surfaceList} = this.props.persistedState;
|
||||
const {attribution} = event;
|
||||
if (attribution instanceof Array && attribution.length > 0) {
|
||||
const surface = attribution[0].trim();
|
||||
if (surface.length > 0) {
|
||||
surfaceList.add(surface);
|
||||
}
|
||||
}
|
||||
this.props.setPersistedState({
|
||||
events: [
|
||||
{eventId: this.nextEventId, ...event},
|
||||
@@ -100,6 +116,40 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
this.imagePool.clear();
|
||||
}
|
||||
|
||||
filterImages = (
|
||||
images: ImagesList,
|
||||
events: Array<ImageEventWithId>,
|
||||
surface: string,
|
||||
): ImagesList => {
|
||||
if (!surface || surface === surfaceDefaultText) {
|
||||
return images;
|
||||
}
|
||||
const imageList = images.map((image: CacheInfo) => {
|
||||
const imageIdList = image.imageIds.filter(imageID => {
|
||||
const filteredEvents = events.filter((event: ImageEventWithId) => {
|
||||
return (
|
||||
event.attribution &&
|
||||
event.attribution.length > 0 &&
|
||||
event.attribution[0] == surface &&
|
||||
event.imageIds &&
|
||||
event.imageIds.includes(imageID)
|
||||
);
|
||||
});
|
||||
return filteredEvents.length > 0;
|
||||
});
|
||||
return {...image, imageIds: imageIdList};
|
||||
});
|
||||
return imageList;
|
||||
};
|
||||
|
||||
updateImagesOnUI = (images: ImagesList, surface: string) => {
|
||||
const filteredImages = this.filterImages(
|
||||
images,
|
||||
this.props.persistedState.events,
|
||||
surface,
|
||||
);
|
||||
this.setState({selectedSurface: surface, images: filteredImages});
|
||||
};
|
||||
updateCaches = (reason: string) => {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -110,6 +160,10 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
this.imagePool.fetchImages(data.imageIds),
|
||||
);
|
||||
this.props.setPersistedState({images: response.levels});
|
||||
this.updateImagesOnUI(
|
||||
this.props.persistedState.images,
|
||||
this.state.selectedSurface,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -178,11 +232,24 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
||||
return <ImagesSidebar image={maybeImage} events={events} />;
|
||||
};
|
||||
|
||||
onSurfaceChange = (surface: string) => {
|
||||
this.updateImagesOnUI(this.props.persistedState.images, surface);
|
||||
};
|
||||
|
||||
render() {
|
||||
const options = [...this.props.persistedState.surfaceList].reduce(
|
||||
(acc, item) => {
|
||||
return {...acc, [item]: item};
|
||||
},
|
||||
{[surfaceDefaultText]: surfaceDefaultText},
|
||||
);
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ImagesCacheOverview
|
||||
images={this.props.persistedState.images}
|
||||
surfaceOptions={options}
|
||||
selectedSurface={this.state.selectedSurface}
|
||||
onChangeSurface={this.onSurfaceChange}
|
||||
images={this.state.images}
|
||||
onClear={this.onClear}
|
||||
onTrimMemory={this.onTrimMemory}
|
||||
onRefresh={() => this.updateCaches('refresh')}
|
||||
|
||||
Reference in New Issue
Block a user