refactor: change web login position (#971)

* refactor: change web login position

* refactor: update
This commit is contained in:
ayangweb
2025-11-08 21:02:04 +08:00
committed by GitHub
parent 01dfc616d4
commit 1fdf7c499d
8 changed files with 40 additions and 29 deletions

View File

@@ -10,6 +10,7 @@ import { HISTORY_PANEL_ID } from "@/constants";
import { AssistantList } from "./AssistantList"; import { AssistantList } from "./AssistantList";
import { ServerList } from "./ServerList"; import { ServerList } from "./ServerList";
import TogglePin from "../Common/TogglePin"; import TogglePin from "../Common/TogglePin";
import WebLogin from "../WebLogin";
interface ChatHeaderProps { interface ChatHeaderProps {
clearChat: () => void; clearChat: () => void;
@@ -63,7 +64,7 @@ export function ChatHeader({
<AssistantList assistantIDs={assistantIDs} /> <AssistantList assistantIDs={assistantIDs} />
{showChatHistory ? ( {showChatHistory && (
<button <button
onClick={clearChat} onClick={clearChat}
className="p-2 py-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800" className="p-2 py-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
@@ -76,7 +77,7 @@ export function ChatHeader({
<MessageSquarePlus className="h-4 w-4 relative top-0.5" /> <MessageSquarePlus className="h-4 w-4 relative top-0.5" />
</VisibleKey> </VisibleKey>
</button> </button>
) : null} )}
</div> </div>
<h2 className="max-w-[calc(100%-200px)] text-sm font-medium text-gray-900 dark:text-gray-100 truncate"> <h2 className="max-w-[calc(100%-200px)] text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
@@ -100,7 +101,7 @@ export function ChatHeader({
)} )}
</div> </div>
) : ( ) : (
<div /> <WebLogin panelClassName="top-8 right-0" />
)} )}
</header> </header>
); );

View File

@@ -16,7 +16,7 @@ import { useThemeStore } from "@/stores/themeStore";
import platformAdapter from "@/utils/platformAdapter"; import platformAdapter from "@/utils/platformAdapter";
import FontIcon from "../Icons/FontIcon"; import FontIcon from "../Icons/FontIcon";
import TogglePin from "../TogglePin"; import TogglePin from "../TogglePin";
import WebFooter from "./WebFooter"; import WebLogin from "@/components/WebLogin";
interface FooterProps { interface FooterProps {
setIsPinnedWeb?: (value: boolean) => void; setIsPinnedWeb?: (value: boolean) => void;
@@ -137,7 +137,7 @@ export default function Footer({ setIsPinnedWeb }: FooterProps) {
</div> </div>
</div> </div>
) : ( ) : (
<WebFooter /> <WebLogin panelClassName="bottom-5 left-0" />
)} )}
<div className={`flex mobile:hidden items-center gap-3`}> <div className={`flex mobile:hidden items-center gap-3`}>

View File

@@ -6,8 +6,8 @@ import clsx from "clsx";
import { formatKey } from "@/utils/keyboardUtils"; import { formatKey } from "@/utils/keyboardUtils";
import SearchEmpty from "../SearchEmpty"; import SearchEmpty from "../SearchEmpty";
import FontIcon from "../Icons/FontIcon"; import FontIcon from "../Icons/FontIcon";
import WebLoginButton from "./WebLoginButton"; import WebLoginButton from "@/components/WebLogin/LoginButton";
import WebRefreshButton from "./WebRefreshButton"; import WebRefreshButton from "@/components/WebLogin/RefreshButton";
import { useWebConfigStore } from "@/stores/webConfigStore"; import { useWebConfigStore } from "@/stores/webConfigStore";
import { useAppStore } from "@/stores/appStore"; import { useAppStore } from "@/stores/appStore";

View File

@@ -16,7 +16,6 @@ import { useSearchStore } from "@/stores/searchStore";
import { useExtensionsStore } from "@/stores/extensionsStore"; import { useExtensionsStore } from "@/stores/extensionsStore";
import { parseSearchQuery, SearchQuery } from "@/utils"; import { parseSearchQuery, SearchQuery } from "@/utils";
import InputUpload from "./InputUpload"; import InputUpload from "./InputUpload";
import WebFooter from "../Common/UI/WebFooter";
import Copyright from "../Common/Copyright"; import Copyright from "../Common/Copyright";
interface InputControlsProps { interface InputControlsProps {
@@ -238,7 +237,7 @@ const InputControls = ({
(source?.type !== "deep_think" || !source?.config?.visible) && (source?.type !== "deep_think" || !source?.config?.visible) &&
!(source?.mcp_servers?.enabled && source?.mcp_servers?.visible) && ( !(source?.mcp_servers?.enabled && source?.mcp_servers?.visible) && (
<div className="px-[9px]"> <div className="px-[9px]">
{isTauri ? <Copyright /> : <WebFooter />} <Copyright />
</div> </div>
)} )}
</div> </div>

View File

@@ -3,7 +3,7 @@ import { Button } from "@headlessui/react";
import { SquareArrowOutUpRight } from "lucide-react"; import { SquareArrowOutUpRight } from "lucide-react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
const WebLoginButton = () => { const LoginButton = () => {
const { endpoint } = useAppStore(); const { endpoint } = useAppStore();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -23,4 +23,4 @@ const WebLoginButton = () => {
); );
}; };
export default WebLoginButton; export default LoginButton;

View File

@@ -3,10 +3,10 @@ import { FC, useState } from "react";
import { Button, ButtonProps } from "@headlessui/react"; import { Button, ButtonProps } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
import VisibleKey from "../VisibleKey";
import { useWebConfigStore } from "@/stores/webConfigStore"; import { useWebConfigStore } from "@/stores/webConfigStore";
import VisibleKey from "../Common/VisibleKey";
const WebRefreshButton: FC<ButtonProps> = (props) => { const RefreshButton: FC<ButtonProps> = (props) => {
const { className, ...rest } = props; const { className, ...rest } = props;
const [isRefreshing, setIsRefreshing] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false);
const { onRefresh } = useWebConfigStore(); const { onRefresh } = useWebConfigStore();
@@ -45,4 +45,4 @@ const WebRefreshButton: FC<ButtonProps> = (props) => {
); );
}; };
export default WebRefreshButton; export default RefreshButton;

