Skip to content

Commit

Permalink
feat: Simplify Barcode component state. Introduce "actions queue"
Browse files Browse the repository at this point in the history
behavior
  • Loading branch information
r0xsh committed Nov 21, 2024
1 parent bf939ea commit 3315760
Showing 1 changed file with 74 additions and 40 deletions.
114 changes: 74 additions & 40 deletions src/navigation/courier/barcode/Barcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
StyleSheet,
Text,
View,
Vibration,
Alert,
} from 'react-native';
import { Button, IconButton, TextArea, FormControl, Icon } from 'native-base';
Expand Down Expand Up @@ -59,13 +58,12 @@ function TextSection({ title, value, variant = 'data' }) {
);
}

function BarcodePage({ t, httpClient, navigation, route, taskLists }) {
function BarcodePage({ t, httpClient, navigation, _route, taskLists }) {
const [barcode, setBarcode] = useState(null);
const [entity, setEntity] = useState(null);
const [clientAction, setClientAction] = useState(null);
const [clientActionsQueue, setClientActionsQueue] = useState([]);
const [showNoteModal, setShowNoteModal] = useState(false);
const [noteLoading, setNoteLoading] = useState(false);
const [disableScan, setDisableScan] = useState(false);

const note = useRef(null);

Expand All @@ -78,14 +76,14 @@ function BarcodePage({ t, httpClient, navigation, route, taskLists }) {
{
text: 'Unassign',
onPress: () => {
_unassignTask(httpClient, entity.id).then(resolve).catch(reject);
_unassignTask(httpClient, entity.id)
.then(resolve)
.catch(reject);
},
},
{
text: 'Ok',
onPress: () => {
resolve();
},
onPress: resolve,
},
],
);
Expand All @@ -100,62 +98,92 @@ function BarcodePage({ t, httpClient, navigation, route, taskLists }) {
{
text: 'Assign to me',
onPress: () => {
_assignTask(httpClient, entity.id).then(resolve).catch(reject);
_assignTask(httpClient, entity.id)
.then(resolve)
.catch(reject);
},
},
{
text: 'Ok',
onPress: () => {
resolve();
},
onPress: resolve,
},
],
);
});

const warningMultiplePackages = ({ count, details }) =>
new Promise((resolve, _reject) => {
Alert.alert(
t('TASK_MULTIPLE_PACKAGES'),
`${t('X_PACKAGES', { count })}:\n\n${details}\n\n${t('NO_NEED_TO_SCAN_OTHERS')}`,
[{ text: t('OK'), onPress: resolve }],
);
});

const checkMultiplePackages = packages => {
if (!packages) return;
const count = packages.reduce((acc, p) => acc + p.barcodes.length, 0);
if (count > 1) {
const details = packages
.map(p => `${p.barcodes.length}x ${p.name}`)
.join('\n');
setDisableScan(true);
Alert.alert(
t('TASK_MULTIPLE_PACKAGES'),
`${t('X_PACKAGES', { count })}:\n\n${details}\n\n${t('NO_NEED_TO_SCAN_OTHERS')}`,
[{ text: t('OK'), onPress: () => setDisableScan(false) }],
);
return {
action: 'warn_multiple_packages',
fn: () => warningMultiplePackages({ count, details }),
};
}
return;
};

useEffect(() => {
async function checkClientAction() {
if (!clientAction || !entity) return;
switch (clientAction) {
case 'ask_to_unassign':
await askToUnassign();
break;
case 'ask_to_assign':
await askToAssign();
break;
case 'ask_to_complete':
async function* actionGenerator(actions) {
for (const action of actions) {
yield action;
}
}

async function checkClientAction({ action, ...params }) {
if (!entity) return;

switch (action) {
case 'ask_to_unassign':
return await askToUnassign();
case 'ask_to_assign':
return await askToAssign();
case 'ask_to_complete':
return await new Promise((resolve, _reject) => {
navigateToTask(
navigation,
null,
taskLists.find(t => t['@id'] === `/api/tasks/${entity.id}`),
);
break;
}
setClientAction(null);
resolve();
});
case 'warn_multiple_packages':
return await params.fn();
default:
return;
}
checkClientAction();
}, [clientAction]);
}

useEffect(() => {
if (!entity) return;
checkMultiplePackages(entity?.barcodes?.packages);
}, [entity]);
async function processActions() {
if (clientActionsQueue.length === 0) return;

const generator = actionGenerator(clientActionsQueue);

try {
for await (const action of generator) {
await checkClientAction(action);
}
} catch (error) {
console.error('Error processing actions:', error);
} finally {
setClientActionsQueue([]);
}
}

processActions();
}, [clientActionsQueue]);

Check failure on line 186 in src/navigation/courier/barcode/Barcode.js

View workflow job for this annotation

GitHub Actions / Basic tests

React Hook useEffect has a missing dependency: 'checkClientAction'. Either include it or remove the dependency array

return (
<>
Expand Down Expand Up @@ -184,16 +212,22 @@ function BarcodePage({ t, httpClient, navigation, route, taskLists }) {
</BottomModal>
<View style={{ flex: 1 }}>
<BarcodeCameraView
disabled={disableScan || showNoteModal || clientAction !== null}
disabled={showNoteModal || clientActionsQueue.length > 0}
onScanned={async code => {
if (clientAction) return;
if (clientActionsQueue.length > 0) return;
const { entity, client_action } = await _fetchBarcode(
httpClient,
code,
);
setBarcode(code);
setEntity(entity);
setClientAction(client_action);

const action = checkMultiplePackages(entity?.barcodes?.packages);
setClientActionsQueue([
...clientActionsQueue,
{ action: client_action },
action,
]);
}}
/>
<ScrollView
Expand Down

0 comments on commit 3315760

Please sign in to comment.