mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
fix: 终端字符宽度&微调样式&路由切换动画
This commit is contained in:
@@ -187,7 +187,7 @@ export default function AudioPlayer(props: AudioPlayerProps) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'fixed right-0 bottom-0 z-[9999] w-full md:w-96',
|
'fixed right-0 bottom-0 z-[52] w-full md:w-96',
|
||||||
!translateX && !translateY && 'transition-transform',
|
!translateX && !translateY && 'transition-transform',
|
||||||
isCollapsed && 'md:hover:!translate-x-80'
|
isCollapsed && 'md:hover:!translate-x-80'
|
||||||
)}
|
)}
|
||||||
|
@@ -19,12 +19,6 @@ loader.config({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
loader.config({
|
|
||||||
'vs/nls': {
|
|
||||||
availableLanguages: { '*': 'zh-cn' }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export interface CodeEditorProps extends React.ComponentProps<typeof Editor> {
|
export interface CodeEditorProps extends React.ComponentProps<typeof Editor> {
|
||||||
test?: string
|
test?: string
|
||||||
}
|
}
|
||||||
|
@@ -1125,7 +1125,7 @@ export const WebUIIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1173,7 +1173,7 @@ export const WebUIIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1220,7 +1220,7 @@ export const WebUIIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1270,7 +1270,7 @@ export const WebUIIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1320,7 +1320,7 @@ export const WebUIIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1372,7 +1372,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1422,7 +1422,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1469,7 +1469,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1519,7 +1519,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1566,7 +1566,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1613,7 +1613,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1660,7 +1660,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
@@ -1707,7 +1707,7 @@ export const BietiaopIcon = (props: IconSvgProps) => (
|
|||||||
>
|
>
|
||||||
<g
|
<g
|
||||||
id="svgGroup"
|
id="svgGroup"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
style={{
|
style={{
|
||||||
|
@@ -50,8 +50,8 @@ const Modal: React.FC<ModalProps> = React.memo((props) => {
|
|||||||
onNativeClose()
|
onNativeClose()
|
||||||
}}
|
}}
|
||||||
classNames={{
|
classNames={{
|
||||||
backdrop: 'z-[99999999]',
|
backdrop: 'z-[99]',
|
||||||
wrapper: 'z-[999999999]'
|
wrapper: 'z-[99]'
|
||||||
}}
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
|
@@ -4,7 +4,7 @@ import { Input } from '@heroui/input'
|
|||||||
import { Snippet } from '@heroui/snippet'
|
import { Snippet } from '@heroui/snippet'
|
||||||
import { useLocalStorage } from '@uidotdev/usehooks'
|
import { useLocalStorage } from '@uidotdev/usehooks'
|
||||||
import { motion } from 'motion/react'
|
import { motion } from 'motion/react'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import { IoLink, IoSend } from 'react-icons/io5'
|
import { IoLink, IoSend } from 'react-icons/io5'
|
||||||
import { PiCatDuotone } from 'react-icons/pi'
|
import { PiCatDuotone } from 'react-icons/pi'
|
||||||
@@ -41,6 +41,7 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
const [isCodeEditorOpen, setIsCodeEditorOpen] = useState(false)
|
const [isCodeEditorOpen, setIsCodeEditorOpen] = useState(false)
|
||||||
const [isResponseOpen, setIsResponseOpen] = useState(false)
|
const [isResponseOpen, setIsResponseOpen] = useState(false)
|
||||||
const [isFetching, setIsFetching] = useState(false)
|
const [isFetching, setIsFetching] = useState(false)
|
||||||
|
const responseRef = useRef<HTMLDivElement>(null)
|
||||||
const parsedRequest = parse(data.request)
|
const parsedRequest = parse(data.request)
|
||||||
const parsedResponse = parse(data.response)
|
const parsedResponse = parse(data.response)
|
||||||
|
|
||||||
@@ -69,6 +70,11 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setIsFetching(false)
|
setIsFetching(false)
|
||||||
|
setIsResponseOpen(true)
|
||||||
|
responseRef.current?.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start'
|
||||||
|
})
|
||||||
toast.dismiss(r)
|
toast.dismiss(r)
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -84,8 +90,8 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
}, [path])
|
}, [path])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 overflow-y-auto p-4 rounded-lg shadow-md">
|
<section className="p-4 pt-14 rounded-lg shadow-md">
|
||||||
<h1 className="text-2xl font-bold mb-4 flex items-center gap-1 text-danger-400 ">
|
<h1 className="text-2xl font-bold mb-4 flex items-center gap-1 text-danger-400">
|
||||||
<PiCatDuotone />
|
<PiCatDuotone />
|
||||||
{data.description}
|
{data.description}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -93,6 +99,9 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
<Snippet
|
<Snippet
|
||||||
className="bg-default-50 bg-opacity-50 backdrop-blur-md"
|
className="bg-default-50 bg-opacity-50 backdrop-blur-md"
|
||||||
symbol={<IoLink size={18} className="inline-block mr-1" />}
|
symbol={<IoLink size={18} className="inline-block mr-1" />}
|
||||||
|
tooltipProps={{
|
||||||
|
content: '点击复制地址'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{path}
|
{path}
|
||||||
</Snippet>
|
</Snippet>
|
||||||
@@ -125,7 +134,10 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
<IoSend />
|
<IoSend />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Card shadow="sm" className="my-4 bg-opacity-50 backdrop-blur-md">
|
<Card
|
||||||
|
shadow="sm"
|
||||||
|
className="my-4 bg-opacity-50 backdrop-blur-md overflow-visible z-20"
|
||||||
|
>
|
||||||
<CardHeader className="font-noto-serif font-bold text-lg gap-1 pb-0">
|
<CardHeader className="font-noto-serif font-bold text-lg gap-1 pb-0">
|
||||||
<span className="mr-2">请求体</span>
|
<span className="mr-2">请求体</span>
|
||||||
<Button
|
<Button
|
||||||
@@ -140,7 +152,7 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="overflow-hidden"
|
ref={responseRef}
|
||||||
initial={{ opacity: 0, height: 0 }}
|
initial={{ opacity: 0, height: 0 }}
|
||||||
animate={{
|
animate={{
|
||||||
opacity: isCodeEditorOpen ? 1 : 0,
|
opacity: isCodeEditorOpen ? 1 : 0,
|
||||||
@@ -223,7 +235,7 @@ const OneBotApiDebug: React.FC<OneBotApiDebugProps> = (props) => {
|
|||||||
<h2 className="text-xl font-semibold mt-4 mb-2">响应体结构</h2>
|
<h2 className="text-xl font-semibold mt-4 mb-2">响应体结构</h2>
|
||||||
<DisplayStruct schema={parsedResponse} />
|
<DisplayStruct schema={parsedResponse} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,9 +19,8 @@ const OneBotApiNavList: React.FC<OneBotApiNavListProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'flex-shrink-0 absolute md:!top-0 md:bottom-0 left-0 !overflow-hidden md:relative md:w-auto z-20',
|
'h-[calc(100vh-3.5rem)] left-0 !overflow-hidden md:w-auto z-20 top-[3.3rem] md:top-[3rem] absolute md:sticky md:float-start',
|
||||||
openSideBar &&
|
openSideBar && 'bg-background bg-opacity-20 backdrop-blur-md'
|
||||||
'bottom-8 z-10 bg-background bg-opacity-20 backdrop-blur-md top-14'
|
|
||||||
)}
|
)}
|
||||||
initial={{ width: 0 }}
|
initial={{ width: 0 }}
|
||||||
transition={{
|
transition={{
|
||||||
@@ -32,7 +31,7 @@ const OneBotApiNavList: React.FC<OneBotApiNavListProps> = (props) => {
|
|||||||
animate={{ width: openSideBar ? '16rem' : '0rem' }}
|
animate={{ width: openSideBar ? '16rem' : '0rem' }}
|
||||||
style={{ overflowY: openSideBar ? 'auto' : 'hidden' }}
|
style={{ overflowY: openSideBar ? 'auto' : 'hidden' }}
|
||||||
>
|
>
|
||||||
<div className="w-64 h-full overflow-y-auto px-2 float-right">
|
<div className="w-64 h-full overflow-y-auto px-2 pt-2 pb-10 md:pb-0">
|
||||||
<Input
|
<Input
|
||||||
className="sticky top-0 z-10 text-danger-600"
|
className="sticky top-0 z-10 text-danger-600"
|
||||||
classNames={{
|
classNames={{
|
||||||
|
@@ -10,6 +10,7 @@ import {
|
|||||||
import { useCallback, useRef } from 'react'
|
import { useCallback, useRef } from 'react'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
|
import ChatInputModal from '@/components/chat_input/modal'
|
||||||
import CodeEditor from '@/components/code_editor'
|
import CodeEditor from '@/components/code_editor'
|
||||||
import type { CodeEditorRef } from '@/components/code_editor'
|
import type { CodeEditorRef } from '@/components/code_editor'
|
||||||
|
|
||||||
@@ -72,6 +73,8 @@ const OneBotSendModal: React.FC<OneBotSendModalProps> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
|
<ChatInputModal />
|
||||||
|
|
||||||
<Button color="danger" variant="flat" onPress={onClose}>
|
<Button color="danger" variant="flat" onPress={onClose}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -36,7 +36,9 @@ const XTerm = forwardRef<XTermRef, React.HTMLAttributes<HTMLDivElement>>(
|
|||||||
allowTransparency: true,
|
allowTransparency: true,
|
||||||
fontFamily: '"Fira Code", "Harmony", "Noto Serif SC", monospace',
|
fontFamily: '"Fira Code", "Harmony", "Noto Serif SC", monospace',
|
||||||
cursorInactiveStyle: 'outline',
|
cursorInactiveStyle: 'outline',
|
||||||
drawBoldTextInBrightColors: false
|
drawBoldTextInBrightColors: false,
|
||||||
|
letterSpacing: 0,
|
||||||
|
lineHeight: 1.0
|
||||||
})
|
})
|
||||||
terminalRef.current = terminal
|
terminalRef.current = terminal
|
||||||
const fitAddon = new FitAddon()
|
const fitAddon = new FitAddon()
|
||||||
@@ -51,10 +53,6 @@ const XTerm = forwardRef<XTermRef, React.HTMLAttributes<HTMLDivElement>>(
|
|||||||
terminal.loadAddon(new WebglAddon())
|
terminal.loadAddon(new WebglAddon())
|
||||||
terminal.open(domRef.current)
|
terminal.open(domRef.current)
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
fitAddon.fit()
|
|
||||||
}, 0)
|
|
||||||
|
|
||||||
terminal.writeln(
|
terminal.writeln(
|
||||||
gradientText(
|
gradientText(
|
||||||
'Welcome to NapCat WebUI',
|
'Welcome to NapCat WebUI',
|
||||||
@@ -69,16 +67,16 @@ const XTerm = forwardRef<XTermRef, React.HTMLAttributes<HTMLDivElement>>(
|
|||||||
const resizeObserver = new ResizeObserver(() => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
fitAddon.fit()
|
fitAddon.fit()
|
||||||
})
|
})
|
||||||
resizeObserver.observe(domRef.current)
|
|
||||||
|
|
||||||
const handleFontLoad = () => {
|
// 字体加载完成后重新调整终端大小
|
||||||
terminal.refresh(0, terminal.rows - 1)
|
document.fonts.ready.then(() => {
|
||||||
}
|
fitAddon.fit()
|
||||||
document.fonts.addEventListener('loadingdone', handleFontLoad)
|
|
||||||
|
resizeObserver.observe(domRef.current!)
|
||||||
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
resizeObserver.disconnect()
|
resizeObserver.disconnect()
|
||||||
document.fonts.removeEventListener('loadingdone', handleFontLoad)
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
terminal.dispose()
|
terminal.dispose()
|
||||||
}, 0)
|
}, 0)
|
||||||
|
@@ -2,7 +2,7 @@ import { BreadcrumbItem, Breadcrumbs } from '@heroui/breadcrumbs'
|
|||||||
import { Button } from '@heroui/button'
|
import { Button } from '@heroui/button'
|
||||||
import { useLocalStorage } from '@uidotdev/usehooks'
|
import { useLocalStorage } from '@uidotdev/usehooks'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { motion } from 'motion/react'
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import { useEffect, useMemo, useRef } from 'react'
|
import { useEffect, useMemo, useRef } from 'react'
|
||||||
import { ErrorBoundary } from 'react-error-boundary'
|
import { ErrorBoundary } from 'react-error-boundary'
|
||||||
import { MdMenu, MdMenuOpen } from 'react-icons/md'
|
import { MdMenu, MdMenuOpen } from 'react-icons/md'
|
||||||
@@ -79,7 +79,7 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
}, [location.pathname])
|
}, [location.pathname])
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="h-screen relative flex bg-danger-50 dark:bg-black"
|
className="h-screen relative flex bg-danger-50 dark:bg-black items-stretch"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url(${b64img})`,
|
backgroundImage: `url(${b64img})`,
|
||||||
backgroundSize: 'cover'
|
backgroundSize: 'cover'
|
||||||
@@ -89,13 +89,22 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
<div
|
<div
|
||||||
ref={contentRef}
|
ref={contentRef}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'overflow-y-auto relative flex-1 rounded-md m-1 bg-content1 pb-10 md:pb-0',
|
'overflow-y-auto flex-1 rounded-md m-1 bg-content1 pb-10 md:pb-0',
|
||||||
openSideBar ? 'ml-0' : 'ml-1',
|
openSideBar ? 'ml-0' : 'ml-1',
|
||||||
!b64img && 'shadow-inner',
|
!b64img && 'shadow-inner',
|
||||||
b64img && '!bg-opacity-50 backdrop-blur-none dark:bg-background'
|
b64img && '!bg-opacity-50 backdrop-blur-none dark:bg-background',
|
||||||
|
'overflow-x-hidden'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'h-10 flex items-center hm-medium text-xl backdrop-blur-lg rounded-full',
|
||||||
|
'dark:bg-background dark:shadow-danger-100',
|
||||||
|
'bg-background !bg-opacity-50',
|
||||||
|
'shadow-sm shadow-danger-50',
|
||||||
|
'z-30 m-2 mb-0 sticky top-2 left-0'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="h-10 flex items-center hm-medium text-xl sticky top-2 left-0 backdrop-blur-lg z-20 shadow-sm bg-background dark:bg-background shadow-danger-50 dark:shadow-danger-100 m-2 rounded-full !bg-opacity-50">
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'mr-1 ease-in-out ml-0 md:relative',
|
'mr-1 ease-in-out ml-0 md:relative',
|
||||||
@@ -117,7 +126,19 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
<Breadcrumbs isDisabled size="lg">
|
<Breadcrumbs isDisabled size="lg">
|
||||||
{title?.map((item, index) => (
|
{title?.map((item, index) => (
|
||||||
<BreadcrumbItem key={index}>{item}</BreadcrumbItem>
|
<BreadcrumbItem key={index}>
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<motion.div
|
||||||
|
key={item}
|
||||||
|
initial={{ opacity: 0, y: -10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: 10 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</motion.div>
|
||||||
|
</AnimatePresence>
|
||||||
|
</BreadcrumbItem>
|
||||||
))}
|
))}
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -27,19 +27,15 @@ export default function HttpDebug() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<title>HTTP调试 - NapCat WebUI</title>
|
<title>HTTP调试 - NapCat WebUI</title>
|
||||||
<div className="w-full h-[calc(100%-3.6rem)] flex items-stretch">
|
|
||||||
<OneBotApiNavList
|
<OneBotApiNavList
|
||||||
data={oneBotHttpApi}
|
data={oneBotHttpApi}
|
||||||
selectedApi={selectedApi}
|
selectedApi={selectedApi}
|
||||||
onSelect={setSelectedApi}
|
onSelect={setSelectedApi}
|
||||||
openSideBar={openSideBar}
|
openSideBar={openSideBar}
|
||||||
/>
|
/>
|
||||||
<div
|
<div ref={contentRef} className="flex-1 h-full overflow-x-hidden">
|
||||||
ref={contentRef}
|
|
||||||
className="flex-1 h-full overflow-x-hidden relative"
|
|
||||||
>
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className="sticky top-0 z-20 md:!ml-4"
|
className="absolute top-16 z-30 md:!ml-4"
|
||||||
animate={{ marginLeft: openSideBar ? '16rem' : '1rem' }}
|
animate={{ marginLeft: openSideBar ? '16rem' : '1rem' }}
|
||||||
transition={{ type: 'spring', stiffness: 150, damping: 15 }}
|
transition={{ type: 'spring', stiffness: 150, damping: 15 }}
|
||||||
>
|
>
|
||||||
@@ -62,7 +58,6 @@ export default function HttpDebug() {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
<OneBotApiDebug path={selectedApi} data={data} />
|
<OneBotApiDebug path={selectedApi} data={data} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,6 @@ import toast from 'react-hot-toast'
|
|||||||
|
|
||||||
import key from '@/const/key'
|
import key from '@/const/key'
|
||||||
|
|
||||||
import ChatInputModal from '@/components/chat_input/modal'
|
|
||||||
import OneBotMessageList from '@/components/onebot/message_list'
|
import OneBotMessageList from '@/components/onebot/message_list'
|
||||||
import OneBotSendModal from '@/components/onebot/send_modal'
|
import OneBotSendModal from '@/components/onebot/send_modal'
|
||||||
import WSStatus from '@/components/onebot/ws_status'
|
import WSStatus from '@/components/onebot/ws_status'
|
||||||
@@ -82,7 +81,6 @@ export default function WSDebug() {
|
|||||||
{FilterMessagesType}
|
{FilterMessagesType}
|
||||||
</div>
|
</div>
|
||||||
<OneBotSendModal sendMessage={sendMessage} />
|
<OneBotSendModal sendMessage={sendMessage} />
|
||||||
<ChatInputModal />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { Route, Routes } from 'react-router-dom'
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
|
import { Route, Routes, useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
import DefaultLayout from '@/layouts/default'
|
import DefaultLayout from '@/layouts/default'
|
||||||
|
|
||||||
@@ -12,9 +13,18 @@ import LogsPage from './dashboard/logs'
|
|||||||
import NetworkPage from './dashboard/network'
|
import NetworkPage from './dashboard/network'
|
||||||
|
|
||||||
export default function IndexPage() {
|
export default function IndexPage() {
|
||||||
|
const location = useLocation()
|
||||||
return (
|
return (
|
||||||
<DefaultLayout>
|
<DefaultLayout>
|
||||||
<Routes>
|
<AnimatePresence mode="wait">
|
||||||
|
<motion.div
|
||||||
|
key={location.pathname}
|
||||||
|
initial={{ opacity: 0, y: 50 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -50 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
>
|
||||||
|
<Routes location={location} key={location.pathname}>
|
||||||
<Route element={<DashboardIndexPage />} path="/" />
|
<Route element={<DashboardIndexPage />} path="/" />
|
||||||
<Route element={<NetworkPage />} path="/network" />
|
<Route element={<NetworkPage />} path="/network" />
|
||||||
<Route element={<ConfigPage />} path="/config" />
|
<Route element={<ConfigPage />} path="/config" />
|
||||||
@@ -25,6 +35,8 @@ export default function IndexPage() {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route element={<AboutPage />} path="/about" />
|
<Route element={<AboutPage />} path="/about" />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</motion.div>
|
||||||
|
</AnimatePresence>
|
||||||
</DefaultLayout>
|
</DefaultLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,7 @@ body {
|
|||||||
-moz-border-radius: 2em;
|
-moz-border-radius: 2em;
|
||||||
border-radius: 2em;
|
border-radius: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-editor {
|
.monaco-editor {
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
@@ -75,6 +76,10 @@ body {
|
|||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.context-view.monaco-menu-container * {
|
||||||
|
font-family: PingFang SC,"Harmony",Helvetica Neue,Microsoft YaHei,sans-serif !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ql-hidden {
|
.ql-hidden {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user