KWMv2/酷我 mflac 支持 #35
@ -1,122 +0,0 @@
|
|||||||
import {
|
|
||||||
Center,
|
|
||||||
Flex,
|
|
||||||
Modal,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalOverlay,
|
|
||||||
Tab,
|
|
||||||
TabList,
|
|
||||||
TabPanel,
|
|
||||||
TabPanels,
|
|
||||||
Tabs,
|
|
||||||
Text,
|
|
||||||
useToast,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import { FileInput } from '~/components/FileInput';
|
|
||||||
import { qmc2ImportKeys } from '../../settingsSlice';
|
|
||||||
import { useAppDispatch } from '~/hooks';
|
|
||||||
import { DatabaseKeyExtractor } from '~/util/DatabaseKeyExtractor';
|
|
||||||
|
|
||||||
import { InstructionsAndroid } from './InstructionsAndroid';
|
|
||||||
import { MMKVParser } from '~/util/MMKVParser';
|
|
||||||
import { getFileName } from '~/util/pathHelper';
|
|
||||||
import { InstructionsMac } from './InstructionsMac';
|
|
||||||
import { InstructionsIOS } from './InstructionsIOS';
|
|
||||||
import { InstructionsPC } from './InstructionsPC';
|
|
||||||
|
|
||||||
export interface ImportFileModalProps {
|
|
||||||
show: boolean;
|
|
||||||
onClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface KeyEntry {
|
|
||||||
name: string;
|
|
||||||
key: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ImportFileModal({ onClose, show }: ImportFileModalProps) {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const toast = useToast();
|
|
||||||
const handleFileReceived = async (files: File[]) => {
|
|
||||||
try {
|
|
||||||
const file = files[0];
|
|
||||||
const fileBuffer = await file.arrayBuffer();
|
|
||||||
|
|
||||||
let qmc2Keys: null | KeyEntry[] = null;
|
|
||||||
|
|
||||||
if (/[_.]db$/i.test(file.name)) {
|
|
||||||
const extractor = await DatabaseKeyExtractor.getInstance();
|
|
||||||
qmc2Keys = extractor.extractQmAndroidDbKeys(fileBuffer);
|
|
||||||
if (!qmc2Keys) {
|
|
||||||
alert(`不是支持的 SQLite 数据库文件。\n表名:${qmc2Keys}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (/MMKVStreamEncryptId|filenameEkeyMap/i.test(file.name)) {
|
|
||||||
const fileBuffer = await file.arrayBuffer();
|
|
||||||
const map = MMKVParser.toStringMap(new DataView(fileBuffer));
|
|
||||||
qmc2Keys = Array.from(map.entries(), ([name, key]) => ({ name: getFileName(name), key }));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qmc2Keys) {
|
|
||||||
dispatch(qmc2ImportKeys(qmc2Keys));
|
|
||||||
onClose();
|
|
||||||
toast({
|
|
||||||
title: `导入成功 (${qmc2Keys.length})`,
|
|
||||||
description: '记得保存更改来应用。',
|
|
||||||
isClosable: true,
|
|
||||||
duration: 5000,
|
|
||||||
status: 'success',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
alert(`不支持的文件:${file.name}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('error during import: ', e);
|
|
||||||
alert(`导入数据库时发生错误:${e}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal isOpen={show} onClose={onClose} closeOnOverlayClick={false} scrollBehavior="inside" size="xl">
|
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent>
|
|
||||||
<ModalHeader>导入密钥数据库</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<Flex as={ModalBody} gap={2} flexDir="column" flex={1}>
|
|
||||||
<Center>
|
|
||||||
<FileInput onReceiveFiles={handleFileReceived}>拖放或点我选择含有密钥的数据库文件</FileInput>
|
|
||||||
</Center>
|
|
||||||
|
|
||||||
<Text mt={2}>选择你的「QQ 音乐」客户端平台以查看对应说明:</Text>
|
|
||||||
|
|
||||||
<Flex as={Tabs} variant="enclosed" flexDir="column" flex={1} minH={0}>
|
|
||||||
<TabList>
|
|
||||||
<Tab>安卓</Tab>
|
|
||||||
<Tab>iOS</Tab>
|
|
||||||
<Tab>Mac</Tab>
|
|
||||||
<Tab>Windows</Tab>
|
|
||||||
</TabList>
|
|
||||||
<TabPanels flex={1} overflow="auto">
|
|
||||||
<TabPanel>
|
|
||||||
<InstructionsAndroid />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel>
|
|
||||||
<InstructionsIOS />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel>
|
|
||||||
<InstructionsMac />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel>
|
|
||||||
<InstructionsPC />
|
|
||||||
</TabPanel>
|
|
||||||
</TabPanels>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user