-
Notifications
You must be signed in to change notification settings - Fork 86
Description
Description
Project Version Informations
System:
OS: macOS 15.4.1
CPU: (8) arm64 Apple M2
Memory: 467.77 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 20.13.1
path: ~/.nvm/versions/node/v20.13.1/bin/node
Yarn:
version: 3.6.4
path: /opt/homebrew/bin/yarn
npm:
version: 10.8.3
path: ~/.nvm/versions/node/v20.13.1/bin/npm
Watchman:
version: 2025.06.30.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.14.3
path: /Users/ashokdudhat/.rvm/gems/ruby-3.1.0/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.4
- iOS 18.4
- macOS 15.4
- tvOS 18.4
- visionOS 2.4
- watchOS 11.4
Android SDK: Not Found
IDEs:
Android Studio: 2024.3 AI-243.25659.59.2432.13423653
Xcode:
version: 16.3/16E140
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.16
path: /opt/homebrew/opt/openjdk@17/bin/javac
Ruby:
version: 3.1.0
path: /Users/ashokdudhat/.rvm/rubies/ruby-3.1.0/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 15.0.1
wanted: 15.0.1
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.78.2
wanted: 0.78.2
react-native-macos: Not Found
npmGlobalPackages:
"react-native": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: true
Code:-
import {
Keyboard,
FlatList,
StyleSheet,
View,
TouchableOpacity,
ActivityIndicator,
} from "react-native";
import React, { useEffect, useRef, useState } from "react";
import { useNavigation, useRoute } from "@react-navigation/native";
import {
usePrintersDiscovery,
Printer,
PrinterConstants,
} from "react-native-esc-pos-printer";
import Print from "../../../assets/svg/print";
import LeftArrow from "../../../assets/svg/leftArrow";
import _styles from "./style";
import {
Header,
Input,
Layout,
EmptyList,
Text,
useToast,
Button,
} from "../../../components";
import MenuImg from "../../../assets/svg/menuImg";
import { useTheme } from "../../../utils/Theming";
import { getHeight, moderateScale } from "../../../utils/Constant";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import {
setCurrentPrinter,
setNoOfReceipts,
} from "../../../redux/actions/appAction";
import CheckMark from "../../../assets/svg/checkMark";
import { hasWritePermission } from "../../../utils/Helper";
const PrinterSetting = ({ route }) => {
const { start, stop, isDiscovering, printers } = usePrintersDiscovery();
const theme = useTheme();
const styles = _styles(theme);
const comingFrom = route?.params?.comingFrom;
const navigation = useNavigation();
const { t } = useTranslation();
const dispatch = useDispatch();
const numberOfReciepts = useSelector((state) => state.app.noOfReceipts);
const [noOfPrint, setNoOfPrint] = React.useState(numberOfReciepts.toString());
const isprintRef = useRef(null);
useEffect(() => {
start();
return () => stop(); // Stop discovery when component unmounts
}, []);
useEffect(() => {
setNoOfPrint(numberOfReciepts.toString());
}, [numberOfReciepts]);
const handleSearchPress = () => {
if (!isDiscovering) {
start();
}
};
const RenderItem = ({ item, index }) => {
return <RenderPrinter item={item} />;
};
const handleNumberofPrintKey = (value) => {
setNoOfPrint(value);
if (value) {
if (!/^\d+$/.test(value)) {
toast?.showToast({
type: "error",
title: null,
subtitle: t("number_validation"),
duration: 3000,
noIcon: true,
});
} else {
const num = Number(value); // Convert to number
// Check if in range 0-5
if (num >= 0 && num <= 5) {
} else {
toast?.showToast({
type: "error",
title: null,
subtitle: t("0_to_5_raneg_validation"),
duration: 3000,
noIcon: true,
});
}
}
}
};
const onPressSave = () => {
if (!hasWritePermission(t)) {
toast?.showToast({
type: "error",
title: t("permission_error"),
subtitle: null,
duration: 1000,
noIcon: true,
});
return;
}
if (noOfPrint) {
if (!/^\d+$/.test(noOfPrint)) {
toast?.showToast({
type: "error",
title: null,
subtitle: t("number_validation"),
duration: 3000,
noIcon: true,
});
} else {
const num = Number(noOfPrint); // Convert to number
// Check if in range 0-5
if (num >= 0 && num <= 5) {
dispatch(setNoOfReceipts(num));
toast?.showToast({
type: "success",
title: null,
subtitle: t("no_of_receipts_update_success"),
duration: 3000,
noIcon: true,
});
} else {
toast?.showToast({
type: "error",
title: null,
subtitle: t("0_to_5_raneg_validation"),
duration: 3000,
noIcon: true,
});
}
}
}
};
return (
<Layout>
<Header
leftIcon={
comingFrom == "sideDrawer" ? (
<MenuImg
width={moderateScale(24)}
height={moderateScale(24)}
color={styles.headerIconColor}
/>
) : (
<LeftArrow
width={moderateScale(24)}
height={moderateScale(24)}
color={styles.headerIconColor}
/>
)
}
leftAction={() =>
comingFrom == "sideDrawer"
? navigation.openDrawer()
: navigation.goBack()
}
title={"printer_setting"}
/>
<View style={styles.container}>
<View style={styles.receiptSettings}>
<Text type="M16" style={{ marginTop: moderateScale(5) }}>
{t("no_of_receipts")}
</Text>
<View style={{ flexDirection: "row", gap: moderateScale(15) }}>
<Input
placeholder={t("enter_number")}
value={noOfPrint}
onChange={handleNumberofPrintKey}
keyboardType={"number-pad"}
spellCheck={false}
returnKeyType="done"
onSubmitEditing={Keyboard.dismiss}
ref={isprintRef}
style={{ flex: 1 }}
/>
<Button
title={"save"}
style={{
flex: 1,
marginTop: 0,
marginVertical: 0,
alignSelf: "center",
flexGrow: 1,
height: getHeight(58),
}}
onPress={onPressSave}
/>
</View>
</View>
<View style={styles.printerConnection}>
<Text type="M16" style={{ marginVertical: moderateScale(5) }}>
{t("printer_connection")}
</Text>
<TouchableOpacity
disabled={isDiscovering}
onPress={handleSearchPress}
style={styles.btnStyle}
>
<Text style={styles.btnTextStyle} type="M14">
{isDiscovering
? t("searching_nearby_printer")
: t("search_nearby_printer")}
</Text>
</TouchableOpacity>
{!isDiscovering ? (
printers.length > 0 ? (
<FlatList
ListHeaderComponent={RenderHeaderComponent}
keyExtractor={(item, index) => index.toString()}
data={printers}
renderItem={RenderItem}
/>
) : (
<EmptyList
text={"no_printers_available"}
Icon={Print}
style={{ marginVertical: moderateScale(150) }}
/>
)
) : (
<View style={{ justifyContent: "center", flex: 1 }}>
<ActivityIndicator
color={theme["color-primary-500"]}
size={"large"}
/>
</View>
)}
</View>
</View>
</Layout>
);
};
export default PrinterSetting;
const RenderPrinter = ({ item }) => {
const theme = useTheme();
const styles = _styles(theme);
const { t } = useTranslation();
const dispatch = useDispatch();
const toast = useToast();
const currentPrinter = useSelector((state) => state.app.currentPrinter);
const [printerStatus, setPrinterStatus] = useState("");
useEffect(() => {
const printerInstance = new Printer({
target: item.target,
deviceName: item.deviceName,
});
const stopMonitoring = Printer.monitorPrinter(
printerInstance,
(status) => {
if (status.online.statusCode === PrinterConstants.TRUE) {
setPrinterStatus("online");
} else {
setPrinterStatus("offline");
}
},
3000 // Monitoring interval
);
return () => stopMonitoring();
}, [item]);
const setPrinter = () => {
if (printerStatus == "online") {
dispatch(setCurrentPrinter(item));
} else {
toast?.showToast({
type: "error",
title: null,
subtitle: t("this_printer_is_offline"),
duration: 3000,
noIcon: true,
});
}
};
const Detail = ({ label, value }) => {
return (
<View style={{ flexDirection: "row", width: "80%" }}>
<Text style={styles.subTextStyle} type={"R16"}>
{t(label)}
</Text>
<Text
style={[
styles.subTextStyle,
{ marginLeft: moderateScale(5), color: styles.headerIconColor },
]}
type={"R16"}
>
{value}
</Text>
</View>
);
};
return (
<>
{item && item?.deviceName && (
<TouchableOpacity
onPress={setPrinter}
style={[
styles.printerItemStyle,
currentPrinter &&
currentPrinter?.deviceName == item?.deviceName &&
currentPrinter?.target == item?.target &&
styles.selectedPrinterStyle,
]}
>
{/* <View style={{flexDirection:'row'}}>
<Text style={styles.subTextStyle} type={'R16'}>{t('device_name')}</Text>
<Text style={styles.subTextStyle} type={'R16'}>{item?.deviceName}</Text>
</View> */}
<View style={{ width: "90%" }}>
<Detail label={"device_name"} value={item?.deviceName} />
<Detail label={"ip_address"} value={item?.ipAddress} />
<Detail label={"mac_address"} value={item?.macAddress} />
<Detail label={"target"} value={item?.target} />
<Detail label={"status"} value={printerStatus} />
</View>
<View style={{ alignSelf: "center" }}>
{currentPrinter &&
currentPrinter?.deviceName == item?.deviceName &&
currentPrinter?.target == item?.target && (
<CheckMark
width={moderateScale(24)}
height={moderateScale(24)}
color={theme["color-primary-500"]}
/>
)}
</View>
</TouchableOpacity>
)}
</>
);
};
const RenderHeaderComponent = () => {
const theme = useTheme();
const styles = _styles(theme);
const { t } = useTranslation();
return <Text type="R16">{t("available_printers")}</Text>;
};
Steps to reproduce
- The above code is One of the screen, when user come to this screen and below error shows
react-native-esc-pos-printer version
4.4.1,4.4.3,
React Native version
0.78.2
Platforms
iOS
Workflow
React Native
Architecture
Fabric (New Architecture)
Build type
Debug app & dev bundle
Device
None
Device model
ios Simulator and real devices (all)
Acknowledgements
Yes