enhance(list):文件列表增加跟随滚动的功能。

This commit is contained in:
徐涛 2023-03-10 10:24:32 +08:00
parent 44c7f78363
commit cf724bb17f

View File

@ -1,15 +1,20 @@
//@ts-nocheck
import { Box, Center, Text } from '@mantine/core';
import EventEmitter from 'events';
import { includes, isEmpty, map, not, pipe, sort } from 'ramda';
import { FC, useCallback, useContext } from 'react';
import { head, includes, indexOf, isEmpty, length, mergeLeft, not, pluck } from 'ramda';
import { FC, useCallback, useContext, useLayoutEffect, useMemo, useRef } from 'react';
import { useMeasure } from 'react-use';
import { FixedSizeList } from 'react-window';
import { EventBusContext } from '../EventBus';
import { useFileListStore } from '../states/files';
import { sortedFilesSelector, useFileListStore } from '../states/files';
export const FileList: FC = () => {
const files = useFileListStore.use.files();
const files = useFileListStore(sortedFilesSelector());
const activeFiles = useFileListStore.use.actives();
const ebus = useContext<EventEmitter>(EventBusContext);
const filesCount = useMemo(() => length(files), [files]);
const [parentRef, { height: parentHeight }] = useMeasure();
const listRef = useRef<FixedSizeList | null>();
const handleFileSelectAction = useCallback(
(filename: string) => {
ebus.emit('navigate_offset', { filename });
@ -17,26 +22,43 @@ export const FileList: FC = () => {
[ebus]
);
useLayoutEffect(() => {
let firstActived = head(activeFiles);
let firstActivedIndex = indexOf(firstActived, pluck('filename', files));
listRef.current?.scrollToItem(firstActivedIndex, 'smart');
}, [activeFiles]);
return (
<Box w="100%" h="100%" pl={4} sx={{ flexGrow: 1, overflowY: 'auto', overflowX: 'hidden' }}>
{pipe(
sort((fa, fb) => fa.sort - fb.sort),
map(item => (
<Box
bg={includes(item.filename, activeFiles) && 'grape'}
key={item.filename}
px={4}
py={2}
onClick={() => handleFileSelectAction(item.filename)}
sx={theme => ({
cursor: 'pointer',
'&:hover': { color: not(includes(item.filename, activeFiles)) && theme.colors.red }
})}
>
{item.filename}
</Box>
))
)(files)}
<Box
w="100%"
h="100%"
pl={4}
sx={{ flexGrow: 1, overflowY: 'auto', contain: 'strict', overflowX: 'hidden' }}
ref={parentRef}
>
{!isEmpty(files) && (
<FixedSizeList itemCount={filesCount} itemSize={35} height={parentHeight} ref={listRef}>
{({ index, style }) => (
<Box
bg={includes(files[index].filename, activeFiles) && 'grape'}
key={index}
px={4}
py={2}
onClick={() => handleFileSelectAction(files[index].filename)}
sx={theme =>
mergeLeft(style, {
cursor: 'pointer',
'&:hover': {
color: not(includes(files[index].filename, activeFiles)) && theme.colors.red
}
})
}
>
{files[index].filename}
</Box>
)}
</FixedSizeList>
)}
{isEmpty(files) && (
<Center h="100%">
<Text size="xs"></Text>