Skip to content

Commit

Permalink
feat: add CashDrawer module (#7)
Browse files Browse the repository at this point in the history
This PR adds support for the
[CashDrawer](https://learn.microsoft.com/en-us/uwp/api/windows.devices.pointofservice.cashdrawer?view=winrt-22621)
class in the
[Windows.Devices.PointOfService](https://learn.microsoft.com/en-us/uwp/api/windows.devices.pointofservice?view=winrt-22621)
namespace.

It also adds a hook and an example to the example app.
  • Loading branch information
joshuayoes authored Mar 12, 2024
2 parents b39100f + 5d3ef69 commit 0a56203
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
3 changes: 3 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import { StyleSheet, View, Text, SectionList } from 'react-native';
import {
useBarcodeScanner,
useCashDrawer,
useDeviceInformation,
usePosPrinter,
} from 'react-native-pos-tools';
Expand All @@ -26,13 +27,15 @@ export default function App() {
const posPrinter = usePosPrinter();
const deviceInformation = useDeviceInformation();
const barcodeScanner = useBarcodeScanner();
const cashDrawer = useCashDrawer();

return (
<View style={styles.container}>
<SectionList<SectionProps>
sections={[
{ title: 'POS Printer', data: [posPrinter] },
{ title: 'Barcode Scanner', data: [barcodeScanner] },
{ title: 'Cash Drawer', data: [cashDrawer] },
{ title: 'Device Information', data: [deviceInformation] },
]}
renderItem={({ item }) => <Section {...item} />}
Expand Down
21 changes: 21 additions & 0 deletions src/NativeCashDrawer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport';
import { TurboModuleRegistry } from 'react-native';

export interface CashDrawerSpec extends TurboModule {
/**
* Returns the first available cash drawer.
* @throws {Error} A device is not found.
* @see https://learn.microsoft.com/en-us/uwp/api/windows.devices.pointofservice.cashdrawer.getdefaultasync?view=winrt-22621#windows-devices-pointofservice-cashdrawer-getdefaultasync
*/
getDefaultAsync(): Promise<ReactCashDrawer>;
}

export default TurboModuleRegistry.get<CashDrawerSpec>(
'CashDrawer'
) as CashDrawerSpec | null;

/** @link windows/ReactNativePosTools/NativeCashDrawer.cs */
export interface ReactCashDrawer {
/** @see https://learn.microsoft.com/en-us/uwp/api/windows.devices.pointofservice.cashdrawer.deviceid?view=winrt-22621 */
DeviceId: string;
}
40 changes: 40 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import NativeDeviceInformation from './NativeDeviceInformation';
import NativeBarcodeScanner, {
type ReactBarcodeScanner,
} from './NativeBarcodeScanner';
import NativeCashDrawer, { type ReactCashDrawer } from './NativeCashDrawer';

class MethodUndefinedError extends Error {
constructor({
Expand Down Expand Up @@ -153,3 +154,42 @@ export const useBarcodeScanner = () => {
loading,
};
};

export const cashDrawer = {
getDefaultAsync: async () => {
if (NativeCashDrawer?.getDefaultAsync === undefined) {
throw new MethodUndefinedError({
moduleName: 'CashDrawer',
methodName: 'getDefaultAsync',
});
}

return NativeCashDrawer.getDefaultAsync();
},
};

export const useCashDrawer = () => {
const [data, setData] = React.useState<ReactCashDrawer | undefined>();
const [error, setError] = React.useState<Error | undefined>();
const [loading, setLoading] = React.useState<boolean>(true);

React.useEffect(() => {
cashDrawer
.getDefaultAsync()
.then((drawer) => {
setData(drawer);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setLoading(false);
});
}, []);

return {
data,
error,
loading,
};
};
53 changes: 53 additions & 0 deletions windows/ReactNativePosTools/NativeCashDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.ReactNative.Managed;

using Windows.Devices.PointOfService;

namespace ReactNativePosTools
{
// This is the structure that will be returned to the JavaScript side
// src/NativeCashDrawer.ts

struct ReactCashDrawer
{
public string DeviceId { get; set; }

public ReactCashDrawer(string deviceId)
{
DeviceId = deviceId;
}
};

[ReactModule("CashDrawer")]
internal class NativeCashDrawer
{

private CashDrawer drawer = null;

[ReactMethod("getDefaultAsync")]
public async void GetDefaultAsync(ReactPromise<ReactCashDrawer> result)
{
try
{
drawer = await CashDrawer.GetDefaultAsync();
if (drawer == null)
{
result.Reject(new ReactError { Message = "Cash Drawer was not found" });
}
else
{
result.Resolve(new ReactCashDrawer { DeviceId = drawer.DeviceId });
}
}
catch (Exception ex)
{
result.Reject(new ReactError { Message = ex.Message });
}
}
}
}
1 change: 1 addition & 0 deletions windows/ReactNativePosTools/ReactNativePosTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="NativeBarcodeScanner.cs" />
<Compile Include="NativeCashDrawer.cs" />
<Compile Include="NativeDeviceInformation.cs" />
<Compile Include="NativePosPrinter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down

0 comments on commit 0a56203

Please sign in to comment.