mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-18 16:56:32 +00:00
Make Flash component a class & rename it FlashStep
Change-type: patch
This commit is contained in:
parent
f9cbff1eec
commit
a3a9edd41a
@ -164,78 +164,91 @@ const formatSeconds = (totalSeconds: number) => {
|
|||||||
return `${minutes}m${seconds}s`;
|
return `${minutes}m${seconds}s`;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface FlashProps {
|
interface FlashStepProps {
|
||||||
shouldFlashStepBeDisabled: boolean;
|
shouldFlashStepBeDisabled: boolean;
|
||||||
goToSuccess: () => void;
|
goToSuccess: () => void;
|
||||||
source: SourceOptions;
|
source: SourceOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Flash = ({
|
interface FlashStepState {
|
||||||
shouldFlashStepBeDisabled,
|
warningMessages: string[];
|
||||||
goToSuccess,
|
errorMessage: string;
|
||||||
source,
|
showDriveSelectorModal: boolean;
|
||||||
}: FlashProps) => {
|
}
|
||||||
const state: any = flashState.getFlashState();
|
|
||||||
const isFlashing = flashState.isFlashing();
|
|
||||||
const flashErrorCode = flashState.getLastFlashErrorCode();
|
|
||||||
|
|
||||||
const [warningMessages, setWarningMessages] = React.useState<string[]>([]);
|
export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
|
||||||
const [errorMessage, setErrorMessage] = React.useState('');
|
constructor(props: FlashStepProps) {
|
||||||
const [showDriveSelectorModal, setShowDriveSelectorModal] = React.useState(
|
super(props);
|
||||||
false,
|
this.state = {
|
||||||
);
|
warningMessages: [],
|
||||||
|
errorMessage: '',
|
||||||
const handleWarningResponse = async (shouldContinue: boolean) => {
|
showDriveSelectorModal: false,
|
||||||
setWarningMessages([]);
|
};
|
||||||
|
|
||||||
if (!shouldContinue) {
|
|
||||||
setShowDriveSelectorModal(true);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setErrorMessage(await flashImageToDrive(goToSuccess, source));
|
private async handleWarningResponse(shouldContinue: boolean) {
|
||||||
};
|
this.setState({ warningMessages: [] });
|
||||||
|
if (!shouldContinue) {
|
||||||
|
this.setState({ showDriveSelectorModal: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
errorMessage: await flashImageToDrive(
|
||||||
|
this.props.goToSuccess,
|
||||||
|
this.props.source,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const handleFlashErrorResponse = (shouldRetry: boolean) => {
|
private handleFlashErrorResponse(shouldRetry: boolean) {
|
||||||
setErrorMessage('');
|
this.setState({ errorMessage: '' });
|
||||||
flashState.resetState();
|
flashState.resetState();
|
||||||
if (shouldRetry) {
|
if (shouldRetry) {
|
||||||
analytics.logEvent('Restart after failure');
|
analytics.logEvent('Restart after failure');
|
||||||
} else {
|
} else {
|
||||||
selection.clear();
|
selection.clear();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const tryFlash = async () => {
|
private async tryFlash() {
|
||||||
const devices = selection.getSelectedDevices();
|
const devices = selection.getSelectedDevices();
|
||||||
const image = selection.getImage();
|
const image = selection.getImage();
|
||||||
const drives = _.filter(availableDrives.getDrives(), (drive: any) => {
|
const drives = _.filter(
|
||||||
|
availableDrives.getDrives(),
|
||||||
|
(drive: { device: string }) => {
|
||||||
return _.includes(devices, drive.device);
|
return _.includes(devices, drive.device);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
if (drives.length === 0 || flashState.isFlashing()) {
|
if (drives.length === 0 || flashState.isFlashing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasDangerStatus = constraints.hasListDriveImageCompatibilityStatus(
|
const hasDangerStatus = constraints.hasListDriveImageCompatibilityStatus(
|
||||||
drives,
|
drives,
|
||||||
image,
|
image,
|
||||||
);
|
);
|
||||||
if (hasDangerStatus) {
|
if (hasDangerStatus) {
|
||||||
setWarningMessages(getWarningMessages(drives, image));
|
this.setState({ warningMessages: getWarningMessages(drives, image) });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.setState({
|
||||||
|
errorMessage: await flashImageToDrive(
|
||||||
|
this.props.goToSuccess,
|
||||||
|
this.props.source,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setErrorMessage(await flashImageToDrive(goToSuccess, source));
|
public render() {
|
||||||
};
|
const state = flashState.getFlashState();
|
||||||
|
const isFlashing = flashState.isFlashing();
|
||||||
|
const flashErrorCode = flashState.getLastFlashErrorCode();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="box text-center">
|
<div className="box text-center">
|
||||||
<div className="center-block">
|
<div className="center-block">
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
paths={['../../assets/flash.svg']}
|
paths={['../../assets/flash.svg']}
|
||||||
disabled={shouldFlashStepBeDisabled}
|
disabled={this.props.shouldFlashStepBeDisabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -246,8 +259,13 @@ export const Flash = ({
|
|||||||
active={isFlashing}
|
active={isFlashing}
|
||||||
percentage={state.percentage}
|
percentage={state.percentage}
|
||||||
label={getProgressButtonLabel()}
|
label={getProgressButtonLabel()}
|
||||||
disabled={Boolean(flashErrorCode) || shouldFlashStepBeDisabled}
|
disabled={
|
||||||
callback={tryFlash}
|
Boolean(flashErrorCode) ||
|
||||||
|
this.props.shouldFlashStepBeDisabled
|
||||||
|
}
|
||||||
|
callback={() => {
|
||||||
|
this.tryFlash();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</StepSelection>
|
</StepSelection>
|
||||||
|
|
||||||
@ -259,10 +277,13 @@ export const Flash = ({
|
|||||||
<span className="glyphicon glyphicon-remove-sign"></span>
|
<span className="glyphicon glyphicon-remove-sign"></span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{!_.isNil(state.speed) && state.percentage !== COMPLETED_PERCENTAGE && (
|
{!_.isNil(state.speed) &&
|
||||||
|
state.percentage !== COMPLETED_PERCENTAGE && (
|
||||||
<p className="step-footer step-footer-split">
|
<p className="step-footer step-footer-split">
|
||||||
{Boolean(state.speed) && (
|
{Boolean(state.speed) && (
|
||||||
<span>{`${state.speed.toFixed(SPEED_PRECISION)} MB/s`}</span>
|
<span>{`${state.speed.toFixed(
|
||||||
|
SPEED_PRECISION,
|
||||||
|
)} MB/s`}</span>
|
||||||
)}
|
)}
|
||||||
{!_.isNil(state.eta) && (
|
{!_.isNil(state.eta) && (
|
||||||
<span>{`ETA: ${formatSeconds(state.eta)}`}</span>
|
<span>{`ETA: ${formatSeconds(state.eta)}`}</span>
|
||||||
@ -284,19 +305,19 @@ export const Flash = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{warningMessages && warningMessages.length > 0 && (
|
{this.state.warningMessages.length > 0 && (
|
||||||
<Modal
|
<Modal
|
||||||
width={400}
|
width={400}
|
||||||
titleElement={'Attention'}
|
titleElement={'Attention'}
|
||||||
cancel={() => handleWarningResponse(false)}
|
cancel={() => this.handleWarningResponse(false)}
|
||||||
done={() => handleWarningResponse(true)}
|
done={() => this.handleWarningResponse(true)}
|
||||||
cancelButtonProps={{
|
cancelButtonProps={{
|
||||||
children: 'Change',
|
children: 'Change',
|
||||||
}}
|
}}
|
||||||
action={'Continue'}
|
action={'Continue'}
|
||||||
primaryButtonProps={{ primary: false, warning: true }}
|
primaryButtonProps={{ primary: false, warning: true }}
|
||||||
>
|
>
|
||||||
{_.map(warningMessages, (message, key) => (
|
{_.map(this.state.warningMessages, (message, key) => (
|
||||||
<Txt key={key} whitespace="pre-line" mt={2}>
|
<Txt key={key} whitespace="pre-line" mt={2}>
|
||||||
{message}
|
{message}
|
||||||
</Txt>
|
</Txt>
|
||||||
@ -304,27 +325,28 @@ export const Flash = ({
|
|||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{errorMessage && (
|
{this.state.errorMessage && (
|
||||||
<Modal
|
<Modal
|
||||||
width={400}
|
width={400}
|
||||||
titleElement={'Attention'}
|
titleElement={'Attention'}
|
||||||
cancel={() => handleFlashErrorResponse(false)}
|
cancel={() => this.handleFlashErrorResponse(false)}
|
||||||
done={() => handleFlashErrorResponse(true)}
|
done={() => this.handleFlashErrorResponse(true)}
|
||||||
action={'Retry'}
|
action={'Retry'}
|
||||||
>
|
>
|
||||||
<Txt>
|
<Txt>
|
||||||
{_.map(errorMessage.split('\n'), (message, key) => (
|
{_.map(this.state.errorMessage.split('\n'), (message, key) => (
|
||||||
<p key={key}>{message}</p>
|
<p key={key}>{message}</p>
|
||||||
))}
|
))}
|
||||||
</Txt>
|
</Txt>
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showDriveSelectorModal && (
|
{this.state.showDriveSelectorModal && (
|
||||||
<DriveSelectorModal
|
<DriveSelectorModal
|
||||||
close={() => setShowDriveSelectorModal(false)}
|
close={() => this.setState({ showDriveSelectorModal: false })}
|
||||||
></DriveSelectorModal>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
@ -47,7 +47,7 @@ import { middleEllipsis } from '../../utils/middle-ellipsis';
|
|||||||
import { bytesToClosestUnit } from '../../../../shared/units';
|
import { bytesToClosestUnit } from '../../../../shared/units';
|
||||||
|
|
||||||
import { DriveSelector } from './DriveSelector';
|
import { DriveSelector } from './DriveSelector';
|
||||||
import { Flash } from './Flash';
|
import { FlashStep } from './Flash';
|
||||||
|
|
||||||
const Icon = styled(BaseIcon)`
|
const Icon = styled(BaseIcon)`
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
@ -249,7 +249,7 @@ export class MainPage extends React.Component<
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-xs">
|
<div className="col-xs">
|
||||||
<Flash
|
<FlashStep
|
||||||
goToSuccess={() => this.setState({ current: 'success' })}
|
goToSuccess={() => this.setState({ current: 'success' })}
|
||||||
shouldFlashStepBeDisabled={shouldFlashStepBeDisabled}
|
shouldFlashStepBeDisabled={shouldFlashStepBeDisabled}
|
||||||
source={this.state.source}
|
source={this.state.source}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user