react-native-elements#CheckBox TypeScript Examples

The following examples show how to use react-native-elements#CheckBox. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RetryPolicyConfiguration.tsx    From react-native-network-client with Apache License 2.0 4 votes vote down vote up
RetryPolicyConfiguration = (props: RetryPolicyConfigurationProps) => {
    const [statusCodesText, setStatusCodesText] = useState(
        props.statusCodes?.join(",") || ""
    );

    const onLinearPress = () =>
        onCheckBoxPress(
            props.policyType === Constants.RETRY_TYPES.LINEAR_RETRY
                ? undefined
                : Constants.RETRY_TYPES.LINEAR_RETRY
        );
    const onExponentialPress = () =>
        onCheckBoxPress(
            props.policyType === Constants.RETRY_TYPES.EXPONENTIAL_RETRY
                ? undefined
                : Constants.RETRY_TYPES.EXPONENTIAL_RETRY
        );
    const onCheckBoxPress = (policyType?: RetryTypes) => {
        props.onTypeSelected(policyType);
    };
    const linearRetryChecked =
        props.policyType === Constants.RETRY_TYPES.LINEAR_RETRY;
    const exponentialRetryChecked =
        props.policyType === Constants.RETRY_TYPES.EXPONENTIAL_RETRY;

    const buttonMethods = ["get", "post", "put", "patch", "delete"];
    const [selectedMethodsIndex, setSelectedMethodsIndex] = useState<number[]>([
        0,
        1,
    ]);

    if (props.setRetryMethods !== undefined) {
        useEffect(() => {
            const selectedMethods = selectedMethodsIndex.map(
                (index) => buttonMethods[index]
            );
            props.setRetryMethods!(selectedMethods);
        }, [selectedMethodsIndex]);
    }

    const PolicyTypeCheckbox = () => (
        <View style={{ flex: 1, flexDirection: "row" }}>
            <CheckBox
                title={`Linear [${linearRetryChecked}]`}
                checked={linearRetryChecked}
                onPress={onLinearPress}
                iconType="ionicon"
                checkedIcon="ios-checkmark-circle"
                uncheckedIcon="ios-checkmark-circle"
                iconRight
                containerStyle={{
                    padding: 0,
                    borderWidth: 0,
                    backgroundColor: "transparent",
                }}
            />
            <CheckBox
                title={`Exponential [${exponentialRetryChecked}]`}
                checked={exponentialRetryChecked}
                onPress={onExponentialPress}
                iconType="ionicon"
                checkedIcon="ios-checkmark-circle"
                uncheckedIcon="ios-checkmark-circle"
                iconRight
                containerStyle={{
                    padding: 0,
                    borderWidth: 0,
                    backgroundColor: "transparent",
                }}
            />
        </View>
    );

    const updateStatusCodes = () => {
        const statusCodes = statusCodesText
            .split(",")
            .map((code) => {
                return parseInt(code.trim());
            })
            .filter((code) => !isNaN(code));

        props.setStatusCodes(statusCodes);
    };

    return (
        <>
            <Input
                placeholder="Retry Policy"
                disabled={true}
                style={{ fontWeight: "bold", fontSize: 17, opacity: 1 }}
                containerStyle={{ height: 50 }}
                inputContainerStyle={{
                    borderColor: "rgba(255,255,255,0)",
                }}
                labelStyle={{ flex: 12, flexWrap: "wrap", height: 100 }}
            />

            <PolicyTypeCheckbox />

            {props.policyType && (
                <NumericInput
                    title="Retry limit"
                    value={props.retryLimit}
                    onChange={props.setRetryLimit}
                    minValue={0}
                    testID="retry_policy_configuration.retry_limit.input"
                />
            )}

            {props.policyType === Constants.RETRY_TYPES.LINEAR_RETRY && (
                <NumericInput
                    title="Retry interval"
                    value={props.retryInterval}
                    onChange={props.setRetryInterval}
                    minValue={1}
                    testID="retry_policy_configuration.retry_interval.input"
                />
            )}
            {props.policyType === Constants.RETRY_TYPES.EXPONENTIAL_RETRY && (
                <>
                    <NumericInput
                        title="Exponential backoff base"
                        value={props.exponentialBackoffBase}
                        onChange={props.setExponentialBackoffBase}
                        minValue={2}
                        testID="retry_policy_configuration.exponential_backoff_base.input"
                    />
                    <NumericInput
                        title="Exponential backoff scale"
                        value={props.exponentialBackoffScale}
                        onChange={props.setExponentialBackoffScale}
                        minValue={0}
                        valueType="real"
                        step={0.1}
                        testID="retry_policy_configuration.exponential_backoff_scale.input"
                    />
                </>
            )}

            {props.policyType && (
                <>
                    <Input
                        placeholder="Retry Status Codes"
                        disabled={true}
                        style={{ fontWeight: "bold", fontSize: 17, opacity: 1 }}
                        containerStyle={{ height: 50 }}
                        inputContainerStyle={{
                            borderColor: "rgba(255,255,255,0)",
                        }}
                    />

                    <Input
                        value={statusCodesText}
                        onChangeText={setStatusCodesText}
                        onBlur={updateStatusCodes}
                    />

                    {props.setRetryMethods && (
                        <>
                            <Input
                                placeholder="Retry Methods"
                                disabled={true}
                                style={{
                                    fontWeight: "bold",
                                    fontSize: 17,
                                    opacity: 1,
                                }}
                                containerStyle={{ height: 50 }}
                                inputContainerStyle={{
                                    borderColor: "rgba(255,255,255,0)",
                                }}
                            />

                            <ButtonGroup
                                selectedIndexes={selectedMethodsIndex}
                                // @ts-ignore
                                onPress={setSelectedMethodsIndex}
                                buttons={buttonMethods}
                                selectMultiple
                            />
                        </>
                    )}
                </>
            )}
        </>
    );
}
Example #2
Source File: APIClientUploadScreen.tsx    From react-native-network-client with Apache License 2.0 4 votes vote down vote up
APIClientUploadScreen = ({ route }: APIClientUploadScreenProps) => {
    const {
        item: { client },
    } = route.params;

    const [state, setState] = useState<UploadState>({
        endpoint: "/files",
        progress: 0,
    });

    const methods = ["POST", "PUT", "PATCH"];
    const [methodIndex, setMethodIndex] = useState<number>(0);
    const [multipart, setMultipart] = useState<boolean>(false);
    const [multipartFileKey, setMultipartFileKey] = useState("");
    const [multipartData, setMultipartData] = useState<Record<string, string>>(
        {}
    );
    const [skipBytes, setSkipBytes] = useState<number>(0);

    const setRequest = (request?: ProgressPromise<ClientResponse>) =>
        setState((state) => ({ ...state, request }));
    const setEndpoint = (endpoint: string) => setState({ ...state, endpoint });
    const setFile = (file: File) => setState((state) => ({ ...state, file }));
    const setProgress = (progress: number) =>
        setState((state) => ({ ...state, progress }));
    const setStatus = (status?: UploadStatus) => {
        setState((state) => ({ ...state, status }));
    };
    const [response, setResponse] = useState<ClientResponse>();
    const [responseSuccessVisible, setResponseSuccessVisible] = useState(false);
    const [error, setError] = useState<ClientResponseError>();
    const [responseErrorVisible, setResponseErrorVisible] = useState(false);

    const setStateFromResponse = (response: ClientResponse) => {
        if (response.ok) {
            resetState();
        } else {
            setState((state) => ({
                ...state,
                request: undefined,
                progress: state.progress === 1 ? 0 : state.progress,
                status: undefined,
            }));
        }
    };

    useEffect(() => {
        if (multipart) {
            setEndpoint("/api/files/multipart");
        }
    }, [multipart]);

    const resetState = () =>
        setState((state) => ({
            ...state,
            request: undefined,
            file: undefined,
            progress: 0,
            status: undefined,
        }));

    const upload = async () => {
        setStatus(UploadStatus.UPLOADING);
        setRequest(undefined);

        const reqOptions: UploadRequestOptions = {};

        if (multipart) {
            // Multipart should always send the file key
            reqOptions["multipart"] = {
                fileKey: multipartFileKey,
            };

            // If there is additional data, add it
            if (Object.keys(multipartData).length) {
                reqOptions["multipart"]["data"] = multipartData;
            }
        }

        // Add the following if they're not the defaults
        if (skipBytes > 0) reqOptions["skipBytes"] = skipBytes;
        if (methodIndex > 0) reqOptions["method"] = methods[methodIndex];

        const request = client.upload(
            state.endpoint,
            state.file!.uri!,
            reqOptions
        );
        setRequest(request);

        request.progress!((fractionCompleted: number) => {
            setProgress(fractionCompleted);
        })
            .then((response: ClientResponse) => {
                setStateFromResponse(response);
                setResponse(response);
                setError(undefined);
                setResponseSuccessVisible(true);
                setResponseErrorVisible(false);
            })
            .catch((error: ClientResponseError) => {
                setStatus(UploadStatus.FAILED);
                setResponse(undefined);
                setError(error);
                setResponseSuccessVisible(false);
                setResponseErrorVisible(true);
            });
    };

    const cancelUpload = () => {
        if (state.request) {
            state.request.cancel!();
        }
    };

    return (
        <SafeAreaView style={{ flex: 1 }}>
            <ScrollView testID="api_client_upload.scroll_view">
                <Input
                    label="Endpoint"
                    placeholder="/upload"
                    value={state.endpoint}
                    onChangeText={setEndpoint}
                    autoCapitalize="none"
                    testID="api_client_upload.endpoint.input"
                />
                <ButtonGroup
                    onPress={setMethodIndex}
                    selectedIndex={methodIndex}
                    buttons={methods}
                    containerStyle={{ flex: 1 }}
                />
                <FilePickerButtonGroup
                    onFilePicked={setFile}
                    disabled={Boolean(state.status)}
                />
                <CheckBox
                    title={`Send as Multi-part? [${multipart}]`}
                    checked={multipart}
                    onPress={() =>
                        multipart ? setMultipart(false) : setMultipart(true)
                    }
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={{ flex: 1 }}
                />
                {multipart && (
                    <>
                        <Input
                            label="Multi-part file key"
                            placeholder="file"
                            value={multipartFileKey}
                            onChangeText={setMultipartFileKey}
                            autoCapitalize="none"
                            testID="api_client_upload.multipart_key.input"
                        />
                        <AddMultipart onMultipartsChanged={setMultipartData} />
                    </>
                )}
                {!multipart && (
                    <NumericInput
                        title="Skip Bytes: "
                        value={skipBytes}
                        onChange={setSkipBytes}
                        minValue={0}
                        testID="api_client_request.skip_bytes.input"
                    />
                )}

                <ProgressiveFileUpload
                    file={state.file}
                    progress={state.progress}
                />

                <ResponseSuccessOverlay
                    response={response}
                    visible={responseSuccessVisible}
                    setVisible={setResponseSuccessVisible}
                />
                <ResponseErrorOverlay
                    error={error}
                    visible={responseErrorVisible}
                    setVisible={setResponseErrorVisible}
                />

                <UploadButton
                    fileUri={state.file?.uri}
                    endpoint={state.endpoint}
                    status={state.status}
                    upload={upload}
                    cancelUpload={cancelUpload}
                    resetState={resetState}
                />
            </ScrollView>
        </SafeAreaView>
    );
}
Example #3
Source File: CreateAPIClientScreen.tsx    From react-native-network-client with Apache License 2.0 4 votes vote down vote up
export default function CreateAPIClientScreen({
    navigation,
}: CreateAPIClientScreenProps) {
    const [name, setName] = useState("");
    const [baseUrl, setBaseUrl] = useState("");
    const [clientHeaders, setClientHeaders] = useState<Header[]>([]);
    const [alertOnClientError, setAlertOnClientError] = useState(true);
    const toggleAlertOnClientError = () =>
        setAlertOnClientError((alertOnClientError) => !alertOnClientError);

    const [
        sessionConfiguration,
        toggleAllowsCellularAccess,
        toggleWaitsForConnectivity,
        toggleCancelRequestsOnUnauthorized,
        toggleTrustSelfSignedServerCertificate,
        setTimeoutIntervalForRequest,
        setTimeoutIntervalForResource,
        setHttpMaximumConnectionsPerHost,
    ] = useSessionConfiguration();

    const [
        retryPolicyConfiguration,
        setRetryPolicyType,
        setRetryLimit,
        setRetryInterval,
        setExponentialBackoffBase,
        setExponentialBackoffScale,
        setStatusCodes,
        setRetryMethods,
    ] = useRetryPolicyConfiguration();

    const [
        clientP12Configuration,
        setClientP12Path,
        setClientP12Password,
    ] = useClientP12Configuration();

    const [
        requestAdapterConfiguration,
        setRequestAdapterConfiguration,
    ] = useState<RequestAdapterConfiguration>({
        bearerAuthTokenResponseHeader: "",
    });

    const setBearerAuthTokenResponseHeader = (
        bearerAuthTokenResponseHeader: string
    ) =>
        setRequestAdapterConfiguration({
            ...requestAdapterConfiguration,
            bearerAuthTokenResponseHeader,
        });

    const createClient = async () => {
        const headers = parseHeaders(clientHeaders);
        const options: APIClientConfiguration = {
            headers,
            sessionConfiguration,
            retryPolicyConfiguration,
            requestAdapterConfiguration,
        };

        if (clientP12Configuration.path && clientP12Configuration.path !== "") {
            options["clientP12Configuration"] = clientP12Configuration;
        }

        const clientErrorEventHandler = alertOnClientError
            ? apiClientErrorEventHandler
            : undefined;

        const { client, created } = await getOrCreateAPIClient(
            baseUrl,
            options,
            clientErrorEventHandler
        );
        if (!created) {
            Alert.alert(
                "Error",
                `A client for ${baseUrl} already exists`,
                [{ text: "OK" }],
                { cancelable: false }
            );
            return;
        }
        const createdClient: APIClientItem = {
            name,
            client,
            type: ClientType.API,
        };

        navigation.navigate("ClientList", { createdClient });
    };

    return (
        <SafeAreaView>
            <ScrollView testID="create_api_client.scroll_view">
                <Input
                    label="Name"
                    onChangeText={setName}
                    autoCorrect={false}
                    testID="create_api_client.name.input"
                />
                <Input
                    label="Base URL"
                    onChangeText={setBaseUrl}
                    autoCapitalize="none"
                    autoCorrect={false}
                    testID="create_api_client.base_url.input"
                />

                <AddHeaders onHeadersChanged={setClientHeaders} />

                <Input
                    label="Bearer Auth Token Response Header"
                    onChangeText={setBearerAuthTokenResponseHeader}
                    placeholder="token"
                    autoCapitalize="none"
                    value=""
                    testID="create_api_client.bearer_auth_token.input"
                />

                <P12Inputs
                    title="Client PKCS12"
                    path={clientP12Configuration.path}
                    password={clientP12Configuration.password}
                    onSelectP12={setClientP12Path}
                    onPasswordChange={setClientP12Password}
                />

                <NumericInput
                    title="Request Timeout Interval (ms)"
                    value={sessionConfiguration.timeoutIntervalForRequest}
                    onChange={setTimeoutIntervalForRequest}
                    minValue={0}
                    step={5000}
                    testID="create_api_client.request_timeout_interval.input"
                />

                <NumericInput
                    title="Resource Timeout Interval (ms)"
                    value={sessionConfiguration.timeoutIntervalForResource}
                    onChange={setTimeoutIntervalForResource}
                    minValue={0}
                    step={5000}
                    testID="create_api_client.resource_timeout_interval.input"
                />

                <NumericInput
                    title="Max Connections"
                    value={sessionConfiguration.httpMaximumConnectionsPerHost}
                    onChange={setHttpMaximumConnectionsPerHost}
                    minValue={1}
                    testID="create_api_client.max_connections.input"
                />

                <RetryPolicyConfiguration
                    policyType={retryPolicyConfiguration.type}
                    onTypeSelected={setRetryPolicyType}
                    retryLimit={retryPolicyConfiguration.retryLimit}
                    setRetryLimit={setRetryLimit}
                    retryInterval={retryPolicyConfiguration.retryInterval}
                    setRetryInterval={setRetryInterval}
                    exponentialBackoffBase={
                        retryPolicyConfiguration.exponentialBackoffBase
                    }
                    setExponentialBackoffBase={setExponentialBackoffBase}
                    exponentialBackoffScale={
                        retryPolicyConfiguration.exponentialBackoffScale
                    }
                    setExponentialBackoffScale={setExponentialBackoffScale}
                    statusCodes={retryPolicyConfiguration.statusCodes}
                    setStatusCodes={setStatusCodes}
                    retryMethods={retryPolicyConfiguration.retryMethods}
                    setRetryMethods={setRetryMethods}
                />

                <CheckBox
                    title={`Alert on client error? [${alertOnClientError}]`}
                    checked={alertOnClientError}
                    onPress={toggleAlertOnClientError}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Allow Cellular Access? [${sessionConfiguration.allowsCellularAccess}]`}
                    checked={
                        sessionConfiguration.allowsCellularAccess as boolean
                    }
                    onPress={toggleAllowsCellularAccess}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Waits For Connectivity? [${sessionConfiguration.waitsForConnectivity}]`}
                    checked={
                        sessionConfiguration.waitsForConnectivity as boolean
                    }
                    onPress={toggleWaitsForConnectivity}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Cancel Requests On 401? [${sessionConfiguration.cancelRequestsOnUnauthorized}]`}
                    checked={
                        sessionConfiguration.cancelRequestsOnUnauthorized as boolean
                    }
                    onPress={toggleCancelRequestsOnUnauthorized}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Trust Self-Signed Server Certificate? [${sessionConfiguration.trustSelfSignedServerCertificate}]`}
                    checked={
                        sessionConfiguration.trustSelfSignedServerCertificate as boolean
                    }
                    onPress={toggleTrustSelfSignedServerCertificate}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <Button
                    title="Create"
                    onPress={createClient}
                    disabled={!name || !baseUrl}
                    style={styles.createButton}
                />
            </ScrollView>
        </SafeAreaView>
    );
}
Example #4
Source File: CreateWebSocketClientScreen.tsx    From react-native-network-client with Apache License 2.0 4 votes vote down vote up
export default function CreateWebSocketClientScreen({
    navigation,
}: CreateWebSocketClientScreenProps) {
    const [name, setName] = useState("");
    const [url, setUrl] = useState("");
    const [alertOnClientError, setAlertOnClientError] = useState(true);
    const toggleAlertOnClientError = () =>
        setAlertOnClientError((alertOnClientError) => !alertOnClientError);

    const [
        configuration,
        setConfiguration,
    ] = useState<WebSocketClientConfiguration>({
        timeoutInterval: 5000,
        enableCompression: false,
        trustSelfSignedServerCertificate: false,
    });
    const [
        clientP12Configuration,
        setClientP12Path,
        setClientP12Password,
    ] = useClientP12Configuration();

    const setHeaders = (headers: Header[]) => {
        setConfiguration((configuration) => ({
            ...configuration,
            headers: parseHeaders(headers),
        }));
    };

    const setTimeoutInterval = (timeoutInterval: number) => {
        setConfiguration((configuration) => ({
            ...configuration,
            timeoutInterval,
        }));
    };

    const toggleEnableCompression = () => {
        setConfiguration((configuration) => ({
            ...configuration,
            enableCompression: !configuration.enableCompression,
        }));
    };

    const toggleTrustSelfSignedServerCertificate = () => {
        setConfiguration((configuration) => ({
            ...configuration,
            trustSelfSignedServerCertificate: !configuration.trustSelfSignedServerCertificate,
        }));
    };

    const createClient = async () => {
        const wsConfiguration = {
            ...configuration,
        };
        if (clientP12Configuration.path) {
            wsConfiguration["clientP12Configuration"] = clientP12Configuration;
        }

        const clientErrorEventHandler = alertOnClientError
            ? webSocketClientErrorEventHandler
            : undefined;

        try {
            const { client, created } = await getOrCreateWebSocketClient(
                url,
                wsConfiguration,
                clientErrorEventHandler
            );

            if (!created) {
                Alert.alert(
                    "Error",
                    `A client for ${url} already exists`,
                    [{ text: "OK" }],
                    { cancelable: false }
                );
                return;
            }
            const createdClient: WebSocketClientItem = {
                name,
                client,
                type: ClientType.WEBSOCKET,
            };

            navigation.navigate("ClientList", { createdClient });
        } catch (e) {
            const error = e as Error;
            Alert.alert("Error", error.message, [{ text: "OK" }], {
                cancelable: false,
            });
        }
    };

    return (
        <SafeAreaView>
            <ScrollView testID="create_websocket_client.scroll_view">
                <Input
                    label="Name"
                    onChangeText={setName}
                    testID="create_websocket_client.name.input"
                />
                <Input
                    label="URL"
                    onChangeText={setUrl}
                    autoCapitalize="none"
                    testID="create_websocket_client.url.input"
                />

                <AddHeaders onHeadersChanged={setHeaders} />

                <P12Inputs
                    title="Client PKCS12"
                    path={clientP12Configuration.path}
                    password={clientP12Configuration.password}
                    onSelectP12={setClientP12Path}
                    onPasswordChange={setClientP12Password}
                />

                <NumericInput
                    title="Timeout Interval (ms)"
                    value={configuration.timeoutInterval}
                    onChange={setTimeoutInterval}
                    minValue={0}
                    step={5000}
                    testID="create_websocket_client.timeout_interval.input"
                />

                <CheckBox
                    title={`Alert on client error? [${alertOnClientError}]`}
                    checked={alertOnClientError}
                    onPress={toggleAlertOnClientError}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Enable Compression? [${configuration.enableCompression!}]`}
                    checked={configuration.enableCompression!}
                    onPress={toggleEnableCompression}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <CheckBox
                    title={`Trust Self-Signed Server Certificate? [${configuration.trustSelfSignedServerCertificate}]`}
                    checked={
                        configuration.trustSelfSignedServerCertificate as boolean
                    }
                    onPress={toggleTrustSelfSignedServerCertificate}
                    iconType="ionicon"
                    checkedIcon="ios-checkmark-circle"
                    uncheckedIcon="ios-checkmark-circle"
                    iconRight
                    textStyle={styles.checkboxText}
                />

                <Button
                    title="Create"
                    onPress={createClient}
                    disabled={!name || !url}
                    style={styles.createButton}
                />
            </ScrollView>
        </SafeAreaView>
    );
}
Example #5
Source File: FoodList.tsx    From save-food with MIT License 4 votes vote down vote up
FoodList = ({ navigation }: Props) => {
	const moveButton = useRef(new Animated.Value(100)).current

	const { useSubscribe } = useSettingsContext()
	const settings = useSubscribe((s) => s.settings)
	const translations = useSubscribe((s) => ({
		...s.translations.FoodList,
		...s.translations.common,
	}))

	const [list, setList] = useState<WastedFood[]>()
	const [amount, setAmount] = useState(0)
	const [visibleData, setVisibleData] = useState(8)
	const [loading, setLoading] = useState(true)
	const [wait, setWait] = useState(false)
	const [selectedId, setSelectedId] = useState<number>()
	const [showModal, setShowModal] = useState(false)

	const initWastedList = async (showMessage = false) => {
		const wastedFoods = await fetchWastedFood()
		const list = wastedFoods.map((food) => {
			let resize: ResizeMode = 'cover'

			if (food.image) {
				getResizeMode(food.image, (resizeMode) => {
					resize = resizeMode
				})
			}

			return {
				...food,
				resizeMode: resize,
			}
		})

		setList(list)
		setAmount(getAmount(list))
		setLoading(false)
		setWait(false)

		if (showMessage) showSuccessMessage()
	}

	const checkFood = async () => {
		const ids = navigation.getParam('ids', undefined)
		if (ids) {
			setLoading(true)

			await Promise.all(
				ids.map(async (id: number) => {
					await paidFood(id)
					await Promise.resolve()
				}),
			)

			await initWastedList(true)
		} else {
			await initWastedList()
		}
	}

	const showSuccessMessage = () => {
		const message: MessageOptions = {
			message: translations.paymentSuccessTitle,
			type: 'success',
			icon: { icon: 'success', position: 'left' },
			duration: 2500,
		}

		showMessage(message)
	}

	const getAmount = (list: WastedFood[]): number =>
		+list
			.filter((item) => !!item.selected)
			.reduce((a, i) => a + i.price * i.productQuantity, 0)
			.toFixed(2)

	const hideButton = () => {
		Animated.timing(moveButton, {
			toValue: 100,
			duration: 250,
			useNativeDriver: true,
		}).start()
	}

	const showButton = () => {
		Animated.timing(moveButton, {
			toValue: -25,
			duration: 250,
			useNativeDriver: true,
		}).start()
	}

	const selectItem = async (item: WastedFood) => {
		if (!wait) {
			setWait(true)
			if (item.selected) {
				await selectFood(item.id, 0)
			} else {
				await selectFood(item.id, 1)
			}

			await initWastedList()
		}
	}

	const removeItemHandler = async (id: number) => {
		await removeFood(id)
		await initWastedList()
		toggleModal()
	}

	const addFoodQuantity = async (item: WastedFood, value: number) => {
		const newQuantity = +item.productQuantity + value
		if (!wait && newQuantity < 100 && newQuantity > 0) {
			setWait(true)
			await saveFood({ ...item, productQuantity: newQuantity })
			await initWastedList()
		}
	}

	const loadNextData = () => {
		if (list && visibleData < list.length) {
			setVisibleData(visibleData + 8)
		}
	}

	const toggleModal = (id?: number) => {
		if (id) setSelectedId(id)
		setShowModal(!showModal)
	}

	const goToPayment = () => {
		navigation.navigate('Payment', {
			ids: list?.filter((item) => !!item.selected).map((i) => i.id),
			amount,
		})
	}

	const renderItemRow = ({ item }: { item: WastedFood }) => (
		<ListItem containerStyle={[styles.listItemContainer, shadow]}>
			<ListItem.Content>
				<TouchableOpacity
					style={styles.listItem}
					onPress={() => navigation.navigate('Food', { ...item })}
				>
					<View style={styles.details}>
						<View style={styles.leftElement}>
							<Image
								style={[styles.image, { resizeMode: item.resizeMode }]}
								onError={(ev) => {
									if (ev.target) {
										// @ts-ignore
										ev.target.src = '../../assets/common/dish.png'
									}
								}}
								source={getImage(item.image)}
							/>

							<View style={styles.productDetails}>
								<Text numberOfLines={2} style={styles.productName}>
									{!item.name || item.name === '' ? translations.noData : item.name}
								</Text>
								<Text numberOfLines={1} style={styles.text}>
									{translations.quantity}:{' '}
									{item.quantity
										? `${item.quantity} ${getQuantitySuffix(item.quantitySuffixIndex)}`
										: translations.noData}
								</Text>
								<Text numberOfLines={1} style={styles.text}>
									{translations.percent}: {item.percentage}%
								</Text>
							</View>
						</View>

						<View style={styles.rightElement}>
							<Icon
								size={22}
								style={styles.quantityAddIcon}
								name='add'
								type='material'
								color={blackColor}
								onPress={() => addFoodQuantity(item, 1)}
							/>
							<Icon
								size={22}
								style={styles.quantityMinusIcon}
								name='minus'
								type='entypo'
								color={blackColor}
								onPress={() => addFoodQuantity(item, -1)}
							/>
						</View>
					</View>

					<View style={styles.itemListFooter}>
						<TouchableOpacity onPress={() => selectItem(item)} style={styles.priceContainer}>
							<CheckBox
								checked={!!item.selected}
								onPress={() => selectItem(item)}
								containerStyle={styles.checkbox}
								checkedColor={primaryColor}
							/>
							<View style={styles.priceWrapper}>
								<Text style={styles.priceText}>
									{(item.price * item.productQuantity).toFixed(2)} {settings.currency}
								</Text>
								{item.productQuantity > 1 && (
									<Text style={styles.quantityText}>
										({item.price} {settings.currency} x{item.productQuantity})
									</Text>
								)}
							</View>
						</TouchableOpacity>
						<Icon
							size={22}
							onPress={() => toggleModal(item.id)}
							style={styles.deleteProductIcon}
							color={redColor}
							name='trash'
							type='font-awesome-5'
						/>
					</View>
				</TouchableOpacity>
			</ListItem.Content>
		</ListItem>
	)

	useAsyncEffect(async () => {
		await checkFood()
	}, [navigation])

	useEffect(() => {
		if (list?.some((item) => !!item.selected)) {
			showButton()
		} else {
			hideButton()
		}
	}, [list])

	useAsyncEffect(async () => {
		await initWastedList()
	}, [])

	if (!list) {
		return <Spinner size={64} />
	}

	return (
		<Background>
			<Header
				leftComponent={<Icon variant='backIcon' onPress={() => navigation.replace('Home')} />}
				centerComponent={<Text style={styles.headerTitle}>{translations.foodList}</Text>}
				rightComponent={
					<Icon
						style={styles.openScannerIcon}
						name='plus'
						type='antdesign'
						onPress={() => navigation.navigate('Scanner')}
					/>
				}
				centerSize={6}
			/>

			<Modal
				visible={showModal}
				toggleModal={toggleModal}
				title={translations.deleteProduct}
				buttons={[
					{ text: translations.yes, onPress: () => selectedId && removeItemHandler(selectedId) },
					{ text: translations.cancel, onPress: toggleModal },
				]}
			>
				<Text style={styles.deleteProductDescription}>{translations.deleteProductDescription}</Text>
			</Modal>

			<View style={styles.container}>
				<FlatList
					keyboardShouldPersistTaps='always'
					keyboardDismissMode='interactive'
					scrollEventThrottle={16}
					refreshControl={
						<RefreshControl refreshing={loading} tintColor='#fff' onRefresh={initWastedList} />
					}
					ListEmptyComponent={<EmptyList navigation={navigation} />}
					data={list}
					initialNumToRender={8}
					onEndReachedThreshold={0.2}
					onEndReached={loadNextData}
					renderItem={renderItemRow}
					keyExtractor={(item) => `${item.id}`}
					onRefresh={initWastedList}
					refreshing={loading}
					ListFooterComponent={
						list.length > visibleData ? (
							<Spinner bgColor='transparency' />
						) : (
							<View style={styles.listFooter} />
						)
					}
				/>
			</View>

			<Animated.View
				style={[{ transform: [{ translateY: moveButton }] }, styles.paymentButtonContainer, shadow]}
			>
				<View style={styles.paymentButtonWrapper}>
					<Button
						buttonStyle={styles.paymentButton}
						titleStyle={styles.paymentButtonTitle}
						onPress={goToPayment}
						disabled={amount === 0}
						title={`${translations.donate} ${getPrice(amount)} ${settings.currency}`}
					/>
				</View>
			</Animated.View>
		</Background>
	)
}