refactor: batch 1

This commit is contained in:
鲁树人
2025-05-17 05:59:39 +09:00
parent 089d66cbf4
commit 13c669b4ea
23 changed files with 828 additions and 533 deletions

View File

@@ -19,7 +19,6 @@ import {
TabPanels,
Tabs,
Text,
useBreakpointValue,
useToast,
VStack,
} from '@chakra-ui/react';
@@ -47,11 +46,7 @@ const TABS: { name: string; Tab: FC }[] = [
export function Settings() {
const toast = useToast();
const dispatch = useAppDispatch();
const isLargeWidthDevice =
useBreakpointValue({
base: false,
lg: true,
}) ?? false;
const isLargeWidthDevice = false;
const [tabIndex, setTabIndex] = useState(0);
const handleTabChange = (idx: number) => {

View File

@@ -1,31 +1,9 @@
import {
Box,
Button,
ButtonGroup,
Checkbox,
Flex,
Heading,
HStack,
Icon,
IconButton,
List,
Menu,
MenuButton,
MenuDivider,
MenuItem,
MenuList,
Select,
Text,
Tooltip,
useToast,
} from '@chakra-ui/react';
import { Select, useToast } from '@chakra-ui/react';
import { useDispatch, useSelector } from 'react-redux';
import { qmc2AddKey, qmc2AllowFuzzyNameSearch, qmc2ClearKeys, qmc2ImportKeys } from '../settingsSlice';
import { selectStagingQMCv2Settings } from '../settingsSelector';
import React, { useState } from 'react';
import { MdAdd, MdDeleteForever, MdExpandMore, MdFileUpload } from 'react-icons/md';
import { QMCv2EKeyItem } from './QMCv2/QMCv2EKeyItem';
import { InfoOutlineIcon } from '@chakra-ui/icons';
import { ImportSecretModal } from '~/components/ImportSecretModal';
import { StagingQMCv2Key } from '../keyFormats';
import { DatabaseKeyExtractor } from '~/util/DatabaseKeyExtractor';
@@ -33,8 +11,11 @@ import { parseAndroidQmEKey } from '~/util/mmkv/qm';
import { getFileName } from '~/util/pathHelper';
import { QMCv2QQMusicAllInstructions } from './QMCv2/QMCv2QQMusicAllInstructions';
import { QMCv2DoubanAllInstructions } from './QMCv2/QMCv2DoubanAllInstructions';
import { AddKey } from '~/components/AddKey';
import { Dialog } from '~/components/Dialog';
export function PanelQMCv2Key() {
const [showFuzzyNameSearchInfo, setShowFuzzyNameSearchInfo] = useState(false);
const toast = useToast();
const dispatch = useDispatch();
const { keys: qmc2Keys, allowFuzzyNameSearch } = useSelector(selectStagingQMCv2Settings);
@@ -93,73 +74,64 @@ export function PanelQMCv2Key() {
};
return (
<Flex minH={0} flexDir="column" flex={1}>
<Heading as="h2" size="lg">
QMCv2
</Heading>
<div className="flex min-h-0 flex-col flex-1">
<h2 className="text-2xl font-bold">QMCv2 </h2>
<Text>
QQ FM QMCv2使QQ Mac iOS 使
FM线
</Text>
<p>
<span>QQ FM QMCv2</span>
<span>
使QQ Mac iOS 使 FM
线
</span>
</p>
<HStack pb={2} pt={2}>
<ButtonGroup isAttached colorScheme="purple" variant="outline">
<Button onClick={addKey} leftIcon={<Icon as={MdAdd} />}>
</Button>
<Menu>
<MenuButton as={IconButton} icon={<MdExpandMore />}></MenuButton>
<MenuList>
<MenuItem onClick={() => setShowImportModal(true)} icon={<Icon as={MdFileUpload} boxSize={5} />}>
</MenuItem>
<MenuDivider />
<MenuItem color="red" onClick={clearAll} icon={<Icon as={MdDeleteForever} boxSize={5} />}>
</MenuItem>
</MenuList>
</Menu>
</ButtonGroup>
<div className="flex flex-row gap-2 items-center">
<label className="label">
<input
className="checkbox"
type="checkbox"
checked={allowFuzzyNameSearch}
onChange={handleAllowFuzzyNameSearchCheckbox}
/>
</label>
<button className="btn btn-info btn-sm" type="button" onClick={() => setShowFuzzyNameSearchInfo(true)}>
?
</button>
<Dialog
closeButton
backdropClose
show={showFuzzyNameSearchInfo}
onClose={() => setShowFuzzyNameSearchInfo(false)}
title="莱文斯坦距离"
>
<p>使</p>
<p>
使
<ruby>
<rp> (</rp>
<rt>Levenshtein distance</rt>
<rp>)</rp>
</ruby>
</p>
<p></p>
<p></p>
</Dialog>
</div>
<HStack>
<Checkbox isChecked={allowFuzzyNameSearch} onChange={handleAllowFuzzyNameSearchCheckbox}>
<Text></Text>
</Checkbox>
<Tooltip
hasArrow
closeOnClick={false}
label={
<Box>
<Text>使</Text>
<Text>
使
<ruby>
<rp> (</rp>
<rt>Levenshtein distance</rt>
<rp>)</rp>
</ruby>
</Text>
<Text></Text>
<Text></Text>
</Box>
}
>
<InfoOutlineIcon />
</Tooltip>
</HStack>
</HStack>
<h3 className="mt-2 text-1xl font-bold"></h3>
<AddKey addKey={addKey} importKeyFromFile={() => setShowImportModal(true)} clearKeys={clearAll} />
<Box flex={1} minH={0} overflow="auto" pr="4">
<List spacing={3}>
<div className="flex-1 min-h-0 overflow-auto pr-4">
<ul className="list bg-base-100 rounded-box shadow-md">
{qmc2Keys.map(({ id, ekey, name }, i) => (
<QMCv2EKeyItem key={id} id={id} ekey={ekey} name={name} i={i} />
))}
</List>
{qmc2Keys.length === 0 && <Text></Text>}
</Box>
</ul>
{qmc2Keys.length === 0 && <p className="p-4 pb-2 text-xs tracking-wide"></p>}
</div>
<ImportSecretModal
clientName={
@@ -181,6 +153,6 @@ export function PanelQMCv2Key() {
{secretType === 'qm' && <QMCv2QQMusicAllInstructions />}
{secretType === 'douban' && <QMCv2DoubanAllInstructions />}
</ImportSecretModal>
</Flex>
</div>
);
}

View File

@@ -1,15 +1,3 @@
import {
HStack,
Icon,
IconButton,
Input,
InputGroup,
InputLeftElement,
InputRightElement,
ListItem,
Text,
VStack,
} from '@chakra-ui/react';
import { MdDelete, MdVpnKey } from 'react-icons/md';
import { qmc2DeleteKey, qmc2UpdateKey } from '../../settingsSlice';
import { useAppDispatch } from '~/hooks';
@@ -22,48 +10,45 @@ export const QMCv2EKeyItem = memo(({ id, name, ekey, i }: { id: string; name: st
dispatch(qmc2UpdateKey({ id, field: prop, value: e.target.value }));
const deleteKey = () => dispatch(qmc2DeleteKey({ id }));
return (
<ListItem mt={0} pt={2} pb={2} _even={{ bg: 'gray.50' }}>
<HStack>
<Text w="2em" textAlign="center">
{i + 1}
</Text>
const isValidEKey = [364, 704].includes(ekey.length);
<VStack flex={1}>
<Input
variant="flushed"
return (
<li className="list-row items-center">
<div className="flex items-center justify-center w-8 h-8 text-sm font-bold text-gray-500 bg-gray-200 rounded-full">
{i + 1}
</div>
<div className="join join-vertical flex-1">
<label className="input w-full rounded-tl-md rounded-tr-md">
<span className="cursor-default select-none"></span>
<input
type="text"
className="font-mono"
placeholder="文件名,包括后缀名。如 “AAA - BBB.mflac”"
value={name}
onChange={(e) => updateKey('name', e)}
/>
</label>
<label className="input w-full rounded-bl-md rounded-br-md mt-[-1px]">
<span className="cursor-default inline-flex items-center gap-1 select-none">
<MdVpnKey />
</span>
<input
type="text"
className="font-mono"
placeholder="密钥,通常包含 364 或 704 位字符,没有空格。"
value={ekey}
onChange={(e) => updateKey('ekey', e)}
/>
<span className={isValidEKey ? 'text-green-600' : 'text-red-600'}>
<code>{ekey.length || '?'}</code>
</span>
</label>
</div>
<InputGroup size="xs">
<InputLeftElement pr="2">
<Icon as={MdVpnKey} />
</InputLeftElement>
<Input
variant="flushed"
placeholder="密钥,通常包含 364 或 704 位字符,没有空格。"
value={ekey}
onChange={(e) => updateKey('ekey', e)}
/>
<InputRightElement>
<Text pl="2" color={ekey.length ? 'green.500' : 'red.500'}>
<code>{ekey.length || '?'}</code>
</Text>
</InputRightElement>
</InputGroup>
</VStack>
<IconButton
aria-label="删除该密钥"
icon={<Icon as={MdDelete} boxSize={6} />}
variant="ghost"
colorScheme="red"
type="button"
onClick={deleteKey}
/>
</HStack>
</ListItem>
<button type="button" className="btn btn-error btn-sm px-1 btn-outline" onClick={deleteKey}>
<MdDelete className="size-6" />
</button>
</li>
);
});