save & upload

main
reng 4 months ago
parent 855083719f
commit e8c557cd2f
  1. 1
      vite/package-lock.json
  2. 4
      vite/src/App.css
  3. 2
      vite/src/comps/debug.jsx
  4. 13
      vite/src/comps/numpad.jsx
  5. 3
      vite/src/main.jsx
  6. 34
      vite/src/pages/flow_free.jsx
  7. 2
      vite/src/util/osc.js
  8. 62
      vite/src/util/useUser.jsx

@ -2644,6 +2644,7 @@
"version": "2.30.1", "version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": { "engines": {
"node": "*" "node": "*"
} }

@ -10,3 +10,7 @@
main{ main{
@apply flex-1 grid grid-cols-2 gap-4 justify-start p-8 overflow-hidden; @apply flex-1 grid grid-cols-2 gap-4 justify-start p-8 overflow-hidden;
} }
label{
@apply !text-sm !font-bold !bg-blue-500 text-white lowercase px-2 rounded-full;
}

@ -24,7 +24,7 @@ export function DebugControl({refLight}){
<button onClick={() => sendOsc(OSC_ADDRESS.STATUS, 'end')}>end</button> <button onClick={() => sendOsc(OSC_ADDRESS.STATUS, 'end')}>end</button>
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<button className="btn btn-success" onClick={() => sendPrompt('Random dogs')}>Test Prompt</button> <button className="btn btn-success" onClick={() => sendPrompt('a dog')}>Test Prompt</button>
<button className="btn btn-success" onClick={() => sendPrompt(TEST_PROMPT)}>Test Prompt</button> <button className="btn btn-success" onClick={() => sendPrompt(TEST_PROMPT)}>Test Prompt</button>
</div> </div>
</div> </div>

@ -13,7 +13,7 @@ const TMP_MAP_KEY={
7:9, 7:9,
} }
export default function NumPad({onSend}){ export default function NumPad({onSend, disabled}){
const [input, _setInput]=useState(); const [input, _setInput]=useState();
const refInput=useRef(); const refInput=useRef();
@ -30,7 +30,11 @@ export default function NumPad({onSend}){
const refAudio=useRef([]); const refAudio=useRef([]);
function onkeydown(e){ function onkeydown(e){
console.log(e.key); console.log(e.key);
if(disabled) return; // Ignore key events if disabled
if(e.key===KEY_ENTER){ if(e.key===KEY_ENTER){
@ -89,16 +93,19 @@ export default function NumPad({onSend}){
useEffect(()=>{ useEffect(()=>{
if(disabled) return;
window.onkeydown=onkeydown; window.onkeydown=onkeydown;
return () => { return () => {
window.onkeydown=null; // Clean up the event listener window.onkeydown=null; // Clean up the event listener
}; };
},[]); },[disabled]);
return ( return (
<div className="flex flex-col justify-center bg-yellow-400 text-4xl overflow-hidden"> <div className={`flex flex-col justify-center ${disabled?'bg-gray-400': 'bg-yellow-400'} text-4xl overflow-hidden relative`}>
<label className="absolute top-0 left-0"> Numpad</label>
{input} {input}
</div> </div>
); );

@ -10,10 +10,12 @@ import { Conversation } from './pages/conversation.jsx';
import { ChatProvider } from './util/useChat.jsx'; import { ChatProvider } from './util/useChat.jsx';
import { DataProvider } from './util/useData.jsx'; import { DataProvider } from './util/useData.jsx';
import { FreeFlow } from './pages/flow_free.jsx'; import { FreeFlow } from './pages/flow_free.jsx';
import { UserProvider } from './util/useUser.jsx';
createRoot(document.getElementById('root')).render( createRoot(document.getElementById('root')).render(
<StrictMode> <StrictMode>
<DataProvider> <DataProvider>
<UserProvider>
<ChatProvider> <ChatProvider>
<BrowserRouter> <BrowserRouter>
<App /> <App />
@ -25,6 +27,7 @@ createRoot(document.getElementById('root')).render(
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
</ChatProvider> </ChatProvider>
</UserProvider>
</DataProvider> </DataProvider>
</StrictMode>, </StrictMode>,

@ -12,6 +12,7 @@ import { useData } from "../util/useData";
import VoiceAnalysis from "../comps/voiceanalysis"; import VoiceAnalysis from "../comps/voiceanalysis";
import { sendOsc, OSC_ADDRESS, updatePrompt } from "../util/osc"; import { sendOsc, OSC_ADDRESS, updatePrompt } from "../util/osc";
import { DebugControl, TEST_PROMPT } from "../comps/debug"; import { DebugControl, TEST_PROMPT } from "../comps/debug";
import { useUser } from "../util/useUser";
const EmojiType={ const EmojiType={
@ -28,6 +29,8 @@ const ChatStatus={
User: 'user', User: 'user',
Processing: 'processing', Processing: 'processing',
Clear: 'clear', Clear: 'clear',
End: 'end',
Playing: 'playing',
} }
const Voice={ const Voice={
@ -44,12 +47,13 @@ export function FreeFlow(){
const [chatWelcome, setChatWelcome] = useState(null); const [chatWelcome, setChatWelcome] = useState(null);
const [audioInput, setAudioInput] = useState(true); const [audioInput, setAudioInput] = useState(true);
const [autoSend, setAutoSend] = useState(true); const [autoSend, setAutoSend] = useState(true);
const [userId, setUserId] = useState(); // const [userId, setUserId] = useState();
const [summary, setSummary] = useState(null); const [summary, setSummary] = useState(null);
const [voice, setVoice] = useState(Voice.ONYX); const [voice, setVoice] = useState(Voice.ONYX);
//const [speechPaused, setSpeechPaused]=useState(false); //const [speechPaused, setSpeechPaused]=useState(false);
const [chatStatus, setChatStatus] = useState(ChatStatus.System); // System, User, Processing const [chatStatus, setChatStatus] = useState(ChatStatus.System); // System, User, Processing
const { userId, setUserId, getFileId } = useUser();
const refTimer=useRef(); const refTimer=useRef();
const refAudio=useRef(); const refAudio=useRef();
@ -121,13 +125,15 @@ export function FreeFlow(){
refTimer.current?.restart(audio.duration*1000 || 0); refTimer.current?.restart(audio.duration*1000 || 0);
}else{ }else{
if(refCurrentCue.current?.type=='chat') setChatStatus(()=>ChatStatus.System); if(refCurrentCue.current?.type=='chat') setChatStatus(()=>ChatStatus.System);
else setChatStatus(()=>ChatStatus.Clear); else setChatStatus(()=>ChatStatus.Playing);
} }
}); });
audio.onended = () => { audio.onended = () => {
if(refCurrentCue.current?.type!='chat') onCueEnd(); if(refCurrentCue.current?.type!='chat'){
else{ onCueEnd();
setChatStatus(ChatStatus.End);
}else{
setChatStatus(ChatStatus.User); // Reset chat status to User after audio ends setChatStatus(ChatStatus.User); // Reset chat status to User after audio ends
@ -202,14 +208,17 @@ export function FreeFlow(){
console.log('Getting summary...'); console.log('Getting summary...');
setChatStatus(ChatStatus.Clear); // Set chat status to Processing setChatStatus(ChatStatus.Clear); // Set chat status to Processing
getSummary(history.map(el=>`${el.role}:${el.content}`).join('\n'), data).then(summary => { getSummary(history.map(el=>`${el.role}:${el.content}`).join('\n'), data).then(summary_ => {
console.log('Summary:', summary); console.log('Summary:', summary_);
onCueEnd(); // End the current cue after getting summary onCueEnd(); // End the current cue after getting summary
setSummary(summary); setSummary(summary_);
refContainer.current.scrollTop = refContainer.current.scrollHeight; // Scroll to bottom refContainer.current.scrollTop = refContainer.current.scrollHeight; // Scroll to bottom
// sendOsc(OSC_ADDRESS.SUMMARY, summary_?.result);
sendOsc(OSC_ADDRESS.SAVE, `${getFileId()}#${summary_?.result}`); // Save summary with file ID
}).catch(error => { }).catch(error => {
console.error('Error getting summary:', error); console.error('Error getting summary:', error);
}); });
@ -481,7 +490,7 @@ export function FreeFlow(){
<button className="!bg-red-300" onClick={onStop}>Stop</button> <button className="!bg-red-300" onClick={onStop}>Stop</button>
{/* <button onClick={saveImage}>Save image</button> */} {/* <button onClick={saveImage}>Save image</button> */}
<NumPad onSend={onNumpad} /> <NumPad onSend={onNumpad} disabled={currentCue?.callback !== 'numpad' || chatStatus!=ChatStatus.End} />
<Light ref={refLight} /> <Light ref={refLight} />
<VoiceAnalysis/> <VoiceAnalysis/>
{/* <div className="flex flex-col"> {/* <div className="flex flex-col">
@ -489,10 +498,17 @@ export function FreeFlow(){
<button className={`${voice==Voice.ONYX && 'bg-gray-300'}`} onClick={() => setVoice(Voice.ONYX)}>Onyx</button> <button className={`${voice==Voice.ONYX && 'bg-gray-300'}`} onClick={() => setVoice(Voice.ONYX)}>Onyx</button>
<button className={`${voice==Voice.SHIMMER && 'bg-gray-300'}`} onClick={() => setVoice(Voice.SHIMMER)}>Shimmer</button> <button className={`${voice==Voice.SHIMMER && 'bg-gray-300'}`} onClick={() => setVoice(Voice.SHIMMER)}>Shimmer</button>
</div> */} </div> */}
<button className="!bg-yellow-300" onClick={()=>{
<div className="grid grid-cols-[1fr_2fr] relative text-xs">
<label className="col-span-1">user</label>
<span></span>
<span>UserId</span><span>{userId}</span>
<span>FileId</span><span>{getFileId()}</span>
<button className="!bg-yellow-300 col-span-2" onClick={()=>{
saveHistory(history); saveHistory(history);
}}>Save Log</button> }}>Save Log</button>
</div> </div>
</div>
<div className="flex-1 overflow-y-auto"> <div className="flex-1 overflow-y-auto">
<table className="border-collapse **:border-y w-full **:p-2 text-sm"> <table className="border-collapse **:border-y w-full **:p-2 text-sm">
<thead> <thead>

@ -10,7 +10,7 @@ export const OSC_ADDRESS={
SCRIPT: '/script', SCRIPT: '/script',
SUMMARY: '/summary', SUMMARY: '/summary',
PROMPT: '/prompt', PROMPT: '/prompt',
SAVE: '/save',
} }

@ -0,0 +1,62 @@
import { createContext, useState, useEffect, useContext } from "react";
import moment from "moment";
const userContext=createContext();
const SesstionTime={
A:["12:00", "13:30"],
B:["13:30", "15:00"],
C:["15:00", "17:30"],
D:["17:30", "19:00"],
E:["19:00", "20:30"],
F:["20:30", "22:00"]
}
export function UserProvider({children}) {
const [userId, setUserId] = useState(null);
const [sessionId, setSessionId] = useState(null);
function getFileId(){
if(!userId) return `test-${moment().format("YYYYMMDDmmss")}-${sessionId}`;
return `${moment().format("YYYYMMDD").substring(2)}-${sessionId}-${userId}`;
}
useEffect(() => {
let symbol='';
for(const [key, value] of Object.entries(SesstionTime)){
const start=moment(value[0], "HH:mm");
const end=moment(value[1], "HH:mm");
if(moment().isBetween(start, end)){
symbol=key;
break;
}
}
setSessionId(symbol);
}, [userId]);
return (
<userContext.Provider value={{ userId, setUserId, getFileId }}>
{children}
</userContext.Provider>
);
}
export function useUser() {
const context = useContext(userContext);
if (!context) {
throw new Error("useUser must be used within a UserProvider");
}
return context;
}
export { userContext };
Loading…
Cancel
Save