Merge pull request #3825 from inaturalist/mob-1479-wire-up-observation-sort-in-myobs-ui-only

Mob 1479 wire up observation sort in myobs UI only
This commit is contained in:
Abbey Campbell authored and GitHub committed 2026-07-14 11:02:13 -07:00
commit 2df780f8b5
4 files changed
+88 -7

No files matched your search

@@ -20,6 +20,7 @@ import { Alert } from "react-native";
import Observation from "realmModels/Observation";
import Taxon from "realmModels/Taxon";
import type { RealmObservation } from "realmModels/types";
import type { OBSERVATIONS_SORT } from "sharedHelpers/observationsSort";
import type { SPECIES_SORT } from "sharedHelpers/speciesSort";
import {
sortSpeciesCounts,
@@ -134,6 +135,13 @@ const MyObservationsResults = ( ) => {
} );
};
const setObservationsSortOptionId = ( value: OBSERVATIONS_SORT ) => {
myObsDispatch( {
type: MY_OBSERVATIONS_ACTION.SET_OBSERVATIONS_SORT,
observationsSort: value,
} );
};
const toggleLayout = ( ) => {
writeLayoutToStorage( layout === "grid"
? "list"
@@ -446,12 +454,14 @@ const MyObservationsResults = ( ) => {
numUnuploadedObservations={numUnuploadedObservations}
numObsMissingBasics={numObsMissingBasics}
observationIds={observationIds}
observationsSortOptionId={myObsState.observationsSort}
onEndReached={fetchNextPage}
onListLayout={restoreScrollOffset}
onScroll={onScroll}
openSheet={openSheet}
refetchTaxa={refetchTaxa}
setActiveTab={setActiveTab}
setObservationsSortOptionId={setObservationsSortOptionId}
setOpenSheet={setOpenSheet}
setSpeciesSortOptionId={setSpeciesSortOptionId}
showNoResults={showNoResults}
@@ -28,6 +28,11 @@ import type {
RealmObservation,
RealmUser,
} from "realmModels/types";
import type { OBSERVATIONS_SORT } from "sharedHelpers/observationsSort";
import {
OBSERVATIONS_SORT_OPTIONS,
useObservationsSortLabels,
} from "sharedHelpers/observationsSort";
import type { SPECIES_SORT } from "sharedHelpers/speciesSort";
import {
MY_OBSERVATIONS_SPECIES_SORT_OPTIONS,
@@ -65,11 +70,13 @@ interface Props {
numUnuploadedObservations: number;
numObsMissingBasics: number;
observationIds: { uuid: string }[];
observationsSortOptionId: OBSERVATIONS_SORT;
onEndReached: ( ) => void;
onListLayout?: ( ) => void;
onScroll?: ( ) => void;
openSheet: ACTIVE_SHEET;
setActiveTab: ( newTab: string ) => void;
setObservationsSortOptionId: ( value: OBSERVATIONS_SORT ) => void;
setOpenSheet: ( value: ACTIVE_SHEET ) => void;
setSpeciesSortOptionId: ( value: SPECIES_SORT ) => void;
showNoResults: boolean;
@@ -95,6 +102,12 @@ interface TaxaSortOption {
value: SPECIES_SORT;
}
interface ObservationsSortOption {
label: string;
text?: string;
value: OBSERVATIONS_SORT;
}
export const OBSERVATIONS_TAB = "observations";
export const TAXA_TAB = "taxa";
@@ -115,11 +128,13 @@ const MyObservationsSimple = ( {
numUnuploadedObservations,
numObsMissingBasics: numUnuploadedObsMissingBasics,
observationIds,
observationsSortOptionId,
onEndReached,
onListLayout,
onScroll,
openSheet,
setActiveTab,
setObservationsSortOptionId,
setOpenSheet,
setSpeciesSortOptionId,
showNoResults,
@@ -137,7 +152,11 @@ const MyObservationsSimple = ( {
const searchMyObservationsEnabled = useFeatureFlag(
FeatureFlag.SearchMyObservationsEnabled,
);
const sortMyObservationsEnabled = useFeatureFlag(
FeatureFlag.SortMyObservationsEnabled,
);
const speciesSortLabels = useSpeciesSortLabels( );
const observationsSortLabels = useObservationsSortLabels( );
const navigation = useNavigation( );
const route = useRoute( );
const {
@@ -163,6 +182,19 @@ const MyObservationsSimple = ( {
{} as Record<SPECIES_SORT, TaxaSortOption>,
);
const observationsSortOptions = OBSERVATIONS_SORT_OPTIONS.reduce(
( acc, sortBy ) => {
const { label, text } = observationsSortLabels[sortBy];
acc[sortBy] = {
label,
text,
value: sortBy,
};
return acc;
},
{} as Record<OBSERVATIONS_SORT, ObservationsSortOption>,
);
const renderTaxaItem = useCallback( ( { item: speciesCount }: TaxaFlashListRenderItemProps ) => {
const taxonId = speciesCount.taxon.id;
const navToTaxonDetails = ( ) => (
@@ -303,7 +335,7 @@ const MyObservationsSimple = ( {
Alert.alert( t( "You-are-offline" ), t( "Please-try-again-when-you-are-online" ) );
}
const handleSortConfirm = ( optionId: SPECIES_SORT ) => {
const handleSpeciesSortConfirm = ( optionId: SPECIES_SORT ) => {
if ( currentUser && !isConnected ) {
showOfflineAlert( );
return;
@@ -321,6 +353,16 @@ const MyObservationsSimple = ( {
setOpenSheet( ACTIVE_SHEET.NONE );
};
const handleObservationsSortConfirm = ( optionId: OBSERVATIONS_SORT ) => {
if ( currentUser && !isConnected ) {
showOfflineAlert( );
return;
}
setObservationsSortOptionId( optionId );
setOpenSheet( ACTIVE_SHEET.NONE );
};
const handlePivotCardGridItemPress = ( ) => {
const { uuid } = observationIds[0];
navigation.navigate( {
@@ -396,10 +438,12 @@ const MyObservationsSimple = ( {
layout={layout}
updateObservationsView={toggleLayout}
/>
{/* <SortButton
onPress={() => setOpenSheet( ACTIVE_SHEET.SORT )}
accessibilityLabel={t( "Change-observations-sort-order" )}
/> */}
{sortMyObservationsEnabled && (
<SortButton
onPress={() => setOpenSheet( ACTIVE_SHEET.SORT )}
accessibilityLabel={t( "Change-observations-sort-order" )}
/>
)}
</>
) }
{ ( activeTab === TAXA_TAB && taxa.length > 0 ) && (
@@ -434,12 +478,21 @@ const MyObservationsSimple = ( {
)}
{ ( activeTab === TAXA_TAB && taxa.length === 0 ) && renderOfflineNotice( )}
</ViewWrapper>
{openSheet === ACTIVE_SHEET.SORT && (
{openSheet === ACTIVE_SHEET.SORT && activeTab === OBSERVATIONS_TAB && (
<RadioButtonSheet
headerText={t( "SORT-OBSERVATIONS" )}
radioValues={observationsSortOptions}
selectedValue={observationsSortOptionId}
confirm={optionId => handleObservationsSortConfirm( optionId as OBSERVATIONS_SORT )}
onPressClose={() => setOpenSheet( ACTIVE_SHEET.NONE )}
/>
)}
{openSheet === ACTIVE_SHEET.SORT && activeTab === TAXA_TAB && (
<RadioButtonSheet
headerText={t( "SORT-SPECIES" )}
radioValues={taxaSortOptions}
selectedValue={speciesSortOptionId}
confirm={optionId => handleSortConfirm( optionId as SPECIES_SORT )}
confirm={optionId => handleSpeciesSortConfirm( optionId as SPECIES_SORT )}
onPressClose={() => setOpenSheet( ACTIVE_SHEET.NONE )}
/>
)}
+15
View File
@@ -75,6 +75,10 @@ const useRozenite = ( { queryClient, storageAdapters }: RozeniteOptions ) => {
resolvedValue: searchMyObservationsEnabled,
setOverride: setSearchMyObservationsEnabled,
} = useFeatureFlagForDebug( FeatureFlag.SearchMyObservationsEnabled );
const {
resolvedValue: sortMyObservationsEnabled,
setOverride: setSortMyObservationsEnabled,
} = useFeatureFlagForDebug( FeatureFlag.SortMyObservationsEnabled );
const sections = useMemo(
() => [
@@ -135,6 +139,15 @@ const useRozenite = ( { queryClient, storageAdapters }: RozeniteOptions ) => {
setSearchMyObservationsEnabled( !searchMyObservationsEnabled );
},
},
{
id: "sort-my-observations",
type: "toggle",
title: "Sort My Observations",
value: sortMyObservationsEnabled,
onUpdate: () => {
setSortMyObservationsEnabled( !sortMyObservationsEnabled );
},
},
],
} ),
],
@@ -147,6 +160,8 @@ const useRozenite = ( { queryClient, storageAdapters }: RozeniteOptions ) => {
setTraditionalProjectsEnabled,
searchMyObservationsEnabled,
setSearchMyObservationsEnabled,
sortMyObservationsEnabled,
setSortMyObservationsEnabled,
],
);
+3
View File
@@ -24,6 +24,7 @@ export enum FeatureFlag {
NewsEnabled = "newsEnabled",
TraditionalProjectsEnabled = "traditionalProjectsEnabled",
SearchMyObservationsEnabled = "searchMyObservationsEnabled",
SortMyObservationsEnabled = "sortMyObservationsEnabled",
}
const initialFeatureFlagConfig: Record<FeatureFlag, boolean> = {
@@ -32,6 +33,7 @@ const initialFeatureFlagConfig: Record<FeatureFlag, boolean> = {
[FeatureFlag.NewsEnabled]: false,
[FeatureFlag.TraditionalProjectsEnabled]: false,
[FeatureFlag.SearchMyObservationsEnabled]: false,
[FeatureFlag.SortMyObservationsEnabled]: false,
};
const initialFeatureFlagDebugOverrides: Record<FeatureFlag, boolean | null> = {
@@ -40,6 +42,7 @@ const initialFeatureFlagDebugOverrides: Record<FeatureFlag, boolean | null> = {
[FeatureFlag.NewsEnabled]: null,
[FeatureFlag.TraditionalProjectsEnabled]: null,
[FeatureFlag.SearchMyObservationsEnabled]: null,
[FeatureFlag.SortMyObservationsEnabled]: null,
};
const DEFAULT_STATE = {