refactor: move components to sub dir

This commit is contained in:
鲁树人
2023-06-03 14:13:37 +01:00
parent b136bac9b6
commit 897830cd44
9 changed files with 34 additions and 34 deletions

23
src/components/App.tsx Normal file
View File

@@ -0,0 +1,23 @@
import { Box, Center, Container } from '@chakra-ui/react';
import { SelectFile } from './SelectFile';
import { FileListing } from '~/features/file-listing/FileListing';
import { Footer } from './Footer';
function App() {
return (
<Box height="full" width="full" pt="4">
<Container maxW="container.large">
<Center>
<SelectFile />
</Center>
<Box mt="8">
<FileListing />
</Box>
<Footer />
</Container>
</Box>
);
}
export default App;

View File

@@ -0,0 +1,23 @@
import { useEffect } from 'react';
import App from './App';
import { ChakraProvider } from '@chakra-ui/react';
import { Provider } from 'react-redux';
import { theme } from '~/theme';
import { persistSettings } from '~/features/settings/persistSettings';
import { setupStore } from '~/store';
// Private to this file only.
const store = setupStore();
export function AppRoot() {
useEffect(() => persistSettings(store), []);
return (
<ChakraProvider theme={theme}>
<Provider store={store}>
<App />
</Provider>
</ChakraProvider>
);
}

View File

@@ -0,0 +1,22 @@
import { useEffect, useState } from 'react';
// Update every half hour
const TIMER_UPDATE_INTERVAL = 30 * 60 * 1000;
const getCurrentYear = () => new Date().getFullYear();
export function CurrentYear() {
const [year, setYear] = useState(getCurrentYear);
useEffect(() => {
const updateTime = () => setYear(getCurrentYear);
updateTime();
const timer = setInterval(updateTime, TIMER_UPDATE_INTERVAL);
return () => {
clearInterval(timer);
};
}, []);
return <>{year}</>;
}

43
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,43 @@
import { Center, Flex, Link, Text } from '@chakra-ui/react';
import { Suspense } from 'react';
import { SDKVersion } from './SDKVersion';
import { CurrentYear } from './CurrentYear';
export function Footer() {
return (
<Center height="footer.container">
<Center
height="footer.content"
fontSize="sm"
textAlign="center"
position="fixed"
bottom="0"
w="full"
bg="gray.100"
color="gray.800"
left="0"
flexDir="column"
>
<Flex as={Text}>
{'音乐解锁 (__APP_VERSION_SHORT__'}
<Suspense>
<SDKVersion />
</Suspense>
{') - 移除已购音乐的加密保护。'}
</Flex>
<Text>
{'Copyright © 2019 - '}
<CurrentYear />{' '}
<Link href="https://git.unlock-music.dev/um" isExternal>
UnlockMusic
</Link>
{' | 音乐解锁授权基于'}
<Link href="https://git.unlock-music.dev/um/um-react/src/branch/main/LICENSE" isExternal>
MIT许可协议
</Link>
</Text>
</Center>
</Center>
);
}

View File

@@ -0,0 +1,33 @@
import { InfoOutlineIcon } from '@chakra-ui/icons';
import { Tooltip, VStack, Text, Flex } from '@chakra-ui/react';
import { workerClientBus } from '~/decrypt-worker/client';
import { DECRYPTION_WORKER_ACTION_NAME } from '~/decrypt-worker/constants';
import usePromise from 'react-promise-suspense';
const getSDKVersion = async (): Promise<string> => {
return workerClientBus.request(DECRYPTION_WORKER_ACTION_NAME.VERSION, null);
};
export function SDKVersion() {
const sdkVersion = usePromise(getSDKVersion, []);
return (
<Flex as="span" pl="1" alignItems="center" data-testid="sdk-version">
<Tooltip
hasArrow
placement="top"
label={
<VStack>
<Text>App: __APP_VERSION__</Text>
<Text>SDK: {sdkVersion}</Text>
</VStack>
}
bg="gray.300"
color="black"
>
<InfoOutlineIcon />
</Tooltip>
</Flex>
);
}

View File

@@ -0,0 +1,77 @@
import { useDropzone } from 'react-dropzone';
import { Box, Text } from '@chakra-ui/react';
import { UnlockIcon } from '@chakra-ui/icons';
import { useAppDispatch } from '~/hooks';
import { addNewFile, processFile } from '~/features/file-listing/fileListingSlice';
import { nanoid } from 'nanoid';
export function SelectFile() {
const dispatch = useAppDispatch();
const { getRootProps, getInputProps, isDragActive } = useDropzone({
multiple: true,
onDropAccepted(files, _event) {
console.debug(
'react-dropzone/onDropAccepted(%o, %o)',
files.length,
files.map((x) => x.name)
);
for (const file of files) {
const blobURI = URL.createObjectURL(file);
const fileName = file.name;
const fileId = 'file://' + nanoid();
// FIXME: this should be a single action/thunk that first adds the item, then updates it.
dispatch(
addNewFile({
id: fileId,
blobURI,
fileName,
})
);
dispatch(processFile({ fileId }));
}
},
});
return (
<Box
{...getRootProps()}
w="100%"
maxW={480}
borderWidth="1px"
borderRadius="lg"
transitionDuration="0.5s"
p="6"
cursor="pointer"
display="flex"
flexDir="column"
alignItems="center"
_hover={{
borderColor: 'gray.400',
bg: 'gray.50',
}}
{...(isDragActive && {
bg: 'blue.50',
borderColor: 'blue.700',
})}
>
<input {...getInputProps()} />
<Box pb={3}>
<UnlockIcon boxSize={8} />
</Box>
<Box textAlign="center">
<Text as="span" color="teal.400">
</Text>
<Text fontSize="sm" opacity="50%">
</Text>
</Box>
</Box>
);
}