bgRemoval.tsx 5.6 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 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/three-dots.svg";
import BotIcon from "@/app/icons/bot.svg";
import CloseIcon from "@/app/icons/close.svg";
import { cosUploadImage } from "@/app/utils/tencentCos";

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 [previewUrl, setPreviewUrl] = useState<string | null>(
    localStorage.getItem("image") || "",
  );
  // 关闭图片
  const closePic = () => {
    setPreviewUrl("");
  };

  //上传图片
  const onChange = async (info: any) => {
    if (info.file.status === "uploading") {
      return;
    }
    if (info.file.status === "done") {
      // 获取上传的文件对象
      const file = info.file.originFileObj;
      setIsLoading(true);
      try {
        const imageUrl = await cosUploadImage(file, Path.BgRemoval);
        setPreviewUrl(
          imageUrl.startsWith("https://") ? imageUrl : `https://${imageUrl}`,
        );
      } catch (error) {
        console.log(error);
        message.error(Locale.ComError.UploadErr);
      } finally {
        setIsLoading(false);
      }
    } else if (info.file.status === "error") {
      message.error(`${info.file.name} file upload failed.`);
    }
  };

  useEffect(() => {
    previewUrl && localStorage.setItem("image", previewUrl);
  }, [previewUrl]);

  return (
    <>
      <BgSiderBar
        className={clsx({ [homeStyles["sidebar-show"]]: isBgRemoval })}
        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}
                  showUploadList={false}
                  accept="image/*"
                >
                  <Button icon={<UploadOutlined />} size="large">
                    上传图片
                  </Button>
                </Upload>
              )}
            </Flex>
          </div>
        </div>
      </WindowContent>
    </>
  );
}