Skip to content

Reboot #471

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

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions example/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import 'ts-node/register';
const config: ExpoConfig = {
name: "react-native-mcu-manager-example",
slug: "react-native-mcu-manager-example",
version: "1.0.0",
orientation: "portrait",
assetBundlePatterns: ["**/*"],
orientation: "portrait",
platforms: ["ios", "android"],
scheme: "rnmcumgr",
version: "1.0.0",
splash: {
image: ".assets/images/pd.png",
backgroundColor: "#FFFFFF",
Expand All @@ -27,6 +29,7 @@ const config: ExpoConfig = {
},
plugins: [
["expo-document-picker"],
["expo-router"],
["./gradlePlugin.ts"]
]
};
Expand Down
8 changes: 0 additions & 8 deletions example/index.ts

This file was deleted.

11 changes: 9 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "react-native-mcu-manager-example",
"description": "Example app for react-native-mcu-manager",
"main": "expo-router/entry",
"version": "0.0.1",
"private": true,
"license": "MIT",
"scripts": {
"android": "expo run:android",
"ios": "expo run:ios",
Expand All @@ -13,12 +14,19 @@
"dependencies": {
"@playerdata/react-native-mcu-manager": "workspace:*",
"expo": "52.0.25",
"expo-constants": "~17.0.4",
"expo-document-picker": "13.0.2",
"expo-linking": "~7.0.4",
"expo-router": "~4.0.16",
"expo-splash-screen": "0.29.20",
"expo-status-bar": "~2.0.1",
"lodash": "4.17.21",
"react": "18.3.1",
"react-native": "0.76.3",
"react-native-ble-plx": "3.4.0",
"react-native-reanimated": "~3.16.1",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
"react-native-toast-message": "2.2.1"
},
"devDependencies": {
Expand All @@ -27,7 +35,6 @@
"@types/lodash": "4.17.14",
"@types/react": "19.0.7",
"metro-react-native-babel-preset": "0.77.0",
"pod-install": "0.3.4",
"ts-node": "^10.9.2",
"typescript": "5.7.3"
}
Expand Down
15 changes: 15 additions & 0 deletions example/src/app/(home)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Stack } from 'expo-router';

const HomeLayout = () => {
return (
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
<Stack.Screen
name="select_device"
options={{ title: 'Select Device', presentation: 'modal' }}
/>
</Stack>
);
};

export default HomeLayout;
62 changes: 62 additions & 0 deletions example/src/app/(home)/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useState } from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';

import { Link } from 'expo-router';

import { resetDevice } from '@playerdata/react-native-mcu-manager';

import { useSelectedDevice } from '../../context/selectedDevice';

const styles = StyleSheet.create({
root: {
padding: 16,
},

block: {
marginBottom: 16,
},
});

const Home = () => {
const { selectedDevice } = useSelectedDevice();
const [resetState, setResetState] = useState('');

return (
<View style={styles.root}>
<View style={styles.block}>
<Text>
Select a device, then use the tabs below to choose which function to
test
</Text>
</View>

<Link asChild href="/select_device">
<Button title="Select Device" />
</Link>

<View style={styles.block}>
<Text>Selected:</Text>

{selectedDevice?.deviceId && <Text>{selectedDevice.deviceName}</Text>}
</View>

<View style={styles.block}>
<Text>{resetState}</Text>

<Button
title="Reset Device"
disabled={!selectedDevice?.deviceId}
onPress={() => {
setResetState('Resetting...');

resetDevice(selectedDevice?.deviceId || '')
.then(() => setResetState('Reset complete'))
.catch((error) => setResetState(error.message));
}}
/>
</View>
</View>
);
};

export default Home;
42 changes: 42 additions & 0 deletions example/src/app/(home)/select_device.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { Button, FlatList, StyleSheet, Text, View } from 'react-native';
import { useNavigation } from 'expo-router';

import { useSelectedDevice } from '../../context/selectedDevice';
import useBluetoothDevices from '../../hooks/useBluetoothDevices';

const styles = StyleSheet.create({
list: {
padding: 16,
},
});

const SelectDevice = () => {
const navigation = useNavigation();
const { setSelectedDevice } = useSelectedDevice();
const { devices, error: scanError } = useBluetoothDevices();

return (
<FlatList
contentContainerStyle={styles.list}
data={devices}
keyExtractor={({ id }) => id}
renderItem={({ item }) => (
<View>
<Text>{item.name || item.id}</Text>

<Button
title="Select"
onPress={() => {
setSelectedDevice({ deviceId: item.id, deviceName: item.name });
navigation.goBack();
}}
/>
</View>
)}
ListHeaderComponent={() => <Text>{scanError}</Text>}
/>
);
};

export default SelectDevice;
28 changes: 28 additions & 0 deletions example/src/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState } from 'react';
import { Tabs } from 'expo-router';
import 'react-native-reanimated';

import {
SelectedDeviceProvider,
SelectedDevice,
} from '../context/selectedDevice';

