From cf8137373b9f5b533076811eab671ad8ecfe681f Mon Sep 17 00:00:00 2001 From: Zhang Minghan Date: Thu, 7 Sep 2023 11:34:52 +0800 Subject: [PATCH] update scroll action and quota store --- api/chat.go | 1 + app/src/assets/chat.less | 16 ++++++++++++++ app/src/routes/Home.tsx | 45 ++++++++++++++++++++++++++++++++++------ app/src/store/index.ts | 2 ++ app/src/store/quota.ts | 38 +++++++++++++++++++++++++++++++++ middleware/cors.go | 2 ++ 6 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 app/src/store/quota.ts diff --git a/api/chat.go b/api/chat.go index c0160930..9933996f 100644 --- a/api/chat.go +++ b/api/chat.go @@ -95,6 +95,7 @@ func ImageChat(conn *websocket.Conn, instance *conversation.Conversation, user * markdown := GetImageMarkdown(url) SendSegmentMessage(conn, types.ChatGPTSegmentResponse{ + Quota: 1., Message: markdown, End: true, }) diff --git a/app/src/assets/chat.less b/app/src/assets/chat.less index db38a8ab..07d3ab7a 100644 --- a/app/src/assets/chat.less +++ b/app/src/assets/chat.less @@ -11,6 +11,22 @@ } } +.scroll-action { + position: absolute; + bottom: 112px; + right: 36px; + opacity: 0; + transition: .25s; + + button { + border-color: rgba(0,0,0,0) !important; + } + + &.active { + opacity: 0.8; + } +} + .message { display: flex; gap: 6px; diff --git a/app/src/routes/Home.tsx b/app/src/routes/Home.tsx index ee34a7b9..a6f8205b 100644 --- a/app/src/routes/Home.tsx +++ b/app/src/routes/Home.tsx @@ -3,6 +3,7 @@ import "../assets/chat.less"; import { Input } from "../components/ui/input.tsx"; import { Toggle } from "../components/ui/toggle.tsx"; import { + ChevronDown, Globe, LogIn, MessageSquare, @@ -28,7 +29,7 @@ import { toggleConversation, updateConversationList, } from "../conversation/history.ts"; -import React, { useEffect, useRef } from "react"; +import React, {useEffect, useRef, useState} from "react"; import { useAnimation, useEffectAsync } from "../utils.ts"; import { useToast } from "../components/ui/use-toast.ts"; import { ConversationInstance, Message } from "../conversation/types.ts"; @@ -177,23 +178,55 @@ function SideBar() { function ChatInterface() { const ref = useRef(null); + const [ scroll, setScroll ] = useState(false); const messages: Message[] = useSelector(selectMessages); + function listenScrolling() { + if (!ref.current) return; + const el = ref.current as HTMLDivElement; + const offset = el.scrollHeight - el.scrollTop - el.clientHeight; + setScroll(offset > 100); + } + useEffect( function () { if (!ref.current) return; const el = ref.current as HTMLDivElement; el.scrollTop = el.scrollHeight; + listenScrolling(); }, [messages], ); + useEffect(() => { + if (!ref.current) return; + const el = ref.current as HTMLDivElement; + el.addEventListener('scroll', listenScrolling); + }, [ref]); + return ( -
- {messages.map((message, i) => ( - - ))} -
+ <> +
+
+ +
+ + { + messages.map((message, i) => + + ) + } +
+ ); } diff --git a/app/src/store/index.ts b/app/src/store/index.ts index a8f98738..786d26fc 100644 --- a/app/src/store/index.ts +++ b/app/src/store/index.ts @@ -2,12 +2,14 @@ import { configureStore } from "@reduxjs/toolkit"; import menuReducer from "./menu"; import authReducer from "./auth"; import chatReducer from "./chat"; +import quotaReducer from "./quota"; const store = configureStore({ reducer: { menu: menuReducer, auth: authReducer, chat: chatReducer, + quota: quotaReducer, }, }); diff --git a/app/src/store/quota.ts b/app/src/store/quota.ts new file mode 100644 index 00000000..558e1940 --- /dev/null +++ b/app/src/store/quota.ts @@ -0,0 +1,38 @@ +import { createSlice } from "@reduxjs/toolkit"; +import {RootState} from "./index.ts"; + +export const quotaSlice = createSlice({ + name: "quota", + initialState: { + dialog: false, + quota: 0., + }, + reducers: { + toggleDialog: (state) => { + state.dialog = !state.dialog; + }, + setDialog: (state, action) => { + state.dialog = action.payload as boolean; + }, + closeDialog: (state) => { + state.dialog = false; + }, + setQuota: (state, action) => { + state.quota = action.payload as number; + }, + increaseQuota: (state, action) => { + state.quota += action.payload as number; + }, + decreaseQuota: (state, action) => { + state.quota -= action.payload as number; + }, + }, +}); + +export const { toggleDialog, setDialog, closeDialog, setQuota, increaseQuota, decreaseQuota } = quotaSlice.actions; +export default quotaSlice.reducer; + +export const dialogSelector = (state: RootState): boolean => state.quota.dialog; +export const quotaValueSelector = (state: RootState): number => state.quota.quota; +export const quotaSelector = (state: RootState): string => state.quota.quota.toFixed(2); + diff --git a/middleware/cors.go b/middleware/cors.go index 709376e3..d8479140 100644 --- a/middleware/cors.go +++ b/middleware/cors.go @@ -22,6 +22,8 @@ func CORSMiddleware() gin.HandlerFunc { c.Writer.Header().Set("Access-Control-Allow-Origin", origin) c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") + c.Writer.Header().Set("Access-Control-Max-Age", "7200") if c.Request.Method == "OPTIONS" { c.Writer.Header().Set("Access-Control-Max-Age", "3600")