Files
flipper/src/ui/components/File.tsx
Daniel Büchele 9159256a3c File components
Summary: _typescript_

Reviewed By: passy

Differential Revision: D16830536

fbshipit-source-id: 979ee7d0ced339ff5c0d200c209d34656827e152
2019-08-20 04:09:42 -07:00

91 lines
2.3 KiB
TypeScript

/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import React, {Component} from 'react';
import fs from 'fs';
type FileProps = {
/** Path to the file in the file system */
src: string;
/** Initial content that should be shown while the file is loading */
buffer?: string | null | undefined;
/** Encoding to parse the contents of the file. Defaults to UTF-8. */
encoding: string;
/** Content that should be rendered, when the file loading failed. */
onError?: (err: Error) => React.ReactNode;
/** Content that should be rendered, while the file is loaded. */
onLoading?: () => React.ReactNode;
/** Callback when the data is successfully loaded. */
onData?: (content: string) => void;
/** Content that should be rendered, when the file is successfully loaded. This ususally should render the file's contents. */
onLoad: (content: string) => React.ReactNode;
};
type FileState = {
error: Error | null | undefined;
loaded: boolean;
content: string;
};
/**
* Wrapper for loading file content from the file system.
*/
export default class File extends Component<FileProps, FileState> {
constructor(props: FileProps, context: Object) {
super(props, context);
this.state = {
content: props.buffer || '',
error: null,
loaded: props.buffer != null,
};
}
static defaultProps = {
encoding: 'utf8',
};
componentWillReceiveProps(nextProps: FileProps) {
if (nextProps.buffer != null) {
this.setState({content: nextProps.buffer, loaded: true});
}
}
componentDidMount() {
if (this.state.loaded) {
return;
}
fs.readFile(this.props.src, this.props.encoding, (err, content) => {
if (err) {
this.setState({error: err});
return;
}
this.setState({content, loaded: true});
if (this.props.onData) {
this.props.onData(content);
}
});
}
render() {
const {onError, onLoad, onLoading} = this.props;
const {content, error, loaded} = this.state;
if (error && onError) {
return onError(error);
} else if (loaded) {
return onLoad(content);
} else if (onLoading) {
return onLoading();
} else {
return null;
}
}
}