Skip to content

Commit c0ea5ee

Browse files
Merge pull request #384 from MaaAssistantArknights/dev
Release to Production
2 parents af04b30 + 1f6da03 commit c0ea5ee

File tree

13 files changed

+308
-222
lines changed

13 files changed

+308
-222
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2025-03-01
2+
3+
- 优化了移动端界面 [@guansss](https://github.com/guansss)
4+
- 加入广告 [@guansss](https://github.com/guansss)
5+
16
## 2025-02-22
27

38
- 添加了关卡筛选器的联想输入功能 [@guansss](https://github.com/guansss)

public/ads_mumu.jpg

283 KB
Loading

src/apis/announcement.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export function useAnnouncement() {
2020
.then((res) => res.text())
2121
.catch((e) => {
2222
if ((e as Error).message === 'Failed to fetch') {
23-
console.warn(e)
2423
throw new Error('网络错误')
2524
}
2625

src/components/NavExpandButton.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import { navAtom, toggleExpandNavAtom } from 'store/nav'
66

77
export const NavExpandButton = () => {
88
const expanded = useAtomValue(navAtom)
9-
const toggleExpaned = useSetAtom(toggleExpandNavAtom)
9+
const toggleExpand = useSetAtom(toggleExpandNavAtom)
1010

1111
return (
12-
<div className="sm:hidden">
13-
<Button
14-
onClick={toggleExpaned}
15-
icon={expanded.expanded ? 'cross' : 'menu'}
16-
/>
17-
</div>
12+
<Button
13+
className="md:!hidden"
14+
onClick={() => toggleExpand()}
15+
icon={expanded.expanded ? 'cross' : 'menu'}
16+
/>
1817
)
1918
}

src/components/announcement/AnnPanel.tsx

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Card, Icon } from '@blueprintjs/core'
22

33
import clsx from 'clsx'
4-
import { FC, useEffect, useMemo, useState } from 'react'
4+
import { FC, ReactNode, useEffect, useMemo, useState } from 'react'
55

66
import { useAnnouncement } from '../../apis/announcement'
77
import {
@@ -15,9 +15,10 @@ import { AnnDialog } from './AnnDialog'
1515

1616
interface AnnPanelProps {
1717
className?: string
18+
trigger?: (params: { handleClick: () => void }) => ReactNode
1819
}
1920

20-
export const AnnPanel: FC<AnnPanelProps> = ({ className }) => {
21+
export const AnnPanel: FC<AnnPanelProps> = ({ className, trigger }) => {
2122
const { data, error } = useAnnouncement()
2223
const announcement = useMemo(
2324
() => (data ? parseAnnouncement(data) : undefined),
@@ -45,34 +46,36 @@ export const AnnPanel: FC<AnnPanelProps> = ({ className }) => {
4546
}
4647
}, [announcement, lastNoticed, setLastNoticed])
4748

49+
const handleClick = () => {
50+
setIsOpen({ yes: true, manually: true })
51+
setDisplaySections(announcement?.sections)
52+
}
53+
54+
trigger ??= ({ handleClick }) => (
55+
<Card interactive className={clsx(className)} onClick={handleClick}>
56+
<CardTitle icon="info-sign">公告</CardTitle>
57+
58+
<div className="flex">
59+
{announcement && (
60+
<ul className="grow list-disc pl-4">
61+
{announcement?.sections
62+
.slice(0, 3)
63+
.map(({ title }) => <li key={title}>{title}</li>)}
64+
</ul>
65+
)}
66+
{!announcement && error && (
67+
<div className="grow text-red-500">
68+
公告加载失败:{formatError(error)}
69+
</div>
70+
)}
71+
<Icon className="self-end" icon="more" size={14} />
72+
</div>
73+
</Card>
74+
)
75+
4876
return (
4977
<>
50-
<Card
51-
interactive
52-
className={clsx(className)}
53-
onClick={() => {
54-
setIsOpen({ yes: true, manually: true })
55-
setDisplaySections(announcement?.sections)
56-
}}
57-
>
58-
<CardTitle icon="info-sign">公告</CardTitle>
59-
60-
<div className="flex">
61-
{announcement && (
62-
<ul className="grow list-disc pl-4">
63-
{announcement?.sections
64-
.slice(0, 3)
65-
.map(({ title }) => <li key={title}>{title}</li>)}
66-
</ul>
67-
)}
68-
{!announcement && error && (
69-
<div className="grow text-red-500">
70-
公告加载失败:{formatError(error)}
71-
</div>
72-
)}
73-
<Icon className="self-end" icon="more" size={14} />
74-
</div>
75-
</Card>
78+
{trigger({ handleClick })}
7679
<AnnDialog
7780
sections={displaySections}
7881
isOpen={!!isOpen?.yes}

src/components/drawer/DrawerLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const DrawerLayout: FCC<{
55
}> = ({ title, children }) => {
66
return (
77
<section className="flex flex-col relative h-full">
8-
<div className="px-8 py-2 text-lg font-medium flex items-center bg-slate-100 shadow w-full h-12 dark:bg-slate-900 dark:text-white">
8+
<div className="px-4 md:px-8 py-2 text-lg font-medium flex flex-wrap items-center bg-slate-100 shadow w-full min-h-12 dark:bg-slate-900 dark:text-white">
99
{title}
1010
</div>
1111

src/components/drawer/NavAside.tsx

Lines changed: 84 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,100 @@
1-
import { Button, Portal } from '@blueprintjs/core'
1+
import { Drawer, Menu, MenuDivider } from '@blueprintjs/core'
2+
import { MenuItem2 } from '@blueprintjs/popover2'
23

34
import { useAtomValue, useSetAtom } from 'jotai'
4-
import { LINKS } from 'layouts/AppLayout'
5+
import { useState } from 'react'
56
import { NavLink } from 'react-router-dom'
67

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

10+
import { NAV_LINKS, SOCIAL_LINKS } from '../../links'
11+
import { useCurrentSize } from '../../utils/useCurrenSize'
12+
import { AnnPanel } from '../announcement/AnnPanel'
13+
import { OperationSetEditorDialog } from '../operation-set/OperationSetEditor'
14+
915
export const NavAside = () => {
16+
const { isMD } = useCurrentSize()
1017
const nav = useAtomValue(navAtom)
1118
const toggleNav = useSetAtom(toggleExpandNavAtom)
12-
const navLinks = [...LINKS]
1319

14-
if (!nav.expanded) return null
20+
const [showOperationSetDialog, setShowOperationSetDialog] = useState(false)
21+
22+
if (!isMD) return null
1523

1624
return (
17-
<Portal>
18-
{/* todo: 这里可以重写移动端header 需要去掉top */}
19-
<div className="fixed inset-0 top-14 z-50 overflow-y-auto backdrop-blur-lg sm:hidden">
20-
<div className="px-4 sm:px-6 pt-3 pb-6">
21-
<nav className="flex flex-col gap-3">
22-
{navLinks.map((link) => (
23-
<div className="flex-col w-full" key={link.to}>
24-
<NavLink
25-
to={link.to}
26-
className="text-sm text-zinc-600 dark:text-slate-100 !no-underline"
25+
<>
26+
<Drawer
27+
isOpen={isMD && !!nav.expanded}
28+
onClose={() => toggleNav()}
29+
position="left"
30+
size="100%"
31+
portalClassName="[&>.bp4-overlay-container]:z-10"
32+
backdropClassName="bg-transparent"
33+
className="bg-transparent backdrop-blur-lg overflow-y-auto mt-14 p-2"
34+
>
35+
<Menu className="p-0 space-y-2 bg-transparent font-bold">
36+
{NAV_LINKS.map((link) => (
37+
<NavLink key={link.to} to={link.to} className="block !no-underline">
38+
{({ isActive }) => (
39+
<MenuItem2
40+
key={link.to}
41+
icon={link.icon}
42+
active={isActive}
43+
text={link.label}
44+
className="p-2 rounded-md"
45+
tagName="div"
2746
onClick={() => toggleNav()}
28-
>
29-
{({ isActive }) => (
30-
<Button
31-
minimal
32-
icon={link.icon}
33-
active={isActive}
34-
className="w-full flex items-center"
35-
style={{ justifyContent: 'flex-start' }}
36-
>
37-
{link.label}
38-
</Button>
39-
)}
40-
</NavLink>
41-
</div>
42-
))}
43-
</nav>
47+
/>
48+
)}
49+
</NavLink>
50+
))}
51+
<MenuDivider />
52+
<MenuItem2
53+
icon="folder-new"
54+
text="创建作业集..."
55+
className="p-2 rounded-md"
56+
onClick={() => {
57+
setShowOperationSetDialog(true)
58+
toggleNav()
59+
}}
60+
/>
61+
<AnnPanel
62+
trigger={({ handleClick }) => (
63+
<MenuItem2
64+
icon="info-sign"
65+
text="公告"
66+
className="p-2 rounded-md"
67+
onClick={handleClick}
68+
/>
69+
)}
70+
/>
71+
<MenuDivider />
72+
</Menu>
73+
<div className="flex flex-wrap leading-relaxed mt-2 p-2 section-social-links">
74+
{SOCIAL_LINKS.map((link) => (
75+
<a
76+
href={link.href}
77+
target="_blank"
78+
rel="noopener noreferrer"
79+
className="flex items-center text-zinc-600 dark:text-slate-100 no-underline"
80+
>
81+
{link.icon}
82+
<span>{link.label}</span>
83+
</a>
84+
)).reduce((prev, curr) => (
85+
<>
86+
{prev}
87+
<div className="mx-2 opacity-50">·</div>
88+
{curr}
89+
</>
90+
))}
4491
</div>
45-
</div>
46-
</Portal>
92+
</Drawer>
93+
94+
<OperationSetEditorDialog
95+
isOpen={showOperationSetDialog}
96+
onClose={() => setShowOperationSetDialog(false)}
97+
/>
98+
</>
4799
)
48100
}

src/components/viewer/OperationViewer.tsx

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -189,38 +189,33 @@ export const OperationViewer: ComponentType<{
189189

190190
<div className="flex-1" />
191191

192-
{operation.uploaderId === auth.userId && (
193-
<Popover2
194-
content={
195-
<ManageMenu
196-
operation={operation}
197-
onUpdate={() => onCloseDrawer()}
198-
/>
199-
}
200-
>
201-
<Button
202-
className="ml-4"
203-
icon="wrench"
204-
text="管理"
205-
rightIcon="caret-down"
206-
/>
207-
</Popover2>
208-
)}
209-
210-
<Button
211-
className="ml-4"
212-
icon="download"
213-
text="下载原 JSON"
214-
onClick={() => handleDownloadJSON(operation.parsedContent)}
215-
/>
192+
<div className="flex flex-wrap items-center gap-2 md:gap-4">
193+
{operation.uploaderId === auth.userId && (
194+
<Popover2
195+
content={
196+
<ManageMenu
197+
operation={operation}
198+
onUpdate={() => onCloseDrawer()}
199+
/>
200+
}
201+
>
202+
<Button icon="wrench" text="管理" rightIcon="caret-down" />
203+
</Popover2>
204+
)}
205+
206+
<Button
207+
icon="download"
208+
text="下载原 JSON"
209+
onClick={() => handleDownloadJSON(operation.parsedContent)}
210+
/>
216211

217-
<Button
218-
className="ml-4"
219-
icon="clipboard"
220-
text="复制神秘代码"
221-
intent="primary"
222-
onClick={() => copyShortCode(operation)}
223-
/>
212+
<Button
213+
icon="clipboard"
214+
text="复制神秘代码"
215+
intent="primary"
216+
onClick={() => copyShortCode(operation)}
217+
/>
218+
</div>
224219
</>
225220
}
226221
>
@@ -276,10 +271,10 @@ function OperationViewerInner({
276271
handleRating: (decision: OpRatingType) => Promise<void>
277272
}) {
278273
return (
279-
<div className="h-full overflow-auto py-4 px-8 pt-8">
274+
<div className="h-full overflow-auto p-4 md:p-8">
280275
<H3>{operation.parsedContent.doc.title}</H3>
281276

282-
<div className="grid grid-rows-1 grid-cols-3 gap-8">
277+
<div className="flex flex-col-reverse md:grid grid-rows-1 grid-cols-3 gap-2 md:gap-8">
283278
<div className="flex flex-col">
284279
<Paragraphs content={operation.parsedContent.doc.details} linkify />
285280
</div>
@@ -330,20 +325,20 @@ function OperationViewerInner({
330325
</FactItem>
331326
</div>
332327

333-
<div className="flex flex-col items-start select-none tabular-nums">
334-
<FactItem title="浏览量" icon="eye-open">
328+
<div className="flex flex-wrap md:flex-col items-start select-none tabular-nums gap-4">
329+
<FactItem dense title="浏览量" icon="eye-open">
335330
<span className="text-gray-800 dark:text-slate-100 font-bold">
336331
{operation.views}
337332
</span>
338333
</FactItem>
339334

340-
<FactItem title="发布于" icon="time">
335+
<FactItem dense title="发布于" icon="time">
341336
<span className="text-gray-800 dark:text-slate-100 font-bold">
342337
<RelativeTime moment={operation.uploadTime} />
343338
</span>
344339
</FactItem>
345340

346-
<FactItem title="作者" icon="user">
341+
<FactItem dense title="作者" icon="user">
347342
<UserName
348343
className="text-gray-800 dark:text-slate-100 font-bold"
349344
userId={operation.uploaderId}
@@ -409,7 +404,7 @@ function OperationViewerInnerDetails({ operation }: { operation: Operation }) {
409404
/>
410405
</H4>
411406
<Collapse isOpen={showOperators}>
412-
<div className="mt-2 flex flex-wrap -ml-4">
407+
<div className="mt-2 flex flex-wrap -ml-4 gap-y-2">
413408
{!operation.parsedContent.opers?.length &&
414409
!operation.parsedContent.groups?.length && (
415410
<NonIdealState
@@ -432,7 +427,7 @@ function OperationViewerInnerDetails({ operation }: { operation: Operation }) {
432427
key={group.name}
433428
>
434429
<H6 className="text-gray-800">{group.name}</H6>
435-
<div className="flex gap-1">
430+
<div className="flex flex-wrap gap-y-2">
436431
{group.opers
437432
?.filter(Boolean)
438433
.map((operator) => (

0 commit comments

Comments
 (0)