Skip to content

Commit

Permalink
Merge pull request #230 from Kutius/dev
Browse files Browse the repository at this point in the history
小屏幕适配 (仅首页除drawer)
  • Loading branch information
guansss authored Nov 17, 2023
2 parents 6e39caa + c71bee2 commit c4386d7
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 76 deletions.
4 changes: 3 additions & 1 deletion src/components/AccountManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { LoginPanel } from 'components/account/LoginPanel'
import { EditorFieldProps } from 'components/editor/EditorFieldProps'
import { authAtom } from 'store/auth'
import { NetworkError } from 'utils/fetcher'
import { useCurrentSize } from 'utils/useCurrenSize'
import { useNetworkState } from 'utils/useNetworkState'
import { wrapErrorMessage } from 'utils/wrapErrorMessage'

Expand Down Expand Up @@ -303,6 +304,7 @@ export const AccountAuthDialog: ComponentType<{
export const AccountManager: ComponentType = withGlobalErrorBoundary(() => {
const [open, setOpen] = useState(false)
const [authState] = useAtom(authAtom)
const { isSM } = useCurrentSize()

return (
<>
Expand All @@ -318,7 +320,7 @@ export const AccountManager: ComponentType = withGlobalErrorBoundary(() => {
</Popover2>
) : (
<Button className="ml-auto" icon="user" onClick={() => setOpen(true)}>
登录 / 注册
{!isSM && '登录 / 注册'}
</Button>
)}
</>
Expand Down
19 changes: 19 additions & 0 deletions src/components/NavExpandButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Button } from '@blueprintjs/core'

import { useAtomValue, useSetAtom } from 'jotai'

import { navAtom, toggleExpandNavAtom } from 'store/nav'

export const NavExpandButton = () => {
const expanded = useAtomValue(navAtom)
const toggleExpaned = useSetAtom(toggleExpandNavAtom)

return (
<div className="sm:hidden">
<Button
onClick={toggleExpaned}
icon={expanded.expanded ? 'cross' : 'menu'}
/>
</div>
)
}
123 changes: 66 additions & 57 deletions src/components/OperationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,58 +51,77 @@ export const OperationCard = ({
<Card
interactive={true}
elevation={Elevation.TWO}
className="mb-2 last:mb-0"
className="mb-4 sm:mb-2 last:mb-0"
onClick={() => setDrawerOpen(true)}
>
<div className="flex items-start">
<H4 className="inline-block pb-1 border-b-2 border-zinc-200 border-solid mb-2 mr-2">
{operationDoc.doc.title}
</H4>
<Tooltip2
placement="bottom"
content={<div className="max-w-sm dark:text-slate-900">下载原 JSON</div>}
>
<Button
small
className="mr-2 mb-2"
icon="download"
onClick={(e) => {
e.stopPropagation()
handleDownloadJSON(operationDoc)
}}
/>
</Tooltip2>
<Tooltip2
placement="bottom"
content={<div className="max-w-sm dark:text-slate-900">复制神秘代码</div>}
>
<Button
small
className="mb-2"
icon="clipboard"
onClick={(e) => {
e.stopPropagation()
handleCopyShortCode(operation)
}}
/>
</Tooltip2>
<div className="flex-1" />
<div className="flex flex-col items-end whitespace-nowrap">
<div className="w-full flex justify-end text-zinc-500">
<div className="flex items-center mr-4">
<Icon icon="star" className="mr-1.5" />
<div className="flex flex-wrap mb-4 sm:mb-2">
{/* title */}
<div className="flex flex-col gap-3">
<div className="flex gap-2">
<H4 className="inline-block pb-1 border-b-2 border-zinc-200 border-solid mb-2">
{operationDoc.doc.title}
</H4>
<Tooltip2
placement="bottom"
content={
<div className="max-w-sm dark:text-slate-900">
下载原 JSON
</div>
}
>
<Button
small
icon="download"
onClick={(e) => {
e.stopPropagation()
handleDownloadJSON(operationDoc)
}}
/>
</Tooltip2>
<Tooltip2
placement="bottom"
content={
<div className="max-w-sm dark:text-slate-900">
复制神秘代码
</div>
}
>
<Button
small
icon="clipboard"
onClick={(e) => {
e.stopPropagation()
handleCopyShortCode(operation)
}}
/>
</Tooltip2>
</div>
<H5 className="flex items-center text-slate-900 -mt-3">
<EDifficultyLevel
level={
findLevelByStageName(levels, operationDoc.stageName) ||
createCustomLevel(operationDoc.stageName)
}
difficulty={operationDoc.difficulty}
/>
</H5>
</div>

<div className="lg:flex-1 hidden" />

{/* meta */}
<div className="flex flex-col flex-1 gap-y-1.5 gap-x-4">
<div className="flex flex-wrap sm:justify-end items-center gap-x-4 gap-y-1 text-zinc-500">
<div className="flex items-center gap-1.5">
<Icon icon="star" />
<OperationRating
className="text-sm"
operation={operation}
layout="horizontal"
/>
</div>

<Tooltip2
className="mr-4"
placement="top"
content={`访问量:${operation.views}`}
>
<Tooltip2 placement="top" content={`访问量:${operation.views}`}>
<div>
<Icon icon="eye-open" className="mr-1.5" />
<span>{operation.views}</span>
Expand All @@ -117,8 +136,7 @@ export const OperationCard = ({
/>
</div>
</div>

<div className="w-full flex justify-end text-zinc-500 mt-1.5">
<div className="text-zinc-500 self-end">
<Tooltip2 placement="top" content={`作者:${operation.uploader}`}>
<div>
<Icon icon="user" className="mr-1.5" />
Expand All @@ -128,24 +146,15 @@ export const OperationCard = ({
</div>
</div>
</div>
<H5 className="flex items-center text-slate-900 -mt-3">
<EDifficultyLevel
level={
findLevelByStageName(levels, operationDoc.stageName) ||
createCustomLevel(operationDoc.stageName)
}
difficulty={operationDoc.difficulty}
/>
</H5>
<div className="flex">
<div className="text-gray-700 leading-normal w-1/2">
<div className="flex md:flex-row flex-col gap-4">
<div className="text-gray-700 leading-normal md:w-1/2">
{/* <div className="text-sm text-zinc-600 mb-2 font-bold">作业描述</div> */}
<Paragraphs
content={operationDoc.doc.details}
limitHeight={21 * 13.5} // 13 lines, 21px per line; the extra 0.5 line is intentional so the `mask` effect is obvious
/>
</div>
<div className="w-1/2 ml-4">
<div className="md:w-1/2">
<div className="text-sm text-zinc-600 mb-2 font-bold">
干员/干员组
</div>
Expand Down
1 change: 0 additions & 1 deletion src/components/ThemeSwitchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const ThemeSwitchButton = () => {
}, [theme])
return (
<Button
className="mr-4"
onClick={handleThemeSwitch}
icon={theme === 'dark' ? 'moon' : 'flash'}
></Button>
Expand Down
48 changes: 48 additions & 0 deletions src/components/drawer/NavAside.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Button, Portal } from '@blueprintjs/core'

import { useAtomValue, useSetAtom } from 'jotai'
import { LINKS } from 'layouts/AppLayout'
import { NavLink } from 'react-router-dom'

import { navAtom, toggleExpandNavAtom } from 'store/nav'

export const NavAside = () => {
const nav = useAtomValue(navAtom)
const toggleNav = useSetAtom(toggleExpandNavAtom)
const navLinks = [...LINKS]

if (!nav.expanded) return null

return (
<Portal>
{/* todo: 这里可以重写移动端header 需要去掉top */}
<div className="fixed inset-0 top-14 z-50 overflow-y-auto backdrop-blur-lg sm:hidden">
<div className="px-4 sm:px-6 pt-3 pb-6">
<nav className="flex flex-col gap-3">
{navLinks.map((link) => (
<div className="flex-col w-full" key={link.to}>
<NavLink
to={link.to}
className="text-sm text-zinc-600 !no-underline"
onClick={() => toggleNav()}
>
{({ isActive }) => (
<Button
minimal
icon={link.icon}
active={isActive}
className="w-full flex items-center"
style={{ justifyContent: 'flex-start' }}
>
{link.label}
</Button>
)}
</NavLink>
</div>
))}
</nav>
</div>
</div>
</Portal>
)
}
42 changes: 25 additions & 17 deletions src/layouts/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { FCC } from 'types'

import { AccountManager } from 'components/AccountManager'
import { BackToTop } from 'components/BackToTop'
import { NavExpandButton } from 'components/NavExpandButton'
import { ThemeSwitchButton } from 'components/ThemeSwitchButton'
import { NavAside } from 'components/drawer/NavAside'

const LINKS: {
export const LINKS: {
to: string
label: string
icon: IconName
Expand All @@ -28,7 +30,7 @@ const LINKS: {

export const AppLayout: FCC = ({ children }) => (
<div className="flex flex-col h-full w-full bg-zinc-50 ">
<Navbar className="flex w-full px-8 py-2 items-center bg-zinc-100 shadow fixed h-14 z-10 whitespace-nowrap overflow-x-auto overflow-y-hidden">
<Navbar className="flex w-full px-8 py-2 items-center bg-zinc-100 shadow fixed h-14 z-10 whitespace-nowrap overflow-x-none overflow-y-hidden">
<Link to="/" className="flex items-center hover:no-underline ">
<div className="select-none text-lg font-bold leading-none">
MAA Copilot
Expand All @@ -41,25 +43,31 @@ export const AppLayout: FCC = ({ children }) => (

<div className="w-[1px] bg-gray-200 ml-4 mr-2 my-0.5 flex self-stretch" />

{LINKS.map((link) => (
<NavLink
key={link.to}
to={link.to}
className="text-sm text-zinc-600 !no-underline ml-2"
>
{({ isActive }) => (
<Button minimal icon={link.icon} active={isActive}>
{link.label}
</Button>
)}
</NavLink>
))}
<div className="sm:flex items-center hidden">
{LINKS.map((link) => (
<NavLink
key={link.to}
to={link.to}
className="text-sm text-zinc-600 !no-underline ml-2"
>
{({ isActive }) => (
<Button minimal icon={link.icon} active={isActive}>
{link.label}
</Button>
)}
</NavLink>
))}
</div>

<div className="flex-1" />

<ThemeSwitchButton />
<AccountManager />
<div className="flex sm:gap-4 gap-3">
<NavExpandButton />
<ThemeSwitchButton />
<AccountManager />
</div>
</Navbar>
<NavAside />

<div className="docs-content-wrapper pt-14 pb-16">{children}</div>

Expand Down
16 changes: 16 additions & 0 deletions src/store/nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { atom } from 'jotai'

interface NavState {
expanded?: boolean
}

export const navAtom = atom<NavState>({
expanded: false,
})

export const toggleExpandNavAtom = atom(null, (get, set, value) => {
set(navAtom, {
...get(navAtom),
expanded: !get(navAtom).expanded,
})
})
15 changes: 15 additions & 0 deletions src/utils/useCurrenSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useMemo } from 'react'
import { useWindowSize } from 'react-use'

// https://tailwindcss.com/docs/container
export const useCurrentSize = () => {
const { width } = useWindowSize()

const isSM = useMemo(() => width < 640, [width])
const isMD = useMemo(() => width >= 640 && width < 768, [width])
const isLG = useMemo(() => width >= 768 && width < 1024, [width])
const isXL = useMemo(() => width >= 1024 && width < 1280, [width])
const is2XL = useMemo(() => width >= 1280 && width < 1536, [width])

return { isSM, isMD, isLG, isXL, is2XL }
}

0 comments on commit c4386d7

Please sign in to comment.