Skip to content

Commit

Permalink
chore: 细节优化
Browse files Browse the repository at this point in the history
  • Loading branch information
weaigc committed Sep 1, 2023
1 parent 0f70163 commit 56c5d6e
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 77 deletions.
31 changes: 15 additions & 16 deletions src/app/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1110,12 +1110,13 @@ button {
position: relative;
width: 100%;
height: 100%;
min-height: 48px;
min-height: 90px;
box-sizing: border-box;
padding: 13px 16px;
z-index: 1;
background: var(--cib-color-background-surface-solid-quaternary);
border-radius: var(--cib-action-bar-search-border-radius);
border-radius: var(--cib-border-radius-extra-large);

outline: transparent solid 1px;
cursor: text;
transition-property: min-height, height, width, transform, border-radius, box-shadow;
Expand All @@ -1137,13 +1138,6 @@ button {

&:hover,
&.active {
min-height: 90px;
border-radius: var(--cib-border-radius-extra-large);

.bottom-bar {
opacity: 1;
}

textarea {
white-space: pre-wrap;
}
Expand All @@ -1160,9 +1154,12 @@ button {
}

.message-input {
max-height: 50vh;
max-height: min(400px, 50vh);
overflow-y: auto;
color: var(--cib-color-foreground-neutral-primary);
&:empty {
max-height: 24px;
}
}
}

Expand All @@ -1182,9 +1179,9 @@ button {

.outside-left-container {
position: relative;
align-self: flex-end;
align-self: flex-start;
height: 48px;
bottom: 42px;
top: 0px;
margin: 0px;
padding: 0px;
transition-property: opacity;
Expand Down Expand Up @@ -1237,8 +1234,11 @@ button {
}
}

&.collapsed .button-compose {
width: var(--button-compose-collapsed-width);

&.collapsed {
.button-compose {
width: var(--button-compose-collapsed-width);
}
}

&:hover .button-compose {
Expand Down Expand Up @@ -1624,7 +1624,6 @@ button {
inset-inline: 0px;
box-sizing: border-box;
padding: 8px;
opacity: 0;
transition-property: opacity;
transition-duration: var(--cib-motion-duration-faster);
transition-delay: var(--cib-motion-duration-faster);
Expand Down Expand Up @@ -1681,7 +1680,7 @@ button {

.outside-left-container {
position: absolute;
bottom: 0px;
top: 0px;
inset-inline-start: 0px;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/chat-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function ChatImage({ children, uploadImage }: React.PropsWithChildren<Cha

useEffect(() => {
if (panel === 'camera-mode') {
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' }, audio: false })
.then(videoStream => {
mediaStream.current = videoStream
if (videoRef.current) {
Expand Down
49 changes: 33 additions & 16 deletions src/components/chat-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use client'

import * as React from 'react'
import React, { useCallback, useEffect, KeyboardEvent } from 'react'
import Textarea from 'react-textarea-autosize'
import { useAtomValue } from 'jotai'
import { useEnterSubmit } from '@/lib/hooks/use-enter-submit'
import { cn } from '@/lib/utils'

import NewTopic from '@/assets/images/new-topic.svg'
Expand Down Expand Up @@ -54,7 +53,14 @@ export function ChatPanel({
const [tid, setTid] = React.useState<any>()
const voiceListening = useAtomValue(voiceListenAtom)

const onSubmit = async () => {
const onSend = useCallback(async () => {
setTimeout(() => {
window.scrollTo({
top: document.body.offsetHeight,
behavior: 'smooth'
})
}, 200)

if (generating) {
return;
}
Expand All @@ -64,33 +70,44 @@ export function ChatPanel({
}
setInput('')
await sendMessage(input)
}
const { onKeyDown } = useEnterSubmit(onSubmit)
const setBlur = React.useCallback(() => {
}, [generating, input, sendMessage, setInput])
const onSubmit = useCallback(async (event: KeyboardEvent<HTMLTextAreaElement>) => {
if (
event.shiftKey ||
event.ctrlKey ||
event.nativeEvent.isComposing ||
event.key !== 'Enter'
) {
return
}
event.preventDefault()

onSend()
}, [attachmentList])

const setBlur = useCallback(() => {
clearTimeout(tid)
const _tid = setTimeout(() => setFocused(false), 2000);
setTid(_tid)
}, [tid])

const setFocus = React.useCallback(() => {
const setFocus = useCallback(() => {
setFocused(true)
clearTimeout(tid)
inputRef.current?.focus()
}, [tid])

React.useEffect(() => {
useEffect(() => {
if (input) {
setFocus()
}

}, [input, setFocus])

return (
<div
className={cn('chat-panel relative', className)}
>
<div className={cn('chat-panel relative', className)}>
<div className="action-bar pb-4">
<div className={cn('action-root focus')} speech-state="hidden" visual-search="" drop-target="">
<div className="action-root" speech-state="hidden" visual-search="" drop-target="">
<div className="fade bottom">
<div className="background"></div>
</div>
Expand All @@ -105,7 +122,7 @@ export function ChatPanel({
</div>
</div>
<div
className={cn('main-container active')}
className={cn('main-container')}
onClick={setFocus}
onBlur={setBlur}
>
Expand All @@ -117,15 +134,15 @@ export function ChatPanel({
<Textarea
ref={inputRef}
tabIndex={0}
onKeyDown={onKeyDown}
onKeyDown={onSubmit}
rows={1}
value={input}
onChange={e => setInput(e.target.value.slice(0, 8000))}
placeholder={voiceListening ? '持续对话中...对话完成说“发送”即可' : 'Shift + Enter 换行,输入 / 选择提示词'}
spellCheck={false}
className="message-input min-h-[24px] w-full text-base resize-none bg-transparent focus-within:outline-none"
/>
<Voice setInput={setInput} sendMessage={sendMessage} isSpeaking={isSpeaking} input={input} />
<Voice className="action-button" setInput={setInput} sendMessage={sendMessage} isSpeaking={isSpeaking} input={input} />
</div>
<ChatAttachments attachmentList={attachmentList} setAttachmentList={setAttachmentList} uploadImage={uploadImage} />
<div className="body-1 bottom-bar">
Expand All @@ -136,7 +153,7 @@ export function ChatPanel({
</div>
<div className="flex gap-2 items-center">
<div className="letter-counter"><span>{input.length}</span>/8000</div>
<button type="submit" className="action-button" onClick={onSubmit}>
<button type="submit" className="action-button" onClick={onSend}>
<SVG alt="send" src={input.length ? SendFillIcon : SendIcon} width={18} height={20} />
</button>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react'
import { useAtom } from 'jotai'
import { Switch } from '@headlessui/react'
import { toast } from 'react-hot-toast'
import { hashAtom, historyAtom, voiceAtom } from '@/state'
import { hashAtom, historyAtom, isImageOnly, voiceAtom } from '@/state'
import {
Dialog,
DialogContent,
Expand All @@ -21,7 +21,7 @@ export function Settings() {
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 })
const [loc, setLoc] = useAtom(hashAtom)
const [curlValue, setCurlValue] = useState(extraCurlFromCookie(parseCookies(document.cookie, ChunkKeys)))
const [imageOnly, setImageOnly] = useState(getCookie('IMAGE_ONLY') !== '0')
const [imageOnly, setImageOnly] = useState(isImageOnly)
const [enabledHistory, setHistory] = useAtom(historyAtom)
const [enableTTS, setEnableTTS] = useAtom(voiceAtom)

Expand Down
5 changes: 3 additions & 2 deletions src/components/voice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import VoiceButton from './ui/voice'
import { SR } from '@/lib/bots/bing/sr'
import { voiceListenAtom } from '@/state'
import { SVG } from './ui/svg'
import { cn } from '@/lib/utils'

const sr = new SR(['发送', '清空', '退出'])

const Voice = ({ setInput, input, sendMessage, isSpeaking }: Pick<BingReturnType, 'setInput' | 'sendMessage' | 'input' | 'isSpeaking'>) => {
const Voice = ({ setInput, input, sendMessage, isSpeaking, className }: Pick<BingReturnType, 'setInput' | 'sendMessage' | 'input' | 'isSpeaking'> & { className?: string }) => {
const setListen = useSetAtom(voiceListenAtom)
useEffect(() => {
if (sr.listening) return
Expand Down Expand Up @@ -47,7 +48,7 @@ const Voice = ({ setInput, input, sendMessage, isSpeaking }: Pick<BingReturnType
}

return (
<div className="voice-container">
<div className={cn('voice-container -mt-2 -mr-2', className)}>
{
sr.listening ? (
<VoiceButton className="voice-button-theme" onClick={() => switchSR(false)} />
Expand Down
10 changes: 5 additions & 5 deletions src/lib/hooks/use-bing.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use client'

import { useState, useCallback, useEffect, useMemo } from 'react'
import { useAtom, useAtomValue } from 'jotai'
import { chatFamily, bingConversationStyleAtom, GreetMessages, hashAtom, voiceAtom, chatHistoryAtom } from '@/state'
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import { chatFamily, bingConversationStyleAtom, GreetMessages, hashAtom, voiceAtom, chatHistoryAtom, isImageOnly } from '@/state'
import { ChatMessageModel, BotId, FileItem } from '@/lib/bots/bing/types'
import { nanoid } from '../utils'
import { TTS } from '../bots/bing/tts'

export function useBing(botId: BotId = 'bing') {
const chatAtom = useMemo(() => chatFamily({ botId, page: 'singleton' }), [botId])
const [chatState, setChatState] = useAtom(chatAtom)
const [historyValue, setHistoryValue] = useAtom(chatHistoryAtom)
const setHistoryValue = useSetAtom(chatHistoryAtom)
const [enableTTS] = useAtom(voiceAtom)
const speaker = useMemo(() => new TTS(), [])
const [hash, setHash] = useAtom(hashAtom)
Expand Down Expand Up @@ -46,9 +46,9 @@ export function useBing(botId: BotId = 'bing') {
draft.abortController = abortController
})
speaker.reset()
const instance = await chatState.bot.sendMessage({
await chatState.bot.sendMessage({
prompt: input,
imageUrl,
imageUrl: !isImageOnly && imageUrl && /api\/blob.jpg\?bcid=([^&]+)/.test(imageUrl) ? `https://www.bing.com/images/blob?bcid=${RegExp.$1}` : imageUrl,
options: {
...options,
bingConversationStyle,
Expand Down
33 changes: 0 additions & 33 deletions src/lib/hooks/use-enter-submit.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { atomFamily } from 'jotai/utils'
import { atomWithHash, atomWithLocation } from 'jotai-location'
import { initialMessages } from '../../tests/fixtures/messages'
import storage from './storage'
import { getCookie } from '@/lib/utils'

export const GreetMessages = [
'谢谢你! 知道你什么时候准备好继续前进总是很有帮助的。我现在能为你回答什么问题?',
Expand All @@ -29,7 +30,7 @@ export interface Prompt {
prompt: string
}


export const isImageOnly = getCookie('IMAGE_ONLY') !== '0'
export const bingConversationStyleAtom = atomWithStorage<BingConversationStyle>('bingConversationStyle', BingConversationStyle.Balanced, undefined, { unstable_getOnInit: true })
export const voiceAtom = atomWithStorage<boolean>('enableTTS', false, undefined, { unstable_getOnInit: true })
export const historyAtom = atomWithStorage<boolean>('enableHistory', false, undefined, { unstable_getOnInit: true })
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "ESNext",
"target": "ES2020",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
Expand Down

0 comments on commit 56c5d6e

Please sign in to comment.