Skip to content

Commit

Permalink
perf: user exp
Browse files Browse the repository at this point in the history
  • Loading branch information
boxizen committed Apr 9, 2023
1 parent d5a2411 commit 62d42d8
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 30 deletions.
8 changes: 6 additions & 2 deletions src/components/ChatPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
import { Divider, Button } from 'antd'
import { Divider, Button, Alert } from 'antd'

import ReactMarkdown from 'react-markdown'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
Expand Down Expand Up @@ -60,9 +60,13 @@ export function ChatPanel() {
setShowSelection(false)
}

return chatState.visible && (showSelection || chatState.resp) ? (
return chatState.visible &&
(showSelection || chatState.resp || chatState.respErr) ? (
<>
<Divider style={{ margin: 0 }} />
{chatState.respErr ? (
<Alert message={chatState.respErrMsg} type="warning" showIcon />
) : null}
{showSelection ? (
<div style={styles.selectionWrap}>
<span style={styles.selection}>
Expand Down
1 change: 0 additions & 1 deletion src/components/Setting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ export function Setting() {
{saveSuc ? (
<Alert message="Save Success" type="success" showIcon />
) : null}
{/* <Alert message="Save Error" type="error" showIcon /> */}
</TabWrap>
)
}
Expand Down
93 changes: 66 additions & 27 deletions src/features/chat/chatSlice.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'
import { baseApiHost } from '../../app/api'
import { timeoutPromise } from '../../utils/fetch'

interface ChatModule {
resp: string
visible: boolean
inputDiabled: boolean
respErr: boolean
respErrMsg: string
}

export const initialState: ChatModule = {
resp: '',
visible: true,
visible: false,
inputDiabled: false,
respErr: false,
respErrMsg: '',
}

export const chatSlice = createSlice({
Expand All @@ -29,10 +34,24 @@ export const chatSlice = createSlice({
const { payload } = action
state.inputDiabled = payload
},
setRespErr: (state, action: PayloadAction<boolean>) => {
const { payload } = action
state.respErr = payload
},
setRespErrMsg: (state, action: PayloadAction<string>) => {
const { payload } = action
state.respErrMsg = payload
},
},
})

export const { saveResp, setVisible, setInputDisabled } = chatSlice.actions
export const {
saveResp,
setVisible,
setInputDisabled,
setRespErr,
setRespErrMsg,
} = chatSlice.actions
export const fetchChatResp = createAsyncThunk(
'chat/fetchChatResp',
async (
Expand All @@ -43,35 +62,55 @@ export const fetchChatResp = createAsyncThunk(
) => {
const { question } = args
dispatch(setInputDisabled(true))
const response = await fetch(`${baseApiHost}/ask`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
question,
}),
})
dispatch(setRespErr(false))

const reader = response.body
?.pipeThrough(new TextDecoderStream())
.getReader()
const request = async () => {
const response = await fetch(`${baseApiHost}/ask`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
question,
}),
})

let str = ''
let shown = false
while (true) {
if (!reader) break
const { value, done } = await reader.read()
if (done) break
if (!shown) {
dispatch(setVisible(true))
shown = true
const reader = response.body
?.pipeThrough(new TextDecoderStream())
.getReader()

let str = ''
let shown = false
while (true) {
if (!reader) break
const { value, done } = await reader.read()
if (done) break
if (!shown) {
dispatch(setVisible(true))
shown = true
}
str += value
console.log('resp:', str)
dispatch(saveResp(str))
}
str += value
console.log('resp:', str)
dispatch(saveResp(str))
}
dispatch(setInputDisabled(false))

Promise.race([
timeoutPromise(
5000,
'Network congestion, check whether you have set up a proxy'
),
request(),
])
.then()
.catch(e => {
dispatch(setVisible(true))
dispatch(setRespErr(true))
dispatch(setRespErrMsg(e.message))
})
.finally(() => {
dispatch(setInputDisabled(false))
})
}
)
export default chatSlice.reducer
7 changes: 7 additions & 0 deletions src/utils/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const timeoutPromise = (timeout: number, timeoutTips: string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error(timeoutTips))
}, timeout)
})
}

0 comments on commit 62d42d8

Please sign in to comment.