Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The camera keeps reopening in an infinite loop on Android #65

Open
ManoelFer opened this issue Apr 17, 2024 · 0 comments
Open

The camera keeps reopening in an infinite loop on Android #65

ManoelFer opened this issue Apr 17, 2024 · 0 comments

Comments

@ManoelFer
Copy link

The camera keeps reopening in an infinite loop on Android!

I'm currently trying to use the lib with react native and expo, I did the implementation identical to the doc! On iOS everything works as expected, but on Android, the camera keeps reopening in an infinite loop.

Bug example: https://www.loom.com/share/d08fa289a1d943eaa67b550350d52e2d?sid=0564dd68-b1c8-410c-bdb4-fbf614a5e5e9

Expected Result: The camera should open smoothly without any flickering, allowing the user to scan items without disruption.

Lib version in package.json
"@veryfi/react-native-veryfi-lens": "^1.5.31"

My veryfi provider code: (Veryfi.ts)

import VeryfiLens from "@veryfi/react-native-veryfi-lens";
import { NativeEventEmitter } from "react-native";

const veryfiLensCredentials = {
  url: process.env.EXPO_PUBLIC_VERYFI_URL!,
  clientId: process.env.EXPO_PUBLIC_VERYFI_CLIENT_ID!,
  userName: process.env.EXPO_PUBLIC_VERYFI_USERNAME!,
  apiKey: process.env.EXPO_PUBLIC_VERYFI_API_KEY!,
};

const veryfiLensSettings = {
  blurDetectionIsOn: true,
  autoLightDetectionIsOn: false,
  documentTypes: ["receipt"],
  showDocumentTypes: true,
  dataExtractionEngine: "api",
};

const VeryfiLensEmitter = new NativeEventEmitter(VeryfiLens.NativeModule);

const setupListeners = (callback: (event: any) => void) => {
  VeryfiLensEmitter.removeAllListeners(VeryfiLens.Events.onVeryfiLensClose);
  VeryfiLensEmitter.removeAllListeners(VeryfiLens.Events.onVeryfiLensError);
  VeryfiLensEmitter.removeAllListeners(VeryfiLens.Events.onVeryfiLensSuccess);

  VeryfiLensEmitter.addListener(VeryfiLens.Events.onVeryfiLensClose, callback);
  VeryfiLensEmitter.addListener(VeryfiLens.Events.onVeryfiLensError, callback);
  VeryfiLensEmitter.addListener(VeryfiLens.Events.onVeryfiLensSuccess, callback);
};

export const showCamera = (callback: (event: any) => void) => {
  setupListeners(callback);

  VeryfiLens.configureWithCredentials(veryfiLensCredentials, veryfiLensSettings, () => {
    VeryfiLens.showCamera();
  });
};

How I use it:

import React from "react";

import { View } from "react-native";

import { SafeAreaView } from "react-native-safe-area-context";
import { showMessage } from "react-native-flash-message";

import { useNavigation } from "expo-router";
import { StatusBar } from "expo-status-bar";

import { Button, HeaderGoBack } from "@/shared/components";
import { showCamera } from "@/shared/providers";
import { theme } from "@/shared/styles/theme";

import { LoadingScan, ScanResult } from "@/shared/features/BottomTabs/Scan/components";
import { horizontalScale, verticalScale } from "@/shared/styles/metrics";
import { ReceiptEventPayload } from "@/shared/types/receipt";
import { useSaveReceipt } from "@/shared/hooks";

export default function Scan() {
  const navigation = useNavigation();

  const [isClosed, setIsClosed] = React.useState(false);
  const [scanPayload, setScanPayload] = React.useState<ReceiptEventPayload | null>(null);

  const { mutateAsync: saveReceipt } = useSaveReceipt();

  const onEventReceivedCallback = React.useCallback(
    async (event: ReceiptEventPayload) => {
      try {
        if (event.status === "done" && event.data) {
          await saveReceipt(event.data);

          setScanPayload(event);
          setIsClosed(true);

          return;
        }

        if (event.status === "close" && !event.queue_count) setIsClosed(true);
      } catch (error) {
        showMessage({
          message: "Something went wrong. Please try again later",
          type: "danger",
          icon: "danger",
        });
        setIsClosed(true);
      }
    },
    [saveReceipt],
  );

  React.useEffect(() => {
    const unsubscribe = navigation.addListener("focus", () => {
      showCamera(onEventReceivedCallback);
    });

    return unsubscribe;
  }, [navigation, onEventReceivedCallback]);

  React.useEffect(() => {
    const unsubscribe = navigation.addListener("blur", () => {
      setScanPayload(null);
      setIsClosed(false);
    });

    return unsubscribe;
  }, [navigation]);

  return (
    <SafeAreaView
      edges={["top", "left", "right"]}
      style={{ flex: 1, backgroundColor: theme.colors.backgroundScreen.wallet }}
    >
      <StatusBar style="dark" />
      <HeaderGoBack title="Scan receipt" />

      <View style={{ flex: 1 }}>
        {!scanPayload && !isClosed && <LoadingScan />}

        {!!scanPayload && (
          <ScanResult
            storeLogo={scanPayload?.data?.vendor?.logo ?? undefined}
            storeName={scanPayload?.data?.vendor?.name ?? "Unavailable store name"}
            price={scanPayload?.data?.total ?? 0}
            date={scanPayload?.data?.date ?? ""}
          />
        )}
      </View>

      {!!isClosed && (
        <View
          style={{
            paddingHorizontal: horizontalScale(20),
            paddingBottom: verticalScale(32),
          }}
        >
          <Button
            label={scanPayload ? "Scan another receipt" : "Launch scanner"}
            onPress={() => {
              showCamera(onEventReceivedCallback);
              setIsClosed(false);
            }}
          />
        </View>
      )}
    </SafeAreaView>
  );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant