feat(layout):完成基本界面布局以及文件夹扫描功能。

This commit is contained in:
徐涛
2023-03-08 14:02:17 +08:00
parent ebc7c26522
commit 848c8c01e7
15 changed files with 367 additions and 24 deletions

View File

@@ -0,0 +1,6 @@
import { Box } from '@mantine/core';
import { FC } from 'react';
export const ComicView: FC = () => {
return <Box w="100%" h="100%" sx={{ overflow: 'hidden' }}></Box>;
};

View File

@@ -0,0 +1,23 @@
import { Box, Center, Text } from '@mantine/core';
import { isEmpty, map, pipe, sort } from 'ramda';
import { FC } from 'react';
import { useFileListStore } from '../states/files';
export const FileList: FC = () => {
const files = useFileListStore.use.files();
console.log('[debug]files from store: ', files);
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 => <div key={item.filename}>{item.filename}</div>)
)(files)}
{isEmpty(files) && (
<Center h="100%">
<Text size="xs"></Text>
</Center>
)}
</Box>
);
};

View File

@@ -0,0 +1,42 @@
import { Button, Group, Tooltip } from '@mantine/core';
import { notifications } from '@mantine/notifications';
import { IconFolder } from '@tabler/icons-react';
import { invoke } from '@tauri-apps/api';
import { open } from '@tauri-apps/api/dialog';
import { FC, useCallback } from 'react';
import { useFileListStore } from '../states/files';
export const FileToolbar: FC = () => {
const storeFiles = useFileListStore.use.updateFiles();
const handleOpenAction = useCallback(async () => {
try {
const directory = await open({
title: '打开要浏览的漫画所在的文件夹',
directory: true,
multiple: false
});
const files = await invoke('scan_directory', { target: directory });
console.log('[debug]file list: ', files);
storeFiles(files);
} catch (e) {
console.error('[error]打开文件夹', e);
notifications.show({ title: '未能成功打开指定文件夹,请重试。', color: 'red' });
}
}, [storeFiles]);
return (
<Group align="start" w="100%" spacing={4}>
<Tooltip label="打开漫画所在文件夹">
<Button
size="xs"
variant="subtle"
fullWidth
leftIcon={<IconFolder stroke={1.5} size={14} />}
onClick={handleOpenAction}
>
</Button>
</Tooltip>
</Group>
);
};

View File

@@ -0,0 +1,61 @@
import { ActionIcon, Group, NumberInput, rem, SegmentedControl, Tooltip } from '@mantine/core';
import {
IconArrowAutofitWidth,
IconLock,
IconPercentage,
IconZoomIn,
IconZoomOut
} from '@tabler/icons-react';
import { FC } from 'react';
import { useZoomState } from '../states/zoom';
export const PicToolbar: FC = () => {
const { lock, autoFit, currentZoom, viewMode } = useZoomState();
return (
<Group w="100%" position="right" spacing={8} px={4} py={4}>
<Tooltip label="锁定缩放">
<ActionIcon variant={lock ? 'filled' : 'subtle'} color="grape">
<IconLock stroke={1.5} size={24} />
</ActionIcon>
</Tooltip>
<Tooltip label="适应窗口宽度">
<ActionIcon variant={autoFit ? 'filled' : 'subtle'} color="grape">
<IconArrowAutofitWidth stroke={1.5} size={24} />
</ActionIcon>
</Tooltip>
<Tooltip label="缩小">
<ActionIcon variant="subtle" color="grape">
<IconZoomOut stroke={1.5} size={24} />
</ActionIcon>
</Tooltip>
<NumberInput
hideControls
size="xs"
min={20}
max={100}
step={5}
value={currentZoom}
styles={{ input: { width: rem(58), textAlign: 'center' } }}
rightSection={<IconPercentage stroke={1.5} size={16} />}
/>
<Tooltip label="放大">
<ActionIcon variant="subtle" color="grape">
<IconZoomIn stroke={1.5} size={24} />
</ActionIcon>
</Tooltip>
<Tooltip label="翻页模式">
<SegmentedControl
size="xs"
value={viewMode}
color="grape"
data={[
{ label: '单页', value: 'single' },
{ label: '双页', value: 'double' },
{ label: '连续', value: 'continuation' }
]}
/>
</Tooltip>
</Group>
);
};