From 2ab5909830cfa0fa86d70338bc4ad9ec0811aed9 Mon Sep 17 00:00:00 2001 From: zetavg Date: Thu, 18 Jan 2024 00:14:18 +0800 Subject: [PATCH] app: use menu to select sorting of untagged items --- App/app/consts/icons.ts | 5 +- App/app/data/hooks/useView.ts | 6 ++ .../screens/RFIDUntaggedItemsScreen.tsx | 102 ++++++++++++++---- 3 files changed, 92 insertions(+), 21 deletions(-) diff --git a/App/app/consts/icons.ts b/App/app/consts/icons.ts index fede1ce3..12e33623 100644 --- a/App/app/consts/icons.ts +++ b/App/app/consts/icons.ts @@ -18,12 +18,15 @@ export const ICON_COLORS = [ export type IconColor = (typeof ICON_COLORS)[number]; +export const MAJOR_VERSION_IOS = + Platform.OS === 'ios' ? parseInt(Platform.Version, 10) : 0; + function sfSymbolForOSVersion( sfSymbolName: string, { ios }: { ios: number }, ): string | undefined { if (Platform.OS === 'ios') { - const majorVersionIOS = parseInt(Platform.Version, 10); + const majorVersionIOS = MAJOR_VERSION_IOS; if (majorVersionIOS < ios) { return undefined; } diff --git a/App/app/data/hooks/useView.ts b/App/app/data/hooks/useView.ts index d14f9a0c..2ad511fc 100644 --- a/App/app/data/hooks/useView.ts +++ b/App/app/data/hooks/useView.ts @@ -68,10 +68,16 @@ export default function useView( } }, [db, logger, cachedOptions, viewName]); + const prevLoadData = useRef(loadData); useFocusEffect( useCallback(() => { if (cachedOptions.disable) return; + if (prevLoadData.current !== loadData) { + setLoading(true); + prevLoadData.current = loadData; + } + if (!dataRef.current) { loadData(); } else { diff --git a/App/app/features/inventory/screens/RFIDUntaggedItemsScreen.tsx b/App/app/features/inventory/screens/RFIDUntaggedItemsScreen.tsx index 61a3109d..176660ba 100644 --- a/App/app/features/inventory/screens/RFIDUntaggedItemsScreen.tsx +++ b/App/app/features/inventory/screens/RFIDUntaggedItemsScreen.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { SectionList } from 'react-native'; +import { Platform, SectionList } from 'react-native'; import { useFocusEffect } from '@react-navigation/native'; import type { StackScreenProps } from '@react-navigation/stack'; import { InvalidDataTypeWithID, ValidDataTypeWithID } from '@deps/data/types'; +import { MAJOR_VERSION_IOS } from '@app/consts/icons'; + import useView from '@app/data/hooks/useView'; import type { StackParamList } from '@app/navigation/MainStack'; @@ -17,15 +19,24 @@ import ItemListItem from '../components/ItemListItem'; function RFIDUntaggedItemsScreen({ navigation, }: StackScreenProps) { + const [sort, setSort] = useState<'updated_time' | 'created_time'>( + 'updated_time', + ); + const [order, setOrder] = useState<'asc' | 'desc'>('desc'); const { data: rfidUntaggedItemsData, loading: rfidUntaggedItemsDataLoading, refresh: refreshRfidUntaggedItems, refreshing: rfidUntaggedItemsRefreshing, - } = useView('rfid_untagged_items_by_updated_time', { - includeDocs: true, - descending: true, - }); + } = useView( + sort === 'updated_time' + ? 'rfid_untagged_items_by_updated_time' + : 'rfid_untagged_items_by_created_time', + { + includeDocs: true, + descending: order === 'desc', + }, + ); const rfidUntaggedItems = rfidUntaggedItemsData ? rfidUntaggedItemsData .map(d => d.data) @@ -37,10 +48,15 @@ function RFIDUntaggedItemsScreen({ loading: rfidTagOutdatedItemsDataLoading, refresh: refreshRfidTagOutdatedItems, refreshing: rfidTagOutdatedItemsRefreshing, - } = useView('rfid_tag_outdated_items_by_updated_time', { - includeDocs: true, - descending: true, - }); + } = useView( + sort === 'updated_time' + ? 'rfid_tag_outdated_items_by_updated_time' + : 'rfid_tag_outdated_items_by_created_time', + { + includeDocs: true, + descending: order === 'desc', + }, + ); const rfidTagOutdatedItems = rfidTagOutdatedItemsData ? rfidTagOutdatedItemsData .map(d => d.data) @@ -58,22 +74,29 @@ function RFIDUntaggedItemsScreen({ return [ { title: 'untagged', - data: rfidUntaggedItems - ? rfidUntaggedItems.length > 0 - ? rfidUntaggedItems - : (['null'] as const) - : (['loading'] as const), + data: + rfidUntaggedItems && !rfidUntaggedItemsDataLoading + ? rfidUntaggedItems.length > 0 + ? rfidUntaggedItems + : (['null'] as const) + : (['loading'] as const), }, { title: 'tag-outdated', - data: rfidTagOutdatedItems - ? rfidTagOutdatedItems.length > 0 - ? rfidTagOutdatedItems - : (['null'] as const) - : (['loading'] as const), + data: + rfidTagOutdatedItems && !rfidTagOutdatedItemsDataLoading + ? rfidTagOutdatedItems.length > 0 + ? rfidTagOutdatedItems + : (['null'] as const) + : (['loading'] as const), }, ]; - }, [rfidTagOutdatedItems, rfidUntaggedItems]); + }, [ + rfidTagOutdatedItems, + rfidTagOutdatedItemsDataLoading, + rfidUntaggedItems, + rfidUntaggedItemsDataLoading, + ]); const loading = rfidUntaggedItemsDataLoading || rfidTagOutdatedItemsDataLoading; @@ -122,6 +145,45 @@ function RFIDUntaggedItemsScreen({ navigation={navigation} title="Items" headerLargeTitle={false} + action1Label="Order" + action1SFSymbolName={ + MAJOR_VERSION_IOS >= 16 + ? 'arrow.up.and.down.text.horizontal' + : 'slider.vertical.3' + } + action1MaterialIconName="sort-ascending" + action1MenuActions={[ + { + type: 'section', + children: [ + { + title: 'Sort by Created Time', + state: sort === 'created_time' ? 'on' : 'off', + onPress: () => setSort('created_time'), + }, + { + title: 'Sort by Updated Time', + state: sort === 'updated_time' ? 'on' : 'off', + onPress: () => setSort('updated_time'), + }, + ], + }, + { + type: 'section', + children: [ + { + title: 'Ascending', + state: order === 'asc' ? 'on' : 'off', + onPress: () => setOrder('asc'), + }, + { + title: 'Descending', + state: order === 'desc' ? 'on' : 'off', + onPress: () => setOrder('desc'), + }, + ], + }, + ]} >