fix: adjust layout for settings
All checks were successful
Build and Deploy / build (push) Successful in 1m26s

This commit is contained in:
鲁树人 2025-05-18 11:05:50 +09:00
parent 9518b813bd
commit 6cb1f9f87f
7 changed files with 86 additions and 56 deletions

View File

@ -1,8 +1,8 @@
<!DOCTYPE html> <!doctype html>
<html lang="zh-cmn-Hans-CN"> <html lang="zh-cmn-Hans-CN">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>音乐解锁 - Unlock Music</title> <title>音乐解锁 - Unlock Music</title>
<meta name="description" content="音乐解锁 - Unlock Music" /> <meta name="description" content="音乐解锁 - Unlock Music" />
@ -10,6 +10,7 @@
<link rel="apple-touch-icon" href="/pwa-512x512.png" sizes="512x512" /> <link rel="apple-touch-icon" href="/pwa-512x512.png" sizes="512x512" />
<meta name="theme-color" content="#4DBA87" /> <meta name="theme-color" content="#4DBA87" />
</head> </head>
<body> <body>
<main id="root"></main> <main id="root"></main>
<script type="module" src="/src/main.tsx"></script> <script type="module" src="/src/main.tsx"></script>

View File

@ -12,11 +12,12 @@ import { Footer } from '~/components/Footer';
import { FaqTab } from '~/tabs/FaqTab'; import { FaqTab } from '~/tabs/FaqTab';
import { SETTINGS_TABS } from '~/features/settings/settingsTabs'; import { SETTINGS_TABS } from '~/features/settings/settingsTabs';
import { Bounce, ToastContainer } from 'react-toastify'; import { Bounce, ToastContainer } from 'react-toastify';
import { SettingsHome } from '~/features/settings/SettingsHome';
// Private to this file only. // Private to this file only.
const store = setupStore(); const store = setupStore();
const tabClassNames = ({ isActive }: { isActive: boolean }) => `tab ${isActive ? 'tab-active' : ''}`; const tabClassNames = ({ isActive }: { isActive: boolean }) => `mb-[-2px] tab ${isActive ? 'tab-active' : ''}`;
export function AppRoot() { export function AppRoot() {
useEffect(() => persistSettings(store), []); useEffect(() => persistSettings(store), []);
@ -24,7 +25,7 @@ export function AppRoot() {
return ( return (
<BrowserRouter> <BrowserRouter>
<Provider store={store}> <Provider store={store}>
<div role="tablist" className="tabs tabs-border w-full justify-center"> <div role="tablist" className="tabs tabs-border w-full justify-center border-b-2 border-base-200 box-content">
<NavLink to="/" role="tab" className={tabClassNames}> <NavLink to="/" role="tab" className={tabClassNames}>
<MdHome /> <MdHome />
@ -39,10 +40,11 @@ export function AppRoot() {
</NavLink> </NavLink>
</div> </div>
<main className="flex-1 flex justify-center"> <main className="flex-1 flex justify-center min-h-0 overflow-auto">
<Routes> <Routes>
<Route path="/" Component={MainTab} /> <Route path="/" Component={MainTab} />
<Route path="/settings" Component={SettingsTab}> <Route path="/settings" Component={SettingsTab}>
<Route index Component={SettingsHome} />
{Object.entries(SETTINGS_TABS).map(([key, { Tab }]) => ( {Object.entries(SETTINGS_TABS).map(([key, { Tab }]) => (
<Route key={key} path={key} Component={Tab} /> <Route key={key} path={key} Component={Tab} />
))} ))}

View File

@ -9,9 +9,9 @@ export interface KeyListContainerProps {
export function KeyListContainer({ keys, children, ref }: KeyListContainerProps) { export function KeyListContainer({ keys, children, ref }: KeyListContainerProps) {
const count = keys.length; const count = keys.length;
return ( return (
<div ref={ref} className="flex grow min-h-0 overflow-auto pr-4 pt-3"> <div ref={ref} className="flex grow min-h-0 pr-4 pt-3">
{count > 0 && ( {count > 0 && (
<ul className="list bg-base-100 rounded-box shadow-md border border-base-300 w-full min-h-0 max-h-[30rem] overflow-auto"> <ul className="list bg-base-100 rounded-box shadow-sm border border-base-300 w-full min-h-0 overflow-auto">
{children} {children}
</ul> </ul>
)} )}

View File

@ -0,0 +1,29 @@
export interface ResponsiveNavProps {
navigationClassName?: string;
navigation?: React.ReactNode;
className?: string;
contentClassName?: string;
children?: React.ReactNode;
}
export function ResponsiveNav({
className = '',
navigationClassName = '',
contentClassName = '',
children,
navigation,
}: ResponsiveNavProps) {
return (
<div
className={`@container/nav grow grid grid-cols-1 grid-rows-[auto_1fr] md:grid-rows-1 md:grid-cols-[10rem_1fr] ${className}`}
>
{/* Sidebar */}
<aside className={`bg-gray-100 md:p-4 md:block ${navigationClassName}`}>{navigation}</aside>
{/* Main content */}
<div className={`p-4 grow ${contentClassName}`}>{children}</div>
</div>
);
}

View File

@ -5,6 +5,8 @@ import { NavLink, Outlet } from 'react-router';
import { SETTINGS_TABS } from '~/features/settings/settingsTabs.tsx'; import { SETTINGS_TABS } from '~/features/settings/settingsTabs.tsx';
import { MdOutlineSettingsBackupRestore } from 'react-icons/md'; import { MdOutlineSettingsBackupRestore } from 'react-icons/md';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { ResponsiveNav } from '../nav/ResponsiveNav';
import classNames from 'classnames';
export function Settings() { export function Settings() {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -25,23 +27,37 @@ export function Settings() {
}; };
const isSettingsNotSaved = useAppSelector(selectIsSettingsNotSaved); const isSettingsNotSaved = useAppSelector(selectIsSettingsNotSaved);
const tabClassNames = ({ isActive }: { isActive: boolean }) =>
classNames(
'link inline-flex text-nowrap mb-[-2px] no-underline w-full',
'border-b-2 md:border-b-0 md:border-r-2',
'tab md:grow',
{
'tab-active bg-accent/10 border-accent': isActive,
},
);
return ( return (
<div className="flex flex-col flex-1 container w-full"> <div className="flex flex-col flex-1 container w-full">
<div role="tablist" className="tabs tabs-border w-full justify-center gap-2"> <ResponsiveNav
{Object.entries(SETTINGS_TABS).map(([id, { name }]) => ( className="grow h-full overflow-auto"
<NavLink className="link link-neutral" key={id} to={`/settings/${id}`} role="tab"> contentClassName="flex flex-col overflow-auto"
{name} navigationClassName="overflow-x-auto pb-[2px] md:pb-0 h-full md:items-center [&]:md:flex"
</NavLink> navigation={
))} <div role="tablist" className="tabs gap-1 flex-nowrap md:flex-col grow items-center">
</div> {Object.entries(SETTINGS_TABS).map(([id, { name }]) => (
<NavLink className={tabClassNames} key={id} to={`/settings/${id}`} role="tab">
{/* TODO: ensure this flex div does not overflow */} {name}
<div className="flex flex-1 flex-col h-full overflow-auto"> </NavLink>
))}
</div>
}
>
<Outlet /> <Outlet />
</div> </ResponsiveNav>
<footer className="flex flex-row gap-2 w-full py-3"> <footer className="flex flex-row gap-2 w-full p-2 border-t border-base-200 bg-base-100">
<div className="grow"> <div className="grow inline-flex items-center">
{isSettingsNotSaved ? ( {isSettingsNotSaved ? (
<span> <span>
<span className="text-red-600"></span> <span className="text-red-600"></span>
@ -64,39 +80,6 @@ export function Settings() {
</button> </button>
</div> </div>
</footer> </footer>
{/* <VStack mt="4" alignItems="flex-start" w="full">*/}
{/* <Flex flexDir="row" gap="2" w="full">*/}
{/* <Center>*/}
{/* {isSettingsNotSaved ? (*/}
{/* <Box color="gray">*/}
{/* 有未储存的更改{' '}*/}
{/* <chakra.span color="red" wordBreak="keep-all">*/}
{/* 设定将在保存后生效*/}
{/* </chakra.span>*/}
{/* </Box>*/}
{/* ) : (*/}
{/* <Box color="gray">设定将在保存后生效</Box>*/}
{/* )}*/}
{/* </Center>*/}
{/* <Spacer />*/}
{/* <HStack gap="2" justifyContent="flex-end">*/}
{/* <IconButton*/}
{/* icon={<Icon as={MdOutlineSettingsBackupRestore} />}*/}
{/* onClick={handleResetSettings}*/}
{/* colorScheme="red"*/}
{/* variant="ghost"*/}
{/* title="放弃未储存的更改,将设定还原未储存前的状态。"*/}
{/* aria-label="放弃未储存的更改"*/}
{/* />*/}
{/* <Button onClick={handleApplySettings}>保存</Button>*/}
{/* </HStack>*/}
{/* </Flex>*/}
{/* </VStack>*/}
{/* </Flex>*/}
{/* ))}*/}
{/* </TabPanels>*/}
{/*</Tabs>*/}
</div> </div>
); );
} }

View File

@ -0,0 +1,8 @@
export function SettingsHome() {
return (
<div className="flex flex-col gap-4">
<h1 className="text-2xl font-bold"></h1>
<p></p>
</div>
);
}

View File

@ -75,7 +75,7 @@ export function PanelQingTing() {
value={secretKey} value={secretKey}
onChange={handleDataInput} onChange={handleDataInput}
/> />
<p className="label"> <p className="label flex-wrap">
<ExtLink href={QTFM_DEVICE_ID_URL}> <ExtLink href={QTFM_DEVICE_ID_URL}>
<code>qtfm-device-id</code> <code>qtfm-device-id</code>
@ -91,8 +91,15 @@ export function PanelQingTing() {
<p> <p>
<VQuote> <VQuote>
<code> <code className="break-words">
<HiWord>[]</HiWord>/Android/data/fm.qingting.qtradio/files/Music/ <HiWord>[]</HiWord>/<wbr />
Android/
<wbr />
data/
<wbr />
fm.qingting.qtradio/
<wbr />
files/Music/
</code> </code>
</VQuote> </VQuote>
</p> </p>