bgRemoval.tsx 6.8 KB
import chatStyles from "@/app/components/chat.module.scss";
import homeStyles from "@/app/components/home.module.scss";
import styles from './bgRemoval.module.scss'

import { WindowContent } from "@/app/components/home";
import { useMobileScreen } from "@/app/utils";
import { IconButton } from "../button";
import Locale from "@/app/locales";
import { Path } from "@/app/constant";
import { useNavigate } from "react-router-dom";
import clsx from "clsx";
import { getClientConfig } from "@/app/config/client";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useAppConfig } from "@/app/store";
import { BgSiderBar } from "./bg-siderBar";
import { Button, Flex, Upload, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd';


import ReturnIcon from "@/app/icons/return.svg";
import MinIcon from "@/app/icons/min.svg";
import MaxIcon from "@/app/icons/max.svg";
import SDIcon from "@/app/icons/sd.svg";
import LoadingIcon from "@/app/icons/loading.svg";
import BotIcon from "@/app/icons/bot.svg";
import CloseIcon from "@/app/icons/close.svg";



export function BgRemoval() {
    const isMobileScreen = useMobileScreen();
    const navigate = useNavigate();
    const clientConfig = useMemo(() => getClientConfig(), []);
    const showMaxIcon = !isMobileScreen && !clientConfig?.isApp;
    const config = useAppConfig();
    const scrollRef = useRef<HTMLDivElement>(null);
    const isBgRemoval = location.pathname === Path.BgRemoval;

    const [isLoading, setIsLoading] = useState(false)
    const [fileData, setFileData] = useState<Blob | null>(null);   //储存上传图片
    const [previewUrl, setPreviewUrl] = useState<string | null>('')
    // 关闭图片
    const closePic = () => {
        setFileData(null);
        setPreviewUrl('');
    };

    //上传图片
    const onChange = (info: any) => {
        if (info.file.status === 'uploading') {
            return;
        }
        if (info.file.status === 'done') {
            // 获取上传的文件对象
            const file = info.file as UploadFile;
            const blob = file.originFileObj as Blob;
            setFileData(blob);
        } else if (info.file.status === 'error') {
            message.error(`${info.file.name} file upload failed.`);
        }
    };
    // 修改 useEffect 监听 fileData
    useEffect(() => {
        if (fileData) {
            // 创建 Blob 的临时 URL
            const objectUrl = URL.createObjectURL(fileData);
            setPreviewUrl(objectUrl);
            // 组件卸载时释放内存
            return () => URL.revokeObjectURL(objectUrl);
        }
    }, [fileData]);


    return (
        <>
            <BgSiderBar 
                className={clsx({ [homeStyles["sidebar-show"]]: isBgRemoval })} 
                fileData={fileData}
                setFileData={setFileData}
                previewUrl={previewUrl}
                setPreviewUrl={setPreviewUrl}
                isLoading={isLoading}
                setIsLoading={setIsLoading}
            />
            <WindowContent>
                <div className={chatStyles.chat} key={"1"}>
                    <div className="window-header" data-tauri-drag-region>
                        {isMobileScreen && (
                            <div className="window-actions">
                                <div className={"window-action-button"}>
                                    <IconButton
                                        icon={<ReturnIcon />}
                                        bordered
                                        title={Locale.Chat.Actions.ChatList}
                                        onClick={() => navigate(Path.BgRemoval)}
                                    />
                                </div>
                            </div>
                        )}
                        <div
                            className={clsx(
                                "window-header-title",
                                chatStyles["chat-body-title"],
                            )}
                        >
                            <div className={`window-header-main-title`}>智能抠图</div>
                        </div>
                        <div className="window-actions">
                            {showMaxIcon && (
                                <div className="window-action-button">
                                    <IconButton
                                        aria={Locale.Chat.Actions.FullScreen}
                                        icon={config.tightBorder ? <MinIcon /> : <MaxIcon />}
                                        bordered
                                        onClick={() => {
                                            config.update(
                                                (config) => (config.tightBorder = !config.tightBorder),
                                            );
                                        }}
                                    />
                                </div>
                            )}
                            {isMobileScreen && <SDIcon width={50} height={50} />}
                        </div>
                    </div>
                    <div className={chatStyles["chat-body"]} ref={scrollRef}>
                        <Flex vertical justify='center' align="center" gap="middle" className={styles['panelFlex']}>
                            {isLoading ? (
                                <div className={clsx("no-dark", styles["loading-content"])}>
                                    <BotIcon />
                                    <LoadingIcon />
                                </div>
                            ) : previewUrl ? (
                                <div className={styles['preview']}>
                                    <img src={previewUrl} alt="Preview" className={styles['previewImage']} />
                                    <IconButton icon={<CloseIcon />} bordered onClick={closePic} className={styles['icon']} />
                                </div>
                            ) : (
                                <Upload
                                    onChange={onChange}
                                    beforeUpload={(file) => {
                                        setFileData(file);
                                        return false;
                                    }}
                                    showUploadList={false}
                                    accept="image/*"
                                >
                                    <Button icon={<UploadOutlined />} size='large'>
                                        上传图片
                                    </Button>
                                </Upload>
                            )}
                        </Flex>
                    </div>
                </div>
            </WindowContent>
        </>)
}