feat: Remember Last Used Library Category

[skip ci]

Closes #1026
This commit is contained in:
Rajarshee Chatterjee
2026-07-25 12:21:53 +05:30
parent 7af0911f5b
commit d02291c22c
5 changed files with 66 additions and 15 deletions
+1 -2
View File
@@ -4,12 +4,11 @@ import {
UseLibraryReturnType,
} from '@screens/library/hooks/useLibrary';
import { useLibrarySettings } from '@hooks/persisted';
import { LibrarySettings } from '@hooks/persisted/useSettings';
// type Library = Category & { novels: LibraryNovelInfo[] };
type LibraryContextType = UseLibraryReturnType & {
settings: LibrarySettings;
settings: ReturnType<typeof useLibrarySettings>;
};
const defaultValue = {} as LibraryContextType;
+2
View File
@@ -103,6 +103,8 @@ export interface BrowseSettings {
export interface LibrarySettings {
/** User-selected category for newly added novels. */
defaultCategoryId?: number;
/** Last category viewed in the library. */
lastUsedCategoryId?: number;
globalUpdateExcludeCategoryIds?: number[];
globalUpdateIncludeCategoryIds?: number[];
sortOrder?: LibrarySortOrder;
+36 -13
View File
@@ -54,6 +54,7 @@ import { ThemeColors } from '@theme/types';
import { useLibraryContext } from '@components/Context/LibraryContext';
import { xor } from 'lodash-es';
import { SelectionContext } from './SelectionContext';
import { getLibraryCategoryIndex } from './constants/constants';
type State = NavigationState<{
key: string;
@@ -86,7 +87,13 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {
categories,
refetchLibrary,
isLoading,
settings: { showNumberOfNovels, downloadedOnlyMode, incognitoMode },
settings: {
showNumberOfNovels,
downloadedOnlyMode,
incognitoMode,
lastUsedCategoryId,
setLibrarySettings,
},
} = useLibraryContext();
const { importNovel } = useImport();
@@ -98,7 +105,19 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {
const bottomSheetRef = useRef<BottomSheetModalMethods | null>(null);
const [index, setIndex] = useState(0);
const [selectedCategoryId, setSelectedCategoryId] =
useState(lastUsedCategoryId);
const index = getLibraryCategoryIndex(categories, selectedCategoryId);
const setIndex = useCallback(
(nextIndex: number) => {
const categoryId = categories[nextIndex]?.id;
if (categoryId !== undefined) {
setSelectedCategoryId(categoryId);
setLibrarySettings({ lastUsedCategoryId: categoryId });
}
},
[categories, setLibrarySettings],
);
const {
value: setCategoryModalVisible,
@@ -483,17 +502,21 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {
) : null}
<SelectionContext.Provider value={selectionContextValue}>
<TabView
commonOptions={{
label: renderLabel,
}}
lazy
navigationState={navigationState}
renderTabBar={renderTabBar}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
/>
{categories.length ? (
<TabView
commonOptions={{
label: renderLabel,
}}
lazy
navigationState={navigationState}
renderTabBar={renderTabBar}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
/>
) : (
<SourceScreenSkeletonLoading theme={theme} />
)}
</SelectionContext.Provider>
{useLibraryFAB &&
@@ -0,0 +1,19 @@
import { getLibraryCategoryIndex } from '../constants';
const categories = [{ id: 1 }, { id: 7 }, { id: 12 }];
describe('getLibraryCategoryIndex', () => {
it('returns the index of the saved category', () => {
expect(getLibraryCategoryIndex(categories, 7)).toBe(1);
});
it('falls back to the first category when the saved category is unavailable', () => {
expect(getLibraryCategoryIndex(categories, 99)).toBe(0);
});
it('finds the saved category after categories are reordered', () => {
expect(getLibraryCategoryIndex([{ id: 7 }, { id: 1 }, { id: 12 }], 7)).toBe(
0,
);
});
});
@@ -1,5 +1,13 @@
import { getString } from '@i18n/translations';
export const getLibraryCategoryIndex = (
categories: { id: number }[],
categoryId?: number,
): number => {
const index = categories.findIndex(category => category.id === categoryId);
return index === -1 ? 0 : index;
};
export enum LibraryFilter {
Downloaded = '(chaptersDownloaded > 0 OR isLocal = 1)',
Unread = 'lastReadAt IS NULL',