View File

@@ -2,11 +2,11 @@ import clsx from "clsx";
import { LucideProps, User } from "lucide-react"; import { LucideProps, User } from "lucide-react";
import { FC, HTMLAttributes } from "react"; import { FC, HTMLAttributes } from "react";
interface WebUserAvatarProps extends HTMLAttributes<HTMLDivElement> { interface UserAvatarProps extends HTMLAttributes<HTMLDivElement> {
icon?: LucideProps; icon?: LucideProps;
} }
const WebUserAvatar: FC<WebUserAvatarProps> = (props) => { const UserAvatar: FC<UserAvatarProps> = (props) => {
const { className, icon } = props; const { className, icon } = props;
return ( return (
@@ -21,4 +21,4 @@ const WebUserAvatar: FC<WebUserAvatarProps> = (props) => {
); );
}; };
export default WebUserAvatar; export default UserAvatar;

View File

@@ -1,16 +1,22 @@
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react"; import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
import FontIcon from "../Icons/FontIcon";
import { useWebConfigStore } from "@/stores/webConfigStore"; import { useWebConfigStore } from "@/stores/webConfigStore";
import { LogOut } from "lucide-react"; import { LogOut } from "lucide-react";
import clsx from "clsx"; import clsx from "clsx";
import Copyright from "../Copyright";
import WebLoginButton from "./WebLoginButton";
import WebRefreshButton from "./WebRefreshButton";
import WebUserAvatar from "./WebUserAvatar";
import { Post } from "@/api/axiosRequest"; import { Post } from "@/api/axiosRequest";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import UserAvatar from "./UserAvatar";
import FontIcon from "../Common/Icons/FontIcon";
import RefreshButton from "./RefreshButton";
import LoginButton from "./LoginButton";
import { FC } from "react";
import Copyright from "../Common/Copyright";
const WebFooter = () => { interface WebLoginProps {
panelClassName: string;
}
const WebLogin: FC<WebLoginProps> = (props) => {
const { panelClassName } = props;
const { integration, loginInfo, setIntegration, setLoginInfo } = const { integration, loginInfo, setIntegration, setLoginInfo } =
useWebConfigStore(); useWebConfigStore();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -20,7 +26,7 @@ const WebFooter = () => {
<Popover> <Popover>
<PopoverButton> <PopoverButton>
{loginInfo ? ( {loginInfo ? (
<WebUserAvatar /> <UserAvatar />
) : ( ) : (
<FontIcon <FontIcon
name="font_coco-logo-line" name="font_coco-logo-line"
@@ -29,19 +35,24 @@ const WebFooter = () => {
)} )}
</PopoverButton> </PopoverButton>
<PopoverPanel className="absolute z-50 bottom-5 left-0 w-[300px] rounded-xl bg-white dark:bg-[#202126] text-sm/6 text-[#333] dark:text-[#D8D8D8] shadow-lg border dark:border-white/10 -translate-y-2"> <PopoverPanel
className={clsx(
"absolute z-50 w-[300px] rounded-xl bg-white dark:bg-[#202126] text-sm/6 text-[#333] dark:text-[#D8D8D8] shadow-lg border dark:border-white/10 -translate-y-2",
panelClassName
)}
>
<div className="p-3"> <div className="p-3">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<span>{t("webLogin.title")}</span> <span>{t("webLogin.title")}</span>
<WebRefreshButton /> <RefreshButton />
</div> </div>
<div className="py-2"> <div className="py-2">
{loginInfo ? ( {loginInfo ? (
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<WebUserAvatar <UserAvatar
className="!size-12" className="!size-12"
icon={{ className: "!size-6" }} icon={{ className: "!size-6" }}
/> />
@@ -76,7 +87,7 @@ const WebFooter = () => {
: t("webLogin.hints.login")} : t("webLogin.hints.login")}
</span> </span>
<WebLoginButton /> <LoginButton />
</div> </div>
)} )}
</div> </div>
@@ -91,4 +102,4 @@ const WebFooter = () => {
); );
}; };
export default WebFooter; export default WebLogin;