mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	feat: add plugin entry selection
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import { useEffect, useRef, useMemo } from "react";
 | 
			
		||||
import React, { useEffect, useRef, useMemo, useState } from "react";
 | 
			
		||||
 | 
			
		||||
import styles from "./home.module.scss";
 | 
			
		||||
 | 
			
		||||
@@ -15,7 +15,7 @@ import DragIcon from "../icons/drag.svg";
 | 
			
		||||
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
 | 
			
		||||
import { useAppConfig, useChatStore } from "../store";
 | 
			
		||||
import { ModelType, useAppConfig, useChatStore } from "../store";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  DEFAULT_SIDEBAR_WIDTH,
 | 
			
		||||
@@ -29,7 +29,7 @@ import {
 | 
			
		||||
import { Link, useNavigate } from "react-router-dom";
 | 
			
		||||
import { isIOS, useMobileScreen } from "../utils";
 | 
			
		||||
import dynamic from "next/dynamic";
 | 
			
		||||
import { showConfirm, showToast } from "./ui-lib";
 | 
			
		||||
import { Selector, showConfirm, showToast } from "./ui-lib";
 | 
			
		||||
 | 
			
		||||
const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, {
 | 
			
		||||
  loading: () => null,
 | 
			
		||||
@@ -140,6 +140,7 @@ export function SideBar(props: { className?: string }) {
 | 
			
		||||
    () => isIOS() && isMobileScreen,
 | 
			
		||||
    [isMobileScreen],
 | 
			
		||||
  );
 | 
			
		||||
  const [showPluginSelector, setShowPluginSelector] = useState(false);
 | 
			
		||||
 | 
			
		||||
  useHotKey();
 | 
			
		||||
 | 
			
		||||
@@ -183,7 +184,7 @@ export function SideBar(props: { className?: string }) {
 | 
			
		||||
          icon={<PluginIcon />}
 | 
			
		||||
          text={shouldNarrow ? undefined : Locale.Plugin.Name}
 | 
			
		||||
          className={styles["sidebar-bar-button"]}
 | 
			
		||||
          onClick={() => showToast(Locale.WIP)}
 | 
			
		||||
          onClick={() => setShowPluginSelector(true)}
 | 
			
		||||
          shadow
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
@@ -245,6 +246,22 @@ export function SideBar(props: { className?: string }) {
 | 
			
		||||
      >
 | 
			
		||||
        <DragIcon />
 | 
			
		||||
      </div>
 | 
			
		||||
      {showPluginSelector && (
 | 
			
		||||
        <Selector
 | 
			
		||||
          items={[
 | 
			
		||||
            {
 | 
			
		||||
              title: "👇 Please select the plugin you need to use",
 | 
			
		||||
              value: "-",
 | 
			
		||||
              disable: true,
 | 
			
		||||
            },
 | 
			
		||||
            { title: "Stable Diffusion", value: "sd" },
 | 
			
		||||
          ]}
 | 
			
		||||
          onClose={() => setShowPluginSelector(false)}
 | 
			
		||||
          onSelection={(s) => {
 | 
			
		||||
            console.log("go to page: ", s);
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      )}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -291,6 +291,10 @@
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
 | 
			
		||||
  .selector-item-disabled{
 | 
			
		||||
    opacity: 0.6;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-content {
 | 
			
		||||
    .list {
 | 
			
		||||
      max-height: 90vh;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import MinIcon from "../icons/min.svg";
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
 | 
			
		||||
import { createRoot } from "react-dom/client";
 | 
			
		||||
import React, { HTMLProps, useEffect, useState } from "react";
 | 
			
		||||
import React, { HTMLProps, MouseEvent, useEffect, useState } from "react";
 | 
			
		||||
import { IconButton } from "./button";
 | 
			
		||||
 | 
			
		||||
export function Popover(props: {
 | 
			
		||||
@@ -47,7 +47,7 @@ export function ListItem(props: {
 | 
			
		||||
  children?: JSX.Element | JSX.Element[];
 | 
			
		||||
  icon?: JSX.Element;
 | 
			
		||||
  className?: string;
 | 
			
		||||
  onClick?: () => void;
 | 
			
		||||
  onClick?: (event: MouseEvent) => void;
 | 
			
		||||
}) {
 | 
			
		||||
  return (
 | 
			
		||||
    <div
 | 
			
		||||
@@ -442,6 +442,7 @@ export function Selector<T>(props: {
 | 
			
		||||
    title: string;
 | 
			
		||||
    subTitle?: string;
 | 
			
		||||
    value: T;
 | 
			
		||||
    disable?: boolean;
 | 
			
		||||
  }>;
 | 
			
		||||
  defaultSelectedValue?: T;
 | 
			
		||||
  onSelection?: (selection: T[]) => void;
 | 
			
		||||
@@ -456,13 +457,18 @@ export function Selector<T>(props: {
 | 
			
		||||
            const selected = props.defaultSelectedValue === item.value;
 | 
			
		||||
            return (
 | 
			
		||||
              <ListItem
 | 
			
		||||
                className={styles["selector-item"]}
 | 
			
		||||
                className={`${styles["selector-item"]} ${
 | 
			
		||||
                  item.disable && styles["selector-item-disabled"]
 | 
			
		||||
                }`}
 | 
			
		||||
                key={i}
 | 
			
		||||
                title={item.title}
 | 
			
		||||
                subTitle={item.subTitle}
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  props.onSelection?.([item.value]);
 | 
			
		||||
                  props.onClose?.();
 | 
			
		||||
                onClick={(event) => {
 | 
			
		||||
                  event.stopPropagation();
 | 
			
		||||
                  if (!item.disable) {
 | 
			
		||||
                    props.onSelection?.([item.value]);
 | 
			
		||||
                    props.onClose?.();
 | 
			
		||||
                  }
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                {selected ? (
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user