summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gui/src/renderer/components/AppButton.tsx42
1 files changed, 42 insertions, 0 deletions
diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx
index 34a7f46e04..6f14fd16e9 100644
--- a/gui/src/renderer/components/AppButton.tsx
+++ b/gui/src/renderer/components/AppButton.tsx
@@ -1,3 +1,4 @@
+import log from 'electron-log';
import * as React from 'react';
import { Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp';
import { colors } from '../../config.json';
@@ -162,6 +163,47 @@ class BaseButton extends Component<IProps, IState> {
};
}
+interface IBlockingState {
+ isBlocked: boolean;
+}
+
+interface IBlockingProps {
+ children?: React.ReactNode;
+ onPress: () => Promise<void>;
+ disabled?: boolean;
+}
+
+export class BlockingButton extends Component<IBlockingProps, IBlockingState> {
+ public state = {
+ isBlocked: false,
+ };
+
+ public render() {
+ return React.Children.map(this.props.children, (child) => {
+ if (React.isValidElement(child)) {
+ return React.cloneElement(child as React.ReactElement<any>, {
+ ...child.props,
+ disabled: this.state.isBlocked || this.props.disabled,
+ onPress: this.onPress,
+ });
+ } else {
+ return child;
+ }
+ });
+ }
+
+ private onPress = () => {
+ this.setState({ isBlocked: true }, async () => {
+ try {
+ await this.props.onPress();
+ } catch (error) {
+ log.error(`onPress() failed - ${error}`);
+ }
+ this.setState({ isBlocked: false });
+ });
+ };
+}
+
export class RedButton extends BaseButton {
protected backgroundStyle = () => (this.state.hovered ? styles.redHover : styles.red);
}