const RootLayout = () => {
const [selectedDevice, setSelectedDevice] = useState<SelectedDevice | null>(
null
);

return (
<SelectedDeviceProvider value={{ selectedDevice, setSelectedDevice }}>
<Tabs>
<Tabs.Screen
name="(home)"
options={{ title: 'Home' }}
/>
<Tabs.Screen name="update" options={{ title: 'Update' }} />
</Tabs>
</SelectedDeviceProvider>
);
};

export default RootLayout;
61 changes: 13 additions & 48 deletions example/src/App.tsx → example/src/app/update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ import {
import React, { useState } from 'react';
import {
Button,
FlatList,
Modal,
SafeAreaView,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';

import useBluetoothDevices from './useBluetoothDevices';
import useFilePicker from './useFilePicker';
import useFirmwareUpdate from './useFirmwareUpdate';
import useFilePicker from '../hooks/useFilePicker';
import useFirmwareUpdate from '../hooks/useFirmwareUpdate';
import { useSelectedDevice } from '../context/selectedDevice';

const styles = StyleSheet.create({
root: {
Expand All @@ -27,29 +25,21 @@ const styles = StyleSheet.create({
block: {
marginBottom: 16,
},

list: {
padding: 16,
},
});

export default function App() {
const [devicesListVisible, setDevicesListVisible] = useState(false);
const [selectedDeviceId, setSelectedDeviceId] = useState<string | null>(null);
const [selectedDeviceName, setSelectedDeviceName] = useState<string | null>(
null
);
const Update = () => {
const { selectedDevice } = useSelectedDevice();

const [fileType, setFileType] = useState<UpgradeFileType>(
UpgradeFileType.BIN
);
const [upgradeMode, setUpgradeMode] = useState<UpgradeMode | undefined>(
undefined
);

const { devices, error: scanError } = useBluetoothDevices();
const { selectedFile, filePickerError, pickFile } = useFilePicker();
const { cancelUpdate, runUpdate, progress, state } = useFirmwareUpdate(
selectedDeviceId,
selectedDevice?.deviceId || null,
selectedFile?.uri || null,
fileType,
upgradeMode
Expand All @@ -61,41 +51,14 @@ export default function App() {
<Text style={styles.block}>Step 1 - Select Device to Update</Text>

<View style={styles.block}>
{selectedDeviceId && (
{selectedDevice?.deviceId && (
<>
<Text>Selected:</Text>
<Text>{selectedDeviceName}</Text>
<Text>{selectedDevice.deviceName}</Text>
</>
)}
<Button
onPress={() => setDevicesListVisible(true)}
title="Select Device"
/>
</View>

<Modal visible={devicesListVisible}>
<FlatList
contentContainerStyle={styles.list}
data={devices}
keyExtractor={({ id }) => id}
renderItem={({ item }) => (
<View>
<Text>{item.name || item.id}</Text>

<Button
title="Select"
onPress={() => {
setSelectedDeviceId(item.id);
setSelectedDeviceName(item.name);
setDevicesListVisible(false);
}}
/>
</View>
)}
ListHeaderComponent={() => <Text>{scanError}</Text>}
/>
</Modal>

<Text style={styles.block}>Step 2 - Select Update File</Text>

<View style={styles.block}>
Expand Down Expand Up @@ -154,13 +117,13 @@ export default function App() {
</Text>

<Button
disabled={!selectedFile || !selectedDeviceId}
disabled={!selectedFile || !selectedDevice?.deviceId}
onPress={() => selectedFile && runUpdate()}
title="Start Update"
/>

<Button
disabled={!selectedFile || !selectedDeviceId}
disabled={!selectedFile || !selectedDevice?.deviceId}
onPress={() => cancelUpdate()}
title="Cancel Update"
/>
Expand All @@ -169,3 +132,5 @@ export default function App() {
</SafeAreaView>
);
}

export default Update;
28 changes: 28 additions & 0 deletions example/src/context/selectedDevice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createContext, useContext } from 'react';

export interface SelectedDevice {
deviceId: string;
deviceName: string | null;
}

const SelectedDeviceContext = createContext<{
selectedDevice: SelectedDevice | null;
setSelectedDevice: (device: SelectedDevice) => void;
}>({
selectedDevice: null,
setSelectedDevice: () => {},
});

export const SelectedDeviceProvider = SelectedDeviceContext.Provider;

export const useSelectedDevice = () => {
const context = useContext(SelectedDeviceContext);

if (!context) {
throw new Error(
'useSelectedDevice must be used within a SelectedDeviceProvider'
);
}

return context;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { sortBy, uniqBy } from 'lodash';
import { useEffect, useRef, useState } from 'react';
import { Device } from 'react-native-ble-plx';

import { BLEService } from './BLEService';
import { BLEService } from '../BLEService';

const useBluetoothDevices = () => {
const [bleManager] = useState(() => BLEService.manager);
Expand All @@ -15,7 +15,7 @@ const useBluetoothDevices = () => {
BLEService.initializeBLE().then(() =>
bleManager.startDeviceScan(
[],
{ allowDuplicates: false },
{ allowDuplicates: false, legacyScan: false },
(e, scannedDevice) => {
if (e) {
setError(`${e.message} - ${e.reason}`);
Expand Down
File renamed without changes.
Loading
Loading