feat: chat panel UE done

This commit is contained in:
butterfly
2024-04-18 12:27:44 +08:00
parent 51a1d9f92a
commit b3559f99a2
39 changed files with 953 additions and 447 deletions

View File

@@ -1,121 +0,0 @@
import { isValidElement } from "react";
type IconMap = {
active?: JSX.Element;
inactive?: JSX.Element;
mobileActive?: JSX.Element;
mobileInactive?: JSX.Element;
};
interface Action {
id: string;
title?: string;
icons: JSX.Element | IconMap;
className?: string;
}
type Groups = {
normal: string[][];
mobile: string[][];
};
export interface TabActionsProps {
actionsShema: Action[];
onSelect: (id: string) => void;
selected: string;
groups: string[][] | Groups;
className?: string;
inMobile: boolean;
}
export default function TabActions(props: TabActionsProps) {
const { actionsShema, onSelect, selected, groups, className, inMobile } =
props;
const handlerClick = (id: string) => (e: { preventDefault: () => void }) => {
e.preventDefault();
if (selected !== id) {
onSelect?.(id);
}
};
const internalGroup = Array.isArray(groups)
? groups
: inMobile
? groups.mobile
: groups.normal;
const content = internalGroup.reduce((res, group, ind, arr) => {
res.push(
...group.map((i) => {
const action = actionsShema.find((a) => a.id === i);
if (!action) {
return <></>;
}
const { icons } = action;
let activeIcon, inactiveIcon, mobileActiveIcon, mobileInactiveIcon;
if (isValidElement(icons)) {
activeIcon = icons;
inactiveIcon = icons;
mobileActiveIcon = icons;
mobileInactiveIcon = icons;
} else {
activeIcon = (icons as IconMap).active;
inactiveIcon = (icons as IconMap).inactive;
mobileActiveIcon = (icons as IconMap).mobileActive;
mobileInactiveIcon = (icons as IconMap).mobileInactive;
}
if (inMobile) {
return (
<div
key={action.id}
className={` shrink-1 grow-0 basis-[${
(100 - 1) / arr.length
}%] flex flex-col items-center justify-center gap-0.5
${
selected === action.id
? "text-blue-700"
: "text-gray-400"
}
`}
onClick={handlerClick(action.id)}
>
{selected === action.id ? mobileActiveIcon : mobileInactiveIcon}
<div className=" leading-3 text-sm-mobile-tab h-3 font-common w-[100%]">
{action.title || " "}
</div>
</div>
);
}
return (
<div
key={action.id}
className={` ${
selected === action.id ? "bg-blue-900" : "bg-transparent"
} p-3 rounded-md items-center ${action.className}`}
onClick={handlerClick(action.id)}
>
{selected === action.id ? activeIcon : inactiveIcon}
</div>
);
}),
);
if (ind < arr.length - 1) {
res.push(<div className=" flex-1"></div>);
}
return res;
}, [] as JSX.Element[]);
return (
<div
className={`flex ${
inMobile ? "justify-around" : "flex-col"
} items-center ${className}`}
>
{content}
</div>
);
}

View File

@@ -18,8 +18,8 @@ import dynamic from "next/dynamic";
import useHotKey from "@/app/hooks/useHotKey";
import useDragSideBar from "@/app/hooks/useDragSideBar";
import useMobileScreen from "@/app/hooks/useMobileScreen";
import TabActions from "./TabActions";
import MenuWrapper from "./MenuWrapper";
import ActionsBar from "@/app/components/ActionsBar";
const SessionList = MenuWrapper(
dynamic(async () => await import("./SessionList"), {
@@ -72,7 +72,7 @@ export function SideBar(props: { className?: string }) {
return (
<div className={`${containerClassName}`}>
<TabActions
<ActionsBar
inMobile={isMobileScreen}
actionsShema={[
{
@@ -133,7 +133,9 @@ export function SideBar(props: { className?: string }) {
mobile: [[Path.Chat, Path.Masks, Path.Settings]],
}}
selected={selectedTab}
className={tabActionsClassName}
className={`${
isMobileScreen ? "justify-around" : "flex-col"
} ${tabActionsClassName}`}
/>
<SessionList