Я сейчас учусь программировать на JavaScript и пытаюсь изменить приложение для личного проекта. Приложение имеет две основные функции.
Сначала приложение создает ha sh файла, загруженного пользователем (который затем загружается в блокчейн, но эта сторона вещей полностью функциональна), и если ha sh определенного файла уже находится в цепочке блоков при попытке загрузки, пользователь получает соответствующее сообщение, сообщающее ему об этом.
Вторая функция, или menuItem, приложения позволяет пользователю введите ha sh, чтобы узнать, хранится ли он в блокчейне, и если да, он отображает, когда исходный файл был загружен, а также возвращает ha sh.
Вот код приложения:
class App extends Component {
state = {
webServiceErrorStatus: null,
isUploadLoading: false,
isSearchLoading: false,
isReaderError: false,
isAfterUpload: false,
isAfterSearch: false,
fileHash: '',
fileInfo: null,
uploadedHashes: []
}
constructor() {
super();
this.WebService = null;
}
async componentWillMount() {
this.WebService = new WebService();
this.setState({
fileInfo: new file()
});
}
fileHashChanged = event => {
this.setState({
webServiceErrorStatus: null,
isAfterSearch: false,
fileHash: event.target.value,
});
};
searchFormSubmitted = async () => {
this.setState({
isSearchLoading: true
});
var response = await this.WebService.getFileAsync(this.state.fileHash);
if(response instanceof WebServiceErrorStatusesEnum) {
this.setState({
webServiceErrorStatus: response
});
}
else {
this.setState({
fileInfo: response,
isAfterSearch: true
});
}
this.setState({
isSearchLoading: false
});
};
fileDropped = async (acceptedFiles) => {
acceptedFiles.forEach(file => {
this.setState({
isUploadLoading: true,
webServiceErrorStatus: null,
isReaderError : false
});
var uploadedHashes = [];
const reader = new FileReader();
reader.onerror = () => {
console.log('file reading has failed');
this.setState({
isUploadLoading: false,
isReaderError: true
});
}
reader.onload = async () => {
const fileAsArrayBuffer = reader.result;
var response = await this.WebService.addFileAsync(fileAsArrayBuffer);
if(response instanceof WebServiceErrorStatusesEnum) {
this.setState({
webServiceErrorStatus: response,
isUploadLoading: false
});
}
else {
uploadedHashes.push(response.fileHash)
var tempUploadedHashes = this.state.uploadedHashes;
tempUploadedHashes.push(...uploadedHashes);
console.log(response);
this.setState({
isAfterUpload: true,
uploadedHashes: tempUploadedHashes,
isUploadLoading: false
});
Вместе с двумя пунктами меню:
{ menuItem: {content: 'Upload', icon:'upload', key: 'Upload'}, render: () =>
<Tab.Pane className='tabPane'>
<Segment basic loading={this.state.isUploadLoading}>
<Form error={this.state.webServiceErrorStatus === WebServiceErrorStatusesEnum.DifferentAddError}>
<Header color='black' as='h2'>Upload</Header>
<ReactDropzone multiple={false}
className='dropZoneDefaultState'
acceptClassName='dropZoneAcceptState'
rejectClassName='dropZoneRejectState'
onDrop={this.fileDropped}>
<Segment basic>
<Icon disabled name='file outline' size='massive' color='black'/>
<Header as='h4' color='black'>Drop file or click to upload </Header>
</Segment>
</ReactDropzone>
<Message error header='Action Error' content='Something went wrong. Please contact with system administrator.' />
</Form>
{this.state.isAfterUpload && this.state.uploadedHashes.length > 0 &&
<Segment raised>
<Header color='black' as='h3'>Uploaded files hash list:</Header>
<List ordered relaxed style={{textAlign: 'left'}}>
{this.state.uploadedHashes.map((hash, index) =>
<List.Item key={index}>
<List.Header>
{hash}
</List.Header>
</List.Item>)}
</List>
</Segment>}
{this.state.webServiceErrorStatus === WebServiceErrorStatusesEnum.FileAlreadyExists &&
<Segment raised>
<Header color='black' as='h3'>File already exists!</Header>
</Segment>}
{this.state.isReaderError &&
<Segment raised>
<Header color='red' as='h3'>Problem with reading file!</Header>
</Segment>}
</Segment>
и
{ menuItem: {content: 'Search', icon:'search', key: 'Search'}, render: () =>
<Tab.Pane className='tabPane'>
<Segment basic loading={this.state.isSearchLoading}>
<Header color='black' as='h2'>Search</Header>
<Form onSubmit={this.searchFormSubmitted} error={this.state.webServiceErrorStatus === WebServiceErrorStatusesEnum.DifferentGetError}>
<Form.Input fluid
action={{disabled: this.state.fileHash === '', icon: 'search'}}
placeholder='Provide file hash...'
type='text' value={this.state.fileHash}
onChange={this.fileHashChanged} />
<Message error header='Action Error' content='Something went wrong. Please contact with system administrator.' />
</Form>
{this.state.fileHash !== '' && this.state.isAfterSearch &&
<Segment raised>
<Header color='black' as='h3'>This file exists in blockchain:</Header>
<List relaxed>
<List.Item>
<List.Header>Upload Time</List.Header>
<List.Description>
{this.state.fileInfo.time}
</List.Description>
</List.Item>
<List.Item>
<List.Header>Hash</List.Header>
<List.Description>
{this.state.fileInfo.hash}
</List.Description>
</List.Item>
<List.Item>
<List.Content>
<List.Description>
<a target="_blank" rel="noopener noreferrer" href={'http://' + this.state.fileInfo.url}>{this.state.fileInfo.url}</a>
</List.Description>
</List.Content>
</List.Item>
</List>
</Segment>}
{this.state.webServiceErrorStatus === WebServiceErrorStatusesEnum.FileNotExist &&
<Segment>
<Header color='red' as='h3'>This VNFD does not match anything in blockchain.</Header>
</Segment>}
</Segment>
Я хотел бы отобразить время загрузки и значение ha sh из второй menuItem в первом menuItem, когда пользователь загружает файл, который уже имеет ha sh в цепочке блоков, поскольку я хотел бы полностью удалить вторую функцию. Я знаю, что это не так просто, как переместить {this.state.fileInfo.time} или {this.state.fileInfo.hash} к первому элементу меню, но я не могу понять, как go сделать их работать там.
Кто-нибудь может объяснить мне, почему просто добавить их в {this.state.webServiceErrorStatus === WebServiceErrorStatusesEnum.FileAlreadyExists в первом menuItem, и как я могу это исправить?