mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	Merge pull request #509 from xiaotianxt/feat/dnd-xiaotianxt
Drag & Drop support for ChatList
This commit is contained in:
		@@ -1,14 +1,13 @@
 | 
			
		||||
import { useState, useRef, useEffect, useLayoutEffect } from "react";
 | 
			
		||||
import DeleteIcon from "../icons/delete.svg";
 | 
			
		||||
import styles from "./home.module.scss";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  Message,
 | 
			
		||||
  SubmitKey,
 | 
			
		||||
  useChatStore,
 | 
			
		||||
  ChatSession,
 | 
			
		||||
  BOT_HELLO,
 | 
			
		||||
} from "../store";
 | 
			
		||||
  DragDropContext,
 | 
			
		||||
  Droppable,
 | 
			
		||||
  Draggable,
 | 
			
		||||
  OnDragEndResponder,
 | 
			
		||||
} from "@hello-pangea/dnd";
 | 
			
		||||
 | 
			
		||||
import { useChatStore } from "../store";
 | 
			
		||||
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
import { isMobileScreen } from "../utils";
 | 
			
		||||
@@ -20,54 +19,92 @@ export function ChatItem(props: {
 | 
			
		||||
  count: number;
 | 
			
		||||
  time: string;
 | 
			
		||||
  selected: boolean;
 | 
			
		||||
  id: number;
 | 
			
		||||
  index: number;
 | 
			
		||||
}) {
 | 
			
		||||
  return (
 | 
			
		||||
    <div
 | 
			
		||||
      className={`${styles["chat-item"]} ${
 | 
			
		||||
        props.selected && styles["chat-item-selected"]
 | 
			
		||||
      }`}
 | 
			
		||||
      onClick={props.onClick}
 | 
			
		||||
    >
 | 
			
		||||
      <div className={styles["chat-item-title"]}>{props.title}</div>
 | 
			
		||||
      <div className={styles["chat-item-info"]}>
 | 
			
		||||
        <div className={styles["chat-item-count"]}>
 | 
			
		||||
          {Locale.ChatItem.ChatItemCount(props.count)}
 | 
			
		||||
    <Draggable draggableId={`${props.id}`} index={props.index}>
 | 
			
		||||
      {(provided) => (
 | 
			
		||||
        <div
 | 
			
		||||
          className={`${styles["chat-item"]} ${
 | 
			
		||||
            props.selected && styles["chat-item-selected"]
 | 
			
		||||
          }`}
 | 
			
		||||
          onClick={props.onClick}
 | 
			
		||||
          ref={provided.innerRef}
 | 
			
		||||
          {...provided.draggableProps}
 | 
			
		||||
          {...provided.dragHandleProps}
 | 
			
		||||
        >
 | 
			
		||||
          <div className={styles["chat-item-title"]}>{props.title}</div>
 | 
			
		||||
          <div className={styles["chat-item-info"]}>
 | 
			
		||||
            <div className={styles["chat-item-count"]}>
 | 
			
		||||
              {Locale.ChatItem.ChatItemCount(props.count)}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className={styles["chat-item-date"]}>{props.time}</div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div className={styles["chat-item-delete"]} onClick={props.onDelete}>
 | 
			
		||||
            <DeleteIcon />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className={styles["chat-item-date"]}>{props.time}</div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div className={styles["chat-item-delete"]} onClick={props.onDelete}>
 | 
			
		||||
        <DeleteIcon />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
      )}
 | 
			
		||||
    </Draggable>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function ChatList() {
 | 
			
		||||
  const [sessions, selectedIndex, selectSession, removeSession] = useChatStore(
 | 
			
		||||
    (state) => [
 | 
			
		||||
  const [sessions, selectedIndex, selectSession, removeSession, moveSession] =
 | 
			
		||||
    useChatStore((state) => [
 | 
			
		||||
      state.sessions,
 | 
			
		||||
      state.currentSessionIndex,
 | 
			
		||||
      state.selectSession,
 | 
			
		||||
      state.removeSession,
 | 
			
		||||
    ],
 | 
			
		||||
  );
 | 
			
		||||
      state.moveSession,
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
  const onDragEnd: OnDragEndResponder = (result) => {
 | 
			
		||||
    const { destination, source } = result;
 | 
			
		||||
    if (!destination) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
      destination.droppableId === source.droppableId &&
 | 
			
		||||
      destination.index === source.index
 | 
			
		||||
    ) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    moveSession(source.index, destination.index);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles["chat-list"]}>
 | 
			
		||||
      {sessions.map((item, i) => (
 | 
			
		||||
        <ChatItem
 | 
			
		||||
          title={item.topic}
 | 
			
		||||
          time={item.lastUpdate}
 | 
			
		||||
          count={item.messages.length}
 | 
			
		||||
          key={i}
 | 
			
		||||
          selected={i === selectedIndex}
 | 
			
		||||
          onClick={() => selectSession(i)}
 | 
			
		||||
          onDelete={() =>
 | 
			
		||||
            (!isMobileScreen() || confirm(Locale.Home.DeleteChat)) &&
 | 
			
		||||
            removeSession(i)
 | 
			
		||||
          }
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
    </div>
 | 
			
		||||
    <DragDropContext onDragEnd={onDragEnd}>
 | 
			
		||||
      <Droppable droppableId="chat-list">
 | 
			
		||||
        {(provided) => (
 | 
			
		||||
          <div
 | 
			
		||||
            className={styles["chat-list"]}
 | 
			
		||||
            ref={provided.innerRef}
 | 
			
		||||
            {...provided.droppableProps}
 | 
			
		||||
          >
 | 
			
		||||
            {sessions.map((item, i) => (
 | 
			
		||||
              <ChatItem
 | 
			
		||||
                title={item.topic}
 | 
			
		||||
                time={item.lastUpdate}
 | 
			
		||||
                count={item.messages.length}
 | 
			
		||||
                key={item.id}
 | 
			
		||||
                id={item.id}
 | 
			
		||||
                index={i}
 | 
			
		||||
                selected={i === selectedIndex}
 | 
			
		||||
                onClick={() => selectSession(i)}
 | 
			
		||||
                onDelete={() =>
 | 
			
		||||
                  (!isMobileScreen() || confirm(Locale.Home.DeleteChat)) &&
 | 
			
		||||
                  removeSession(i)
 | 
			
		||||
                }
 | 
			
		||||
              />
 | 
			
		||||
            ))}
 | 
			
		||||
            {provided.placeholder}
 | 
			
		||||
          </div>
 | 
			
		||||
        )}
 | 
			
		||||
      </Droppable>
 | 
			
		||||
    </DragDropContext>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin-bottom: 10px;
 | 
			
		||||
  box-shadow: var(--card-shadow);
 | 
			
		||||
  transition: all 0.3s ease;
 | 
			
		||||
  transition: background-color 0.3s ease;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  border: 2px solid transparent;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ import CloseIcon from "../icons/close.svg";
 | 
			
		||||
import { useChatStore } from "../store";
 | 
			
		||||
import { isMobileScreen } from "../utils";
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
import { ChatList } from "./chat-list";
 | 
			
		||||
import { Chat } from "./chat";
 | 
			
		||||
 | 
			
		||||
import dynamic from "next/dynamic";
 | 
			
		||||
@@ -39,6 +38,10 @@ const Settings = dynamic(async () => (await import("./settings")).Settings, {
 | 
			
		||||
  loading: () => <Loading noLogo />,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, {
 | 
			
		||||
  loading: () => <Loading noLogo />,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function useSwitchTheme() {
 | 
			
		||||
  const config = useChatStore((state) => state.config);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -201,6 +201,7 @@ interface ChatStore {
 | 
			
		||||
  currentSessionIndex: number;
 | 
			
		||||
  clearSessions: () => void;
 | 
			
		||||
  removeSession: (index: number) => void;
 | 
			
		||||
  moveSession: (from: number, to: number) => void;
 | 
			
		||||
  selectSession: (index: number) => void;
 | 
			
		||||
  newSession: () => void;
 | 
			
		||||
  currentSession: () => ChatSession;
 | 
			
		||||
@@ -291,6 +292,31 @@ export const useChatStore = create<ChatStore>()(
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      moveSession(from: number, to: number) {
 | 
			
		||||
        set((state) => {
 | 
			
		||||
          const { sessions, currentSessionIndex: oldIndex } = state;
 | 
			
		||||
 | 
			
		||||
          // move the session
 | 
			
		||||
          const newSessions = [...sessions];
 | 
			
		||||
          const session = newSessions[from];
 | 
			
		||||
          newSessions.splice(from, 1);
 | 
			
		||||
          newSessions.splice(to, 0, session);
 | 
			
		||||
 | 
			
		||||
          // modify current session id
 | 
			
		||||
          let newIndex = oldIndex === from ? to : oldIndex;
 | 
			
		||||
          if (oldIndex > from && oldIndex <= to) {
 | 
			
		||||
            newIndex -= 1;
 | 
			
		||||
          } else if (oldIndex < from && oldIndex >= to) {
 | 
			
		||||
            newIndex += 1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return {
 | 
			
		||||
            currentSessionIndex: newIndex,
 | 
			
		||||
            sessions: newSessions,
 | 
			
		||||
          };
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      newSession() {
 | 
			
		||||
        set((state) => ({
 | 
			
		||||
          currentSessionIndex: 0,
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
    "prepare": "husky install"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@hello-pangea/dnd": "^16.2.0",
 | 
			
		||||
    "@svgr/webpack": "^6.5.1",
 | 
			
		||||
    "@vercel/analytics": "^0.1.11",
 | 
			
		||||
    "emoji-picker-react": "^4.4.7",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										85
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -954,7 +954,7 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
 | 
			
		||||
  integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4":
 | 
			
		||||
"@babel/runtime@^7.12.1", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
 | 
			
		||||
  version "7.21.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
 | 
			
		||||
  integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
 | 
			
		||||
@@ -1027,6 +1027,19 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.37.0.tgz#cf1b5fa24217fe007f6487a26d765274925efa7d"
 | 
			
		||||
  integrity sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==
 | 
			
		||||
 | 
			
		||||
"@hello-pangea/dnd@^16.2.0":
 | 
			
		||||
  version "16.2.0"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/@hello-pangea/dnd/-/dnd-16.2.0.tgz#58cbadeb56f8c7a381da696bb7aa3bfbb87876ec"
 | 
			
		||||
  integrity sha512-inACvMcvvLr34CG0P6+G/3bprVKhwswxjcsFUSJ+fpOGjhvDj9caiA9X3clby0lgJ6/ILIJjyedHZYECB7GAgA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.19.4"
 | 
			
		||||
    css-box-model "^1.2.1"
 | 
			
		||||
    memoize-one "^6.0.0"
 | 
			
		||||
    raf-schd "^4.0.3"
 | 
			
		||||
    react-redux "^8.0.4"
 | 
			
		||||
    redux "^4.2.0"
 | 
			
		||||
    use-memo-one "^1.1.3"
 | 
			
		||||
 | 
			
		||||
"@humanwhocodes/config-array@^0.11.8":
 | 
			
		||||
  version "0.11.8"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
 | 
			
		||||
@@ -1333,6 +1346,14 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/unist" "*"
 | 
			
		||||
 | 
			
		||||
"@types/hoist-non-react-statics@^3.3.1":
 | 
			
		||||
  version "3.3.1"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
 | 
			
		||||
  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
 | 
			
		||||
"@types/json5@^0.0.29":
 | 
			
		||||
  version "0.0.29"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
 | 
			
		||||
@@ -1408,6 +1429,11 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
 | 
			
		||||
  integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
 | 
			
		||||
 | 
			
		||||
"@types/use-sync-external-store@^0.0.3":
 | 
			
		||||
  version "0.0.3"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
 | 
			
		||||
  integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
 | 
			
		||||
 | 
			
		||||
"@typescript-eslint/parser@^5.42.0":
 | 
			
		||||
  version "5.57.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.57.0.tgz#f675bf2cd1a838949fd0de5683834417b757e4fa"
 | 
			
		||||
@@ -1912,6 +1938,13 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
 | 
			
		||||
    shebang-command "^2.0.0"
 | 
			
		||||
    which "^2.0.1"
 | 
			
		||||
 | 
			
		||||
css-box-model@^1.2.1:
 | 
			
		||||
  version "1.2.1"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1"
 | 
			
		||||
  integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tiny-invariant "^1.0.6"
 | 
			
		||||
 | 
			
		||||
css-select@^4.1.3:
 | 
			
		||||
  version "4.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
 | 
			
		||||
@@ -2885,6 +2918,13 @@ highlight.js@~11.7.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
 | 
			
		||||
  integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
 | 
			
		||||
 | 
			
		||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
 | 
			
		||||
  version "3.3.2"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
 | 
			
		||||
  integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    react-is "^16.7.0"
 | 
			
		||||
 | 
			
		||||
human-signals@^4.3.0:
 | 
			
		||||
  version "4.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2"
 | 
			
		||||
@@ -3527,6 +3567,11 @@ mdn-data@2.0.14:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
 | 
			
		||||
  integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
 | 
			
		||||
 | 
			
		||||
memoize-one@^6.0.0:
 | 
			
		||||
  version "6.0.0"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
 | 
			
		||||
  integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
 | 
			
		||||
 | 
			
		||||
merge-stream@^2.0.0:
 | 
			
		||||
  version "2.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
 | 
			
		||||
@@ -4211,6 +4256,11 @@ queue-microtask@^1.2.2:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
 | 
			
		||||
  integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
 | 
			
		||||
 | 
			
		||||
raf-schd@^4.0.3:
 | 
			
		||||
  version "4.0.3"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
 | 
			
		||||
  integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
 | 
			
		||||
 | 
			
		||||
react-dom@^18.2.0:
 | 
			
		||||
  version "18.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
 | 
			
		||||
@@ -4219,7 +4269,7 @@ react-dom@^18.2.0:
 | 
			
		||||
    loose-envify "^1.1.0"
 | 
			
		||||
    scheduler "^0.23.0"
 | 
			
		||||
 | 
			
		||||
react-is@^16.13.1:
 | 
			
		||||
react-is@^16.13.1, react-is@^16.7.0:
 | 
			
		||||
  version "16.13.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
 | 
			
		||||
  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 | 
			
		||||
@@ -4250,6 +4300,18 @@ react-markdown@^8.0.5:
 | 
			
		||||
    unist-util-visit "^4.0.0"
 | 
			
		||||
    vfile "^5.0.0"
 | 
			
		||||
 | 
			
		||||
react-redux@^8.0.4:
 | 
			
		||||
  version "8.0.5"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd"
 | 
			
		||||
  integrity sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.12.1"
 | 
			
		||||
    "@types/hoist-non-react-statics" "^3.3.1"
 | 
			
		||||
    "@types/use-sync-external-store" "^0.0.3"
 | 
			
		||||
    hoist-non-react-statics "^3.3.2"
 | 
			
		||||
    react-is "^18.0.0"
 | 
			
		||||
    use-sync-external-store "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react@^18.2.0:
 | 
			
		||||
  version "18.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
 | 
			
		||||
@@ -4264,6 +4326,13 @@ readdirp@~3.6.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    picomatch "^2.2.1"
 | 
			
		||||
 | 
			
		||||
redux@^4.2.0:
 | 
			
		||||
  version "4.2.1"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
 | 
			
		||||
  integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.9.2"
 | 
			
		||||
 | 
			
		||||
regenerate-unicode-properties@^10.1.0:
 | 
			
		||||
  version "10.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
 | 
			
		||||
@@ -4774,6 +4843,11 @@ tiny-glob@^0.2.9:
 | 
			
		||||
    globalyzer "0.1.0"
 | 
			
		||||
    globrex "^0.1.2"
 | 
			
		||||
 | 
			
		||||
tiny-invariant@^1.0.6:
 | 
			
		||||
  version "1.3.1"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
 | 
			
		||||
  integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
 | 
			
		||||
 | 
			
		||||
to-fast-properties@^2.0.0:
 | 
			
		||||
  version "2.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
 | 
			
		||||
@@ -4979,7 +5053,12 @@ use-debounce@^9.0.3:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-9.0.3.tgz#bac660c19ab7b38662e08608fee23c7ad303f532"
 | 
			
		||||
  integrity sha512-FhtlbDtDXILJV7Lix5OZj5yX/fW1tzq+VrvK1fnT2bUrPOGruU9Rw8NCEn+UI9wopfERBEZAOQ8lfeCJPllgnw==
 | 
			
		||||
 | 
			
		||||
use-sync-external-store@1.2.0:
 | 
			
		||||
use-memo-one@^1.1.3:
 | 
			
		||||
  version "1.1.3"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
 | 
			
		||||
  integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
 | 
			
		||||
 | 
			
		||||
use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0:
 | 
			
		||||
  version "1.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
 | 
			
		||||
  integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user