feat: 添加tabber
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 110 KiB |
BIN
projects/translate-h5/src/assets/translate/def-avatar.png
Normal file
BIN
projects/translate-h5/src/assets/translate/def-avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,11 +1,14 @@
|
|||||||
.main-layout {
|
.main-layout {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.layout-content {
|
.layout-content {
|
||||||
|
--bottom: 0;
|
||||||
|
--bottom: constant(safe-area-inset-bottom);
|
||||||
|
--bottom: env(safe-area-inset-bottom);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// padding-bottom: 150px;
|
// padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
|
||||||
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
|
// padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
|
||||||
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
|
padding-bottom: calc(var(--bottom) + 44px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-tab {
|
.layout-tab {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { NavBar, SafeArea } from "antd-mobile";
|
import { NavBar, SafeArea, TabBar } from "antd-mobile";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
import { Translate, Electrocardiogram, GithubOne, Blossom, User } from "@icon-park/react";
|
||||||
|
|
||||||
interface MainLayoutProps {
|
interface MainLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -20,30 +21,42 @@ const MainLayout: React.FC<MainLayoutProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// const location = useLocation();
|
// const location = useLocation();
|
||||||
|
const [pathname, setPathname] = React.useState(location.pathname);
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
key: "/translate",
|
||||||
|
title: "宠物翻译",
|
||||||
|
icon: <Translate />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "/translate/archives",
|
||||||
|
title: "情绪监控",
|
||||||
|
icon: <Electrocardiogram />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "/translate/mood",
|
||||||
|
title: "我的宠物",
|
||||||
|
icon: <GithubOne />,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// key: "/translate/mood",
|
||||||
|
// title: "宠物服务",
|
||||||
|
// icon: <Blossom />,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// key: "/translate/mood",
|
||||||
|
// title: "个人中心",
|
||||||
|
|
||||||
// const tabs = [
|
// icon: <User />,
|
||||||
// {
|
// },
|
||||||
// key: "/",
|
];
|
||||||
// title: "宠物翻译",
|
|
||||||
// icon: <CattleZodiac />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// key: "/set",
|
|
||||||
// title: "待办",
|
|
||||||
// icon: <User />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// key: "/message",
|
|
||||||
// title: "消息",
|
|
||||||
// icon: <User />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// key: "/me",
|
|
||||||
// title: "我的",
|
|
||||||
|
|
||||||
// icon: <User size="24" />,
|
const setRouteActive = (value: string) => {
|
||||||
// },
|
console.log(value);
|
||||||
// ];
|
|
||||||
|
setPathname(value);
|
||||||
|
navigate(value);
|
||||||
|
};
|
||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
// 打印路由栈
|
// 打印路由栈
|
||||||
@@ -68,15 +81,11 @@ const MainLayout: React.FC<MainLayoutProps> = ({
|
|||||||
<div className="layout-content">{children}</div>
|
<div className="layout-content">{children}</div>
|
||||||
|
|
||||||
<div className="footer layout-tab">
|
<div className="footer layout-tab">
|
||||||
{/* <TabBar
|
<TabBar activeKey={pathname} onChange={(value) => setRouteActive(value)} safeArea={true}>
|
||||||
activeKey={pathname}
|
|
||||||
onChange={(value) => setRouteActive(value)}
|
|
||||||
safeArea={true}
|
|
||||||
>
|
|
||||||
{tabs.map((item) => (
|
{tabs.map((item) => (
|
||||||
<TabBar.Item key={item.key} icon={item.icon} title={item.title} />
|
<TabBar.Item key={item.key} icon={item.icon} title={item.title} />
|
||||||
))}
|
))}
|
||||||
</TabBar> */}
|
</TabBar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Avatar, Divider, Space, SpinLoading, Toast } from "antd-mobile";
|
import { Avatar, Divider, Space, SpinLoading, Toast } from "antd-mobile";
|
||||||
import { VoiceIcon } from "@workspace/shared";
|
import { VoiceIcon } from "@workspace/shared";
|
||||||
import { Message } from "../../../types";
|
import { Message } from "../../../types";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
import { Refresh } from "@icon-park/react";
|
import { Refresh } from "@icon-park/react";
|
||||||
|
import DefAvatar from "@/assets/translate/def-avatar.png";
|
||||||
|
|
||||||
interface DefinedProps {
|
interface DefinedProps {
|
||||||
data: Message[];
|
data: Message[];
|
||||||
@@ -48,7 +49,7 @@ function Index(props: DefinedProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderAvatar = (item: Message) => {
|
const renderAvatar = (item: Message) => {
|
||||||
return <Avatar src={item.petAvatar || ""} style={{ "--border-radius": "32px" }} />;
|
return <Avatar src={item.petAvatar || DefAvatar} style={{ "--border-radius": "32px" }} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshMessage = async (messageId: number, e: React.MouseEvent) => {
|
const refreshMessage = async (messageId: number, e: React.MouseEvent) => {
|
||||||
@@ -107,7 +108,10 @@ function Index(props: DefinedProps) {
|
|||||||
<span className="name">
|
<span className="name">
|
||||||
{item.isTranslating && !item.isRefresh ? "" : item.petName ?? "未知宠物"}
|
{item.isTranslating && !item.isRefresh ? "" : item.petName ?? "未知宠物"}
|
||||||
</span>
|
</span>
|
||||||
<Divider direction="vertical" style={{ margin: "0px 8px" }} />
|
|
||||||
|
{!(item.isTranslating && !item.isRefresh) && (
|
||||||
|
<Divider direction="vertical" style={{ margin: "0px 8px" }} />
|
||||||
|
)}
|
||||||
<span className="">{item.createTime}</span>
|
<span className="">{item.createTime}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="voice-container" onClick={() => playAudio(item.id, item.contentText)}>
|
<div className="voice-container" onClick={() => playAudio(item.id, item.contentText)}>
|
||||||
@@ -122,7 +126,7 @@ function Index(props: DefinedProps) {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<div style={{ height: "80px", width: "100%" }}></div>
|
<div style={{ height: "130px", width: "100%" }}></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { Image, Toast } from "antd-mobile";
|
import { Image, Toast } from "antd-mobile";
|
||||||
import MessageCom from "./component/message";
|
import MessageCom from "./component/message";
|
||||||
import VoiceRecord from "./component/voice";
|
import VoiceRecord from "./component/voice";
|
||||||
@@ -35,6 +35,15 @@ function Index(props: DefinedProps) {
|
|||||||
const [visible, setVisible] = useState<boolean>(false);
|
const [visible, setVisible] = useState<boolean>(false);
|
||||||
const [dialogId, setDialogId] = useState<number>(0);
|
const [dialogId, setDialogId] = useState<number>(0);
|
||||||
|
|
||||||
|
// 创建稳定化的消息字符串(排除 isTranslating 字段变化的影响)
|
||||||
|
const stableMessagesString = useMemo(() => {
|
||||||
|
const stableMessages = messages.map((msg) => {
|
||||||
|
const { isTranslating, isRefresh, ...rest } = msg;
|
||||||
|
return rest;
|
||||||
|
});
|
||||||
|
return JSON.stringify(stableMessages);
|
||||||
|
}, [messages]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentLanguage(menuItems[0]);
|
setCurrentLanguage(menuItems[0]);
|
||||||
fetchInitialMessages();
|
fetchInitialMessages();
|
||||||
@@ -75,7 +84,7 @@ function Index(props: DefinedProps) {
|
|||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [messages, scrollToBottom]);
|
}, [stableMessagesString, scrollToBottom]);
|
||||||
|
|
||||||
//完成录音
|
//完成录音
|
||||||
const onRecordingComplete = useCallback(
|
const onRecordingComplete = useCallback(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default defineConfig({
|
|||||||
// basicSsl()
|
// basicSsl()
|
||||||
// target: "https://petshy.tashowz.com",
|
// target: "https://petshy.tashowz.com",
|
||||||
// http://192.168.1.231:48080
|
// http://192.168.1.231:48080
|
||||||
plugins: [react(), basicSsl()],
|
plugins: [react()],
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user