mirror of
https://github.com/coaidev/coai.git
synced 2025-05-26 00:10:15 +09:00
feat: optimize sharing feature, add mobile adapter, add maximized screen and minized screen feature
This commit is contained in:
parent
e05b181047
commit
98cf701ff6
@ -3,7 +3,6 @@
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 56px);
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.loading {
|
||||
@ -127,6 +126,17 @@
|
||||
.shot-content {
|
||||
padding: 2rem;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
@media (max-width: 520px) {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.message-toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& > * {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
@ -151,6 +161,18 @@
|
||||
width: 80vw;
|
||||
height: 70vh;
|
||||
background: hsl(var(--background));
|
||||
transition: 0.25s;
|
||||
|
||||
.message-toolbar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&.maximized {
|
||||
width: 100vw;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
@ -226,7 +248,8 @@
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 6px;
|
||||
padding: 0.75rem 1.5rem 1rem;
|
||||
padding: 1.25rem 1rem;
|
||||
border-top: 1px solid hsl(var(--border));
|
||||
|
||||
button {
|
||||
white-space: nowrap;
|
||||
|
@ -35,6 +35,7 @@ type MessageProps = {
|
||||
end?: boolean;
|
||||
onEvent?: (event: string, index?: number, message?: string) => void;
|
||||
ref?: Ref<HTMLElement>;
|
||||
sharing?: boolean;
|
||||
};
|
||||
|
||||
function MessageSegment(props: MessageProps) {
|
||||
|
@ -50,7 +50,7 @@ function ModelUsageChart({ labels, datasets }: ModelChartProps) {
|
||||
const categories = useMemo(() => {
|
||||
return chart.map(
|
||||
(item) => `${item.name} (${getReadableNumber(item.value, 1)})`,
|
||||
)
|
||||
);
|
||||
}, [chart]);
|
||||
|
||||
type CustomTooltipTypeDonut = {
|
||||
@ -104,6 +104,7 @@ function ModelUsageChart({ labels, datasets }: ModelChartProps) {
|
||||
showAnimation={true}
|
||||
valueFormatter={(value) => getReadableNumber(value, 1)}
|
||||
customTooltip={customTooltip}
|
||||
colors={chart.map((item) => getModelColor(item.name))}
|
||||
/>
|
||||
<Legend
|
||||
className={`common-chart p-2 w-[50%] z-0`}
|
||||
|
@ -1,16 +1,17 @@
|
||||
import "@/assets/pages/sharing.less";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { viewConversation, ViewData, ViewForm } from "@/api/sharing.ts";
|
||||
import { copyClipboard, saveImageAsFile } from "@/utils/dom.ts";
|
||||
import { saveImageAsFile } from "@/utils/dom.ts";
|
||||
import { useEffectAsync } from "@/utils/hook.ts";
|
||||
import { useRef, useState } from "react";
|
||||
import {
|
||||
Clock,
|
||||
Copy,
|
||||
HelpCircle,
|
||||
Image,
|
||||
Loader2,
|
||||
Maximize,
|
||||
MessagesSquare,
|
||||
Minimize,
|
||||
Newspaper,
|
||||
} from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@ -24,6 +25,8 @@ import Avatar from "@/components/Avatar.tsx";
|
||||
import { toJpeg } from "html-to-image";
|
||||
import { appLogo } from "@/conf/env.ts";
|
||||
import { extractMessage } from "@/utils/processor.ts";
|
||||
import { cn } from "@/components/ui/lib/utils.ts";
|
||||
import { useMobile } from "@/utils/device.ts";
|
||||
|
||||
type SharingFormProps = {
|
||||
refer?: string;
|
||||
@ -35,13 +38,13 @@ function SharingForm({ refer, data }: SharingFormProps) {
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const mobile = useMobile();
|
||||
const [maximized, setMaximized] = useState(false);
|
||||
const container = useRef<HTMLDivElement>(null);
|
||||
const date = new Date(data.time);
|
||||
const time = `${
|
||||
date.getMonth() + 1
|
||||
}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`;
|
||||
const value = JSON.stringify(data, null, 2);
|
||||
|
||||
const saveImage = async () => {
|
||||
toast({
|
||||
title: t("message.saving-image-prompt"),
|
||||
@ -68,7 +71,7 @@ function SharingForm({ refer, data }: SharingFormProps) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`sharing-container`}>
|
||||
<div className={cn("sharing-container", maximized && "maximized")}>
|
||||
<div className={`sharing-screenshot`}>
|
||||
<div className={`shot-body`} ref={container}>
|
||||
<div className={`shot-wrapper`}>
|
||||
@ -78,7 +81,9 @@ function SharingForm({ refer, data }: SharingFormProps) {
|
||||
<Newspaper className={`shot-icon`} />
|
||||
<p className={`shot-label`}>{t("message.sharing.title")}</p>
|
||||
<div className={`grow`} />
|
||||
<p className={`shot-value`}>{data.name}</p>
|
||||
<p className={`shot-value`}>
|
||||
{mobile ? extractMessage(data.name, 12) : data.name}
|
||||
</p>
|
||||
</div>
|
||||
<div className={`shot-row`}>
|
||||
<Clock className={`shot-icon`} />
|
||||
@ -126,15 +131,14 @@ function SharingForm({ refer, data }: SharingFormProps) {
|
||||
<div className={`action`}>
|
||||
<Button
|
||||
variant={`outline`}
|
||||
onClick={async () => {
|
||||
await copyClipboard(value);
|
||||
toast({
|
||||
title: t("share.copied"),
|
||||
});
|
||||
}}
|
||||
size={`icon`}
|
||||
onClick={() => setMaximized(!maximized)}
|
||||
>
|
||||
<Copy className={`h-4 w-4 mr-2`} />
|
||||
{t("message.copy")}
|
||||
{maximized ? (
|
||||
<Minimize className={`h-4 w-4`} />
|
||||
) : (
|
||||
<Maximize className={`h-4 w-4`} />
|
||||
)}
|
||||
</Button>
|
||||
<Button variant={`outline`} onClick={saveImage}>
|
||||
<Image className={`h-4 w-4 mr-2`} />
|
||||
|
Loading…
Reference in New Issue
Block